コード例 #1
0
        public void TestMemoizeIndices()
        {
            var model = new PatternModel
            {
                Frequencies = new double[] { 1, 1 },
                // Free model
                Propagator = new int[][][]
                {
                    new int[][] { new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 0, 1 }, },
                    new int[][] { new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 0, 1 }, },
                }
            };
            var width           = 10;
            var height          = 10;
            var topology        = new GridTopology(width, height, true);
            var indexPicker     = new CustomIndexPicker();
            var memoIndexPicker = new MemoizeIndexPicker(indexPicker);
            var options         = new WavePropagatorOptions {
                BacktrackPolicy = new ConstantBacktrackPolicy(1),
                IndexPicker     = memoIndexPicker,
                PatternPicker   = new SimpleOrderedPatternPicker(),
                Constraints     = new[] { new  DontBanOneConstraint() },
            };
            var propagator = new WavePropagator(model, topology, options);

            // Attempts to pick pattern 0 at index 0, should contradict and backtrack
            var status = propagator.Step();

            Assert.AreEqual(Resolution.Undecided, status);
            Assert.AreEqual(1, propagator.BacktrackCount);
            CollectionAssert.AreEqual(propagator.GetPossiblePatterns(0), new[] { 1 });
            Assert.AreEqual(1, indexPicker.Count);
            // Should re-attempt index zero, with no effect.
            propagator.Step();
            Assert.AreEqual(Resolution.Undecided, status);
            Assert.AreEqual(1, propagator.BacktrackCount);
            CollectionAssert.AreEqual(propagator.GetPossiblePatterns(0), new[] { 1 });
            Assert.AreEqual(1, indexPicker.Count);
            // Attempts to pick pattern 0 at index 1, should contradict and backtrack
            propagator.Step();
            Assert.AreEqual(Resolution.Undecided, status);
            Assert.AreEqual(2, propagator.BacktrackCount);
            CollectionAssert.AreEqual(propagator.GetPossiblePatterns(1), new[] { 1 });
            Assert.AreEqual(2, indexPicker.Count);
            // etc
        }
コード例 #2
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));
        }