public TilePropagator(TileModel tileModel, ITopology topology, TilePropagatorOptions options) { this.tileModel = tileModel; this.topology = topology; var overlapping = tileModel as OverlappingModel; tileModelMapping = tileModel.GetTileModelMapping(topology); var patternTopology = tileModelMapping.PatternTopology; var patternModel = tileModelMapping.PatternModel; var waveConstraints = (options.Constraints?.Select(x => new TileConstraintAdaptor(x, this)).ToArray() ?? Enumerable.Empty <IWaveConstraint>()) .ToArray(); var waveFrequencySets = options.Weights == null ? null : GetFrequencySets(options.Weights, tileModelMapping); #pragma warning disable CS0618 // Type or member is obsolete this.wavePropagator = new WavePropagator( patternModel, patternTopology, options.BackTrackDepth, waveConstraints, options.RandomDouble ?? (options.Random == null ? (Func <double>)null : options.Random.NextDouble), waveFrequencySets, clear: false); #pragma warning restore CS0618 // Type or member is obsolete wavePropagator.Clear(); }
private static IBacktrackPolicy MakeBacktrackPolicy(TilePropagatorOptions options) { switch (options.BacktrackType) { case BacktrackType.None: return(null); case BacktrackType.Backtrack: return(new ConstantBacktrackPolicy(1)); case BacktrackType.Backjump: return(new PatienceBackjumpPolicy()); default: throw new Exception($"Unknown BacktrackType {options.BacktrackType}"); } }
public TilePropagator(TileModel tileModel, ITopology topology, TilePropagatorOptions options) { this.tileModel = tileModel; this.topology = topology; var overlapping = tileModel as OverlappingModel; tileModelMapping = tileModel.GetTileModelMapping(topology); var patternTopology = tileModelMapping.PatternTopology; var patternModel = tileModelMapping.PatternModel; var waveConstraints = (options.Constraints?.Select(x => new TileConstraintAdaptor(x, this)).ToArray() ?? Enumerable.Empty <IWaveConstraint>()) .ToArray(); #pragma warning disable CS0618 // Type or member is obsolete var randomDouble = options.RandomDouble ?? (options.Random ?? new Random()).NextDouble; #pragma warning restore CS0618 // Type or member is obsolete var(indexPicker, patternPicker) = MakePickers(options); var wavePropagatorOptions = new WavePropagatorOptions { BacktrackPolicy = MakeBacktrackPolicy(options), MaxBacktrackDepth = options.MaxBacktrackDepth, RandomDouble = randomDouble, Constraints = waveConstraints, IndexPicker = indexPicker, PatternPicker = patternPicker, Clear = false, ModelConstraintAlgorithm = options.ModelConstraintAlgorithm, }; this.wavePropagator = new WavePropagator( patternModel, patternTopology, wavePropagatorOptions); wavePropagator.Clear(); }
private IPickHeuristic MakePickHeuristic(WavePropagator wavePropagator, TilePropagatorOptions options) { var waveFrequencySets = options.Weights == null ? null : GetFrequencySets(options.Weights, tileModelMapping); var randomDouble = wavePropagator.RandomDouble; var patternTopology = wavePropagator.Topology; var pathConstraint = options.Constraints?.OfType <EdgedPathConstraint>().FirstOrDefault(); var pathPickHeuristic = pathConstraint != null && pathConstraint.UsePickHeuristic; var connectedConstraint = options.Constraints?.OfType <ConnectedConstraint>().FirstOrDefault(); var connectedPickHeuristic = connectedConstraint != null && connectedConstraint.UsePickHeuristic; // Use the appropriate random picker // Generally this is HeapEntropyTracker, but it doesn't support some features // so there's a few slower implementations for that IRandomPicker randomPicker; if (options.PickHeuristicType == PickHeuristicType.Ordered) { randomPicker = new OrderedRandomPicker(wavePropagator.Wave, wavePropagator.Frequencies, patternTopology.Mask); } else if (waveFrequencySets != null) { var entropyTracker = new ArrayPriorityEntropyTracker(wavePropagator.Wave, waveFrequencySets, patternTopology.Mask); entropyTracker.Reset(); wavePropagator.AddTracker(entropyTracker); randomPicker = entropyTracker; } else if (pathPickHeuristic || connectedPickHeuristic) { var entropyTracker = new EntropyTracker(wavePropagator.Wave, wavePropagator.Frequencies, patternTopology.Mask); entropyTracker.Reset(); wavePropagator.AddTracker(entropyTracker); randomPicker = entropyTracker; } else { var entropyTracker = new HeapEntropyTracker(wavePropagator.Wave, wavePropagator.Frequencies, patternTopology.Mask, randomDouble); entropyTracker.Reset(); wavePropagator.AddTracker(entropyTracker); randomPicker = entropyTracker; } IPickHeuristic heuristic = new RandomPickerHeuristic(randomPicker, randomDouble); if (pathPickHeuristic) { heuristic = pathConstraint.GetHeuristic( randomPicker, randomDouble, this, tileModelMapping, heuristic); } if (connectedPickHeuristic) { heuristic = connectedConstraint.GetHeuristic( randomPicker, randomDouble, this, tileModelMapping, heuristic); } return(heuristic); }
public TilePropagator(TileModel tileModel, ITopology topology, TilePropagatorOptions options) { this.tileModel = tileModel; this.topology = topology; var overlapping = tileModel as OverlappingModel; tileModelMapping = tileModel.GetTileModelMapping(topology); var patternTopology = tileModelMapping.PatternTopology; var patternModel = tileModelMapping.PatternModel; var waveConstraints = (options.Constraints?.Select(x => new TileConstraintAdaptor(x, this)).ToArray() ?? Enumerable.Empty <IWaveConstraint>()) .ToArray(); var waveFrequencySets = options.Weights == null ? null : GetFrequencySets(options.Weights, tileModelMapping); #pragma warning disable CS0618 // Type or member is obsolete var randomDouble = options.RandomDouble ?? (options.Random ?? new Random()).NextDouble; #pragma warning restore CS0618 // Type or member is obsolete IPickHeuristic MakePickHeuristic(WavePropagator wavePropagator) { IRandomPicker randomPicker; if (options.PickHeuristicType == PickHeuristicType.Ordered) { randomPicker = new OrderedRandomPicker(wavePropagator.Wave, wavePropagator.Frequencies, patternTopology.Mask); } else if (waveFrequencySets != null) { var entropyTracker = new ArrayPriorityEntropyTracker(wavePropagator.Wave, waveFrequencySets, patternTopology.Mask); entropyTracker.Reset(); wavePropagator.AddTracker(entropyTracker); randomPicker = entropyTracker; } else { var entropyTracker = new EntropyTracker(wavePropagator.Wave, wavePropagator.Frequencies, patternTopology.Mask); entropyTracker.Reset(); wavePropagator.AddTracker(entropyTracker); randomPicker = entropyTracker; } IPickHeuristic heuristic = new RandomPickerHeuristic(randomPicker, randomDouble); var pathConstraint = options.Constraints?.OfType <EdgedPathConstraint>().FirstOrDefault(); if (pathConstraint != null && pathConstraint.UsePickHeuristic) { heuristic = pathConstraint.GetHeuristic( randomPicker, randomDouble, this, tileModelMapping, heuristic); } var connectedConstraint = options.Constraints?.OfType <ConnectedConstraint>().FirstOrDefault(); if (connectedConstraint != null && connectedConstraint.UsePickHeuristic) { heuristic = connectedConstraint.GetHeuristic( randomPicker, randomDouble, this, tileModelMapping, heuristic); } return(heuristic); } var wavePropagatorOptions = new WavePropagatorOptions { BackTrackDepth = options.BackTrackDepth, RandomDouble = randomDouble, Constraints = waveConstraints, PickHeuristicFactory = MakePickHeuristic, Clear = false, ModelConstraintAlgorithm = options.ModelConstraintAlgorithm, }; this.wavePropagator = new WavePropagator( patternModel, patternTopology, wavePropagatorOptions); wavePropagator.Clear(); }
private Tuple <IIndexPicker, IPatternPicker> MakePickers(TilePropagatorOptions options) { var pathConstraint = options.Constraints?.OfType <EdgedPathConstraint>().FirstOrDefault(); var connectedConstraint = options.Constraints?.OfType <ConnectedConstraint>().FirstOrDefault(); var connectedPickHeuristic = connectedConstraint != null && connectedConstraint.UsePickHeuristic; if (connectedPickHeuristic) { // Lists pickers that implement IFilteredIndexPicker if (options.IndexPickerType != IndexPickerType.Default && options.IndexPickerType != IndexPickerType.MinEntropy && options.IndexPickerType != IndexPickerType.Ordered) { throw new Exception($"Connected Pick Heuristic is incompatible with the selected IndexPikcerType {options.IndexPickerType}"); } if (options.IndexPickerType == IndexPickerType.Default) { options.IndexPickerType = IndexPickerType.MinEntropy; } } // Use the appropriate random picker // Generally this is HeapEntropyTracker, but it doesn't support some features // so there's a few slower implementations for that IIndexPicker indexPicker = null; IPatternPicker patternPicker = null; switch (options.IndexPickerType) { case IndexPickerType.Ordered: { if (options.IndexOrder != null) { indexPicker = new OrderedIndexPicker(options.IndexOrder); } else { indexPicker = new SimpleOrderedIndexPicker(); } break; } case IndexPickerType.ArrayPriorityMinEntropy: { if (options.WeightSetByIndex == null || options.WeightSets == null) { throw new ArgumentNullException($"Expected WeightSetByIndex and WeightSets to be set"); } if (options.TilePickerType != TilePickerType.ArrayPriority && options.TilePickerType != TilePickerType.Default) { throw new Exception($"ArrayPriorityMinEntropy only works with Default tile picker"); } var weightSetCollection = new WeightSetCollection(options.WeightSetByIndex, options.WeightSets, tileModelMapping); var entropyTracker = new ArrayPriorityEntropyTracker(weightSetCollection); indexPicker = entropyTracker; patternPicker = entropyTracker; break; } case IndexPickerType.MinEntropy: { indexPicker = new EntropyTracker(); break; } case IndexPickerType.Default: case IndexPickerType.HeapMinEntropy: { indexPicker = new HeapEntropyTracker(); break; } case IndexPickerType.Dirty: { // Create clean patterns if (tileModelMapping.TileCoordToPatternCoordIndexAndOffset != null) { throw new NotSupportedException(); } if (options.CleanTiles == null) { throw new ArgumentNullException($"{nameof(options.CleanTiles)} is null"); } var cleanPatterns = options.CleanTiles.Map(t => tileModelMapping.TilesToPatternsByOffset[0][t].First()); indexPicker = new DirtyIndexPicker(new SimpleOrderedIndexPicker(), cleanPatterns); break; } default: throw new Exception($"Unknown IndexPickerType {options.IndexPickerType}"); } if (patternPicker == null) { switch (options.TilePickerType) { case TilePickerType.Default: case TilePickerType.Weighted: patternPicker = new WeightedRandomPatternPicker(); break; case TilePickerType.Ordered: patternPicker = new SimpleOrderedPatternPicker(); break; case TilePickerType.ArrayPriority: if (options.WeightSetByIndex == null || options.WeightSets == null) { throw new ArgumentNullException($"Expected WeightSetByIndex and WeightSets to be set"); } var weightSetCollection = new WeightSetCollection(options.WeightSetByIndex, options.WeightSets, tileModelMapping); patternPicker = new ArrayPriorityPatternPicker(weightSetCollection); break; default: throw new Exception($"Unknown TilePickerType {options.TilePickerType}"); } } if (connectedPickHeuristic) { indexPicker = connectedConstraint.GetHeuristic( (IFilteredIndexPicker)indexPicker, this); } if (options.MemoizeIndices) { indexPicker = new MemoizeIndexPicker(indexPicker); } return(Tuple.Create(indexPicker, patternPicker)); }