Ejemplo n.º 1
0
        /**
         * Resets the wave to it's original state
         */
        public Resolution Clear()
        {
            wave = new Wave(frequencies.Length, indexCount);

            if (backtrack)
            {
                backtrackItems        = new Deque <IndexPatternItem>();
                backtrackItemsLengths = new Deque <int>();
                backtrackItemsLengths.Push(0);
                prevChoices = new Deque <IndexPatternItem>();
            }

            status        = Resolution.Undecided;
            this.trackers = new List <ITracker>();
            if (frequencySets != null)
            {
                var entropyTracker = new ArrayPriorityEntropyTracker(wave, frequencySets, topology.Mask);
                entropyTracker.Reset();
                AddTracker(entropyTracker);
                pickHeuristic = new ArrayPriorityEntropyHeuristic(entropyTracker, randomDouble);
            }
            else
            {
                var entropyTracker = new EntropyTracker(wave, frequencies, topology.Mask);
                entropyTracker.Reset();
                AddTracker(entropyTracker);
                pickHeuristic = new EntropyHeuristic(entropyTracker, randomDouble);
            }

            patternModelConstraint.Clear();

            if (status == Resolution.Contradiction)
            {
                return(status);
            }

            InitConstraints();

            return(status);
        }
Ejemplo n.º 2
0
 public ArrayPriorityEntropyHeuristic(ArrayPriorityEntropyTracker entropyTracker, Func <double> randomDouble)
 {
     this.entropyTracker = entropyTracker;
     this.randomDouble   = randomDouble;
 }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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();
        }
Ejemplo n.º 5
0
        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));
        }