Ejemplo n.º 1
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
            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();
        }
Ejemplo n.º 2
0
        public void TestChessboard()
        {
            var model = new PatternModel
            {
                Frequencies = new double[] { 1, 1 },
                Propagator  = new int[][][]
                {
                    new int[][] { new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, },
                    new int[][] { new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, },
                }
            };
            var width      = 10;
            var height     = 10;
            var topology   = new Topology(width, height, true);
            var propagator = new WavePropagator(model, topology);
            var status     = propagator.Run();

            Assert.AreEqual(Resolution.Decided, status);
            var a       = propagator.ToTopoArray().ToArray2d();
            var topLeft = a[0, 0];

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    Assert.IsTrue((a[x, y] == topLeft) ^ (x % 2 == 0) ^ (y % 2 == 0));
                }
            }

            // Should be impossible with an odd sized region
            topology   = new Topology(width + 1, height + 1, true);
            propagator = new WavePropagator(model, topology);
            status     = propagator.Run();
            Assert.AreEqual(Resolution.Contradiction, status);
        }
Ejemplo n.º 3
0
 public SelectedTracker(TilePropagator tilePropagator, WavePropagator wavePropagator, TileModelMapping tileModelMapping, TilePropagatorTileSet tileSet)
 {
     this.tilePropagator   = tilePropagator;
     this.wavePropagator   = wavePropagator;
     this.tileModelMapping = tileModelMapping;
     this.tileSet          = tileSet;
     patternCounts         = new int[tilePropagator.Topology.IndexCount];
 }
        public void Init(WavePropagator wavePropagator)
        {
            wave = wavePropagator.Wave;

            this.mask = wavePropagator.Topology.Mask;

            this.indices = wave.Indicies;
        }
Ejemplo n.º 5
0
        public void TestBacktracking()
        {
            // Reproduces the wang tiles found at
            // https://en.wikipedia.org/wiki/Wang_tile
            // They only have aperiodic tiling, so they are a hard set to put down.
            // Clockwise from top
            var tileBorders = new[]
            {
                "rrrg",
                "brbg",
                "rggg",
                "wbrb",
                "bbwb",
                "wwrw",
                "rgbw",
                "bwbr",
                "brwr",
                "ggbr",
                "rwrg",
            };
            var propagator = tileBorders.Select(tile1 =>

                                                tile1.Select((c, i) =>
            {
                var d = new[] { 3, 0, 2, 1 }[i];
                var o = (i + 2) % 4;
                return(Tuple.Create(d, tileBorders
                                    .Select((tile2, i2) => Tuple.Create(tile2, i2))
                                    .Where(t => t.Item1[o] == c)
                                    .Select(t => t.Item2)
                                    .ToArray()));
            })
                                                .OrderBy(x => x.Item1)
                                                .Select(x => x.Item2)
                                                .ToArray()
                                                ).ToArray();

            var model = new PatternModel
            {
                Frequencies = tileBorders.Select(x => 1.0).ToArray(),
                Propagator  = propagator,
            };
            var topology = new GridTopology(10, 10, false);

            var seed = Environment.TickCount;
            var r    = new Random(seed);

            Console.WriteLine("Seed {0}", seed);

            var wavePropagator = new WavePropagator(model, topology, 10, randomDouble: r.NextDouble);

            var status = wavePropagator.Run();

            Assert.AreEqual(Resolution.Decided, status);

            Console.WriteLine($"Backtrack Count {wavePropagator.BacktrackCount}");
        }
Ejemplo n.º 6
0
 internal SelectedChangeTracker(TilePropagator tilePropagator, WavePropagator wavePropagator, TileModelMapping tileModelMapping, TilePropagatorTileSet tileSet, IQuadstateChanged onChange)
 {
     this.tilePropagator   = tilePropagator;
     this.wavePropagator   = wavePropagator;
     this.tileModelMapping = tileModelMapping;
     this.tileSet          = tileSet;
     this.onChange         = onChange;
     patternCounts         = new int[tilePropagator.Topology.IndexCount];
     values = new Quadstate[tilePropagator.Topology.IndexCount];
 }
        public void Init(WavePropagator wavePropagator)
        {
            mask          = wavePropagator.Topology.Mask;
            wave          = wavePropagator.Wave;
            indices       = wave.Indicies;
            entropyValues = new EntropyValues[indices];

            Reset();
            wavePropagator.AddTracker(this);
        }
Ejemplo n.º 8
0
 public void Check(WavePropagator wavePropagator)
 {
     foreach (var i in Enumerable.Range(0, wavePropagator.Wave.Indicies))
     {
         if (wavePropagator.Wave.Get(i, 1) == false)
         {
             wavePropagator.SetContradiction();
         }
     }
 }
Ejemplo n.º 9
0
        public void TestChessboard(ModelConstraintAlgorithm algorithm)
        {
            var model = new PatternModel
            {
                Frequencies = new double[] { 1, 1 },
                Propagator  = new int[][][]
                {
                    new int[][] { new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, },
                    new int[][] { new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, },
                }
            };
            var width    = 10;
            var height   = 10;
            var topology = new GridTopology(width, height, true);
            var options  = new WavePropagatorOptions {
                ModelConstraintAlgorithm = algorithm
            };
            var propagator = new WavePropagator(model, topology, options);
            var status     = propagator.Run();

            Assert.AreEqual(Resolution.Decided, status);
            var a       = propagator.ToTopoArray().ToArray2d();
            var topLeft = a[0, 0];

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    Assert.IsTrue((a[x, y] == topLeft) ^ (x % 2 == 0) ^ (y % 2 == 0));
                }
            }

            // Should be impossible with an odd sized region
            topology   = new GridTopology(width + 1, height + 1, true);
            propagator = new WavePropagator(model, topology, options);
            status     = propagator.Run();
            Assert.AreEqual(Resolution.Contradiction, status);

            // Should be possible with an odd sized region, if we have the right mask
            var mask = new bool[(width + 1) * (height + 1)];

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    mask[x + y * (width + 1)] = true;
                }
            }
            topology   = new GridTopology(width + 1, height + 1, true).WithMask(mask);
            propagator = new WavePropagator(model, topology, options);
            status     = propagator.Run();
            Assert.AreEqual(Resolution.Decided, status);
        }
Ejemplo n.º 10
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
        }
Ejemplo n.º 11
0
        public void TestChessboard3d(ModelConstraintAlgorithm algorithm)
        {
            var model = new PatternModel
            {
                Frequencies = new double[] { 1, 1 },
                Propagator  = new int[][][]
                {
                    new int[][] { new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, },
                    new int[][] { new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, },
                }
            };
            var width    = 4;
            var height   = 4;
            var depth    = 4;
            var topology = new GridTopology(width, height, depth, true);
            var options  = new WavePropagatorOptions {
                ModelConstraintAlgorithm = algorithm
            };
            var propagator = new WavePropagator(model, topology, options);
            var status     = propagator.Run();

            Assert.AreEqual(Resolution.Decided, status);
            var a       = propagator.ToTopoArray();
            var topLeft = a.Get(0, 0, 0);

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    for (var z = 0; z < depth; z++)
                    {
                        Assert.IsFalse((a.Get(x, y, z) == topLeft) ^ (x % 2 == 0) ^ (y % 2 == 0) ^ (z % 2 == 0));
                    }
                }
            }

            // Should be impossible with an odd sized region
            topology   = new GridTopology(width + 1, height + 1, depth + 1, true);
            propagator = new WavePropagator(model, topology, options);
            status     = propagator.Run();
            Assert.AreEqual(Resolution.Contradiction, status);
        }
Ejemplo n.º 12
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();


#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();
        }
Ejemplo n.º 13
0
 public void Init(WavePropagator wavePropagator)
 {
     filteredIndexPicker.Init(wavePropagator);
     // TODO: It's a pity this isn't shared with the path constraint
     edgedPathView = (EdgedPathView)edgedPathSpec.MakeView(propagator);
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Constructs a TilePropagator.
        /// </summary>
        /// <param name="tileModel">The model to guide the generation.</param>
        /// <param name="topology">The dimensions of the output to generate</param>
        /// <param name="backtrack">If true, store additional information to allow rolling back choices that lead to a contradiction.</param>
        /// <param name="constraints">Extra constraints to control the generation process.</param>
        /// <param name="random">Source of randomness</param>
        public TilePropagator(TileModel tileModel, Topology topology, bool backtrack = false,
                              ITileConstraint[] constraints = null,
                              Random random = null)
        {
            this.tileModel = tileModel;
            this.topology  = topology;

            var overlapping = tileModel as OverlappingModel;

            Topology patternTopology;

            if (!(topology.PeriodicX && topology.PeriodicY && topology.PeriodicZ) && overlapping != null)
            {
                // Shrink the topology as patterns can cover multiple tiles.
                patternTopology = topology.WithSize(
                    topology.PeriodicX ? topology.Width : topology.Width - overlapping.NX + 1,
                    topology.PeriodicY ? topology.Height : topology.Height - overlapping.NY + 1,
                    topology.PeriodicZ ? topology.Depth : topology.Depth - overlapping.NZ + 1);

                mappingType = MappingType.Overlapping;
                mappingNX   = overlapping.NX;
                mappingNY   = overlapping.NY;
                mappingNZ   = overlapping.NZ;

                // Compute tilesToPatterns and patternsToTiles
                var patternArrays = overlapping.PatternArrays;
                tilesToPatternsByOffset = new Dictionary <int, IReadOnlyDictionary <Tile, ISet <int> > >();
                patternsToTilesByOffset = new Dictionary <int, IReadOnlyDictionary <int, Tile> >();
                for (int ox = 0; ox < overlapping.NX; ox++)
                {
                    for (int oy = 0; oy < overlapping.NY; oy++)
                    {
                        for (int oz = 0; oz < overlapping.NZ; oz++)
                        {
                            var o = CombineOffsets(ox, oy, oz);
                            var tilesToPatterns = new Dictionary <Tile, ISet <int> >();
                            tilesToPatternsByOffset[o] = tilesToPatterns;
                            var patternsToTiles = new Dictionary <int, Tile>();
                            patternsToTilesByOffset[o] = patternsToTiles;
                            for (var pattern = 0; pattern < patternArrays.Count; pattern++)
                            {
                                var patternArray = patternArrays[pattern];
                                var tile         = patternArray.Values[ox, oy, oz];
                                patternsToTiles[pattern] = tile;
                                if (!tilesToPatterns.TryGetValue(tile, out var patternSet))
                                {
                                    patternSet = tilesToPatterns[tile] = new HashSet <int>();
                                }
                                patternSet.Add(pattern);
                            }
                        }
                    }
                }
            }
            else
            {
                patternTopology         = topology;
                mappingType             = MappingType.OneToOne;
                tilesToPatternsByOffset = new Dictionary <int, IReadOnlyDictionary <Tile, ISet <int> > >()
                {
                    { 0, tileModel.TilesToPatterns.ToDictionary(g => g.Key, g => (ISet <int>) new HashSet <int>(g)) }
                };
                patternsToTilesByOffset = new Dictionary <int, IReadOnlyDictionary <int, Tile> >
                {
                    { 0, tileModel.PatternsToTiles },
                };
            }

            // Masks interact a bit weirdly with the overlapping model
            // We choose a pattern mask that is a expansion of the topology mask
            // i.e. a pattern location is masked out if all the tile locations it covers is masked out.
            // This makes the propagator a bit conservative - it'll always preserve the overlapping property
            // but might ban some layouts that make sense.
            // The alternative is to contract the mask - that is more permissive, but sometimes will
            // violate the overlapping property.
            // (passing the mask verbatim is unacceptable as does not lead to symmetric behaviour)
            // See TestTileMaskWithThinOverlapping for an example of the problem, and
            // https://github.com/BorisTheBrave/DeBroglie/issues/7 for a possible solution.
            if (topology.Mask != null && overlapping != null)
            {
                // TODO: This could probably do with some cleanup
                bool GetTopologyMask(int x, int y, int z)
                {
                    if (!topology.PeriodicX && x >= topology.Width)
                    {
                        return(false);
                    }
                    if (!topology.PeriodicY && y >= topology.Height)
                    {
                        return(false);
                    }
                    if (!topology.PeriodicZ && z >= topology.Depth)
                    {
                        return(false);
                    }
                    x = x % topology.Width;
                    y = y % topology.Height;
                    z = z % topology.Depth;
                    return(topology.Mask[topology.GetIndex(x, y, z)]);
                }

                bool GetPatternTopologyMask(Point p)
                {
                    for (var oz = 0; oz < overlapping.NZ; oz++)
                    {
                        for (var oy = 0; oy < overlapping.NY; oy++)
                        {
                            for (var ox = 0; ox < overlapping.NX; ox++)
                            {
                                if (GetTopologyMask(p.X + ox, p.Y + oy, p.Z + oz))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                    return(false);
                }

                var patternMask = TopoArray.Create(GetPatternTopologyMask, patternTopology);
                patternTopology = patternTopology.WithMask(patternMask);
            }

            var waveConstraints =
                (constraints?.Select(x => new TileConstraintAdaptor(x, this)).ToArray() ?? Enumerable.Empty <IWaveConstraint>())
                .ToArray();

            this.wavePropagator = new WavePropagator(tileModel.GetPatternModel(), patternTopology, backtrack, waveConstraints, random, clear: false);
            wavePropagator.Clear();
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Constructs a TilePropagator.
        /// </summary>
        /// <param name="tileModel">The model to guide the generation.</param>
        /// <param name="topology">The dimensions of the output to generate</param>
        /// <param name="backtrack">If true, store additional information to allow rolling back choices that lead to a contradiction.</param>
        /// <param name="constraints">Extra constraints to control the generation process.</param>
        /// <param name="random">Source of randomness</param>
        public TilePropagator(TileModel tileModel, Topology topology, bool backtrack = false,
                              ITileConstraint[] constraints = null,
                              Random random = null)
        {
            this.tileModel = tileModel;
            this.topology  = topology;

            var patternTopology = topology;

            if (!(topology.PeriodicX && topology.PeriodicY && topology.PeriodicZ) && tileModel is OverlappingModel overlapping)
            {
                // Shrink the topology as patterns can cover multiple tiles.
                patternTopology = topology.WithSize(
                    topology.PeriodicX ? topology.Width : topology.Width - overlapping.NX + 1,
                    topology.PeriodicY ? topology.Height : topology.Height - overlapping.NY + 1,
                    topology.PeriodicZ ? topology.Depth : topology.Depth - overlapping.NZ + 1);

                mappingType = MappingType.Overlapping;
                mappingNX   = overlapping.NX;
                mappingNY   = overlapping.NY;
                mappingNZ   = overlapping.NZ;

                // Compute tilesToPatterns and patternsToTiles
                var patternArrays = overlapping.PatternArrays;
                tilesToPatternsByOffset = new Dictionary <int, IReadOnlyDictionary <Tile, ISet <int> > >();
                patternsToTilesByOffset = new Dictionary <int, IReadOnlyDictionary <int, Tile> >();
                for (int ox = 0; ox < overlapping.NX; ox++)
                {
                    for (int oy = 0; oy < overlapping.NY; oy++)
                    {
                        for (int oz = 0; oz < overlapping.NZ; oz++)
                        {
                            var o = CombineOffsets(ox, oy, oz);
                            var tilesToPatterns = new Dictionary <Tile, ISet <int> >();
                            tilesToPatternsByOffset[o] = tilesToPatterns;
                            var patternsToTiles = new Dictionary <int, Tile>();
                            patternsToTilesByOffset[o] = patternsToTiles;
                            for (var pattern = 0; pattern < patternArrays.Count; pattern++)
                            {
                                var patternArray = patternArrays[pattern];
                                var tile         = patternArray.Values[ox, oy, oz];
                                patternsToTiles[pattern] = tile;
                                if (!tilesToPatterns.TryGetValue(tile, out var patternSet))
                                {
                                    patternSet = tilesToPatterns[tile] = new HashSet <int>();
                                }
                                patternSet.Add(pattern);
                            }
                        }
                    }
                }
            }
            else
            {
                mappingType             = MappingType.OneToOne;
                tilesToPatternsByOffset = new Dictionary <int, IReadOnlyDictionary <Tile, ISet <int> > >()
                {
                    { 0, tileModel.TilesToPatterns.ToDictionary(g => g.Key, g => (ISet <int>) new HashSet <int>(g)) }
                };
                patternsToTilesByOffset = new Dictionary <int, IReadOnlyDictionary <int, Tile> >
                {
                    { 0, tileModel.PatternsToTiles },
                };
            }

            var waveConstraints =
                (constraints?.Select(x => new TileConstraintAdaptor(x, this)).ToArray() ?? Enumerable.Empty <IWaveConstraint>())
                .ToArray();

            this.wavePropagator = new WavePropagator(tileModel.GetPatternModel(), patternTopology, backtrack, waveConstraints, random, clear: false);
            wavePropagator.Clear();
        }
Ejemplo n.º 16
0
 public void Init(WavePropagator wavePropagator)
 {
     this.wave         = wavePropagator.Wave;
     this.patternCount = wavePropagator.PatternCount;
 }
Ejemplo n.º 17
0
 public Resolution Init(WavePropagator wavePropagator)
 {
     return(underlying.Init(propagator));
 }
Ejemplo n.º 18
0
        public Resolution Check(WavePropagator wp)
        {
            var wave    = wp.Wave;
            var indices = wp.Indices;
            // Initialize couldBePath and mustBePath based on wave possibilities
            var couldBePath = new bool[indices];
            var mustBePath  = new bool[indices];

            for (int i = 0; i < indices; i++)
            {
                var couldBe = false;
                var mustBe  = true;
                for (int p = 0; p < wp.PatternCount; p++)
                {
                    if (wave.Get(i, p))
                    {
                        if (PathPatterns.Contains(p))
                        {
                            couldBe = true;
                        }
                        if (!PathPatterns.Contains(p))
                        {
                            mustBe = false;
                        }
                    }
                }
                couldBePath[i] = couldBe;
                mustBePath[i]  = mustBe;
            }

            // Select relevant cells, i.e. those that must be connected.
            bool[] relevant;
            if (EndPoints == null)
            {
                relevant = mustBePath;
            }
            else
            {
                relevant = new bool[indices];
                if (EndPoints.Length == 0)
                {
                    return(Resolution.Undecided);
                }
                foreach (var endPoint in EndPoints)
                {
                    var index = wp.Topology.GetIndex(endPoint.X, endPoint.Y, endPoint.Z);
                    relevant[index] = true;
                }
            }
            var walkable = couldBePath;

            var isArticulation = PathConstraintUtils.GetArticulationPoints(wp.Topology, walkable, relevant);

            if (isArticulation == null)
            {
                return(Resolution.Contradiction);
            }


            // All articulation points must be paths,
            // So ban any other possibilities
            for (var i = 0; i < indices; i++)
            {
                if (!isArticulation[i])
                {
                    continue;
                }
                for (int p = 0; p < wp.PatternCount; p++)
                {
                    if (!PathPatterns.Contains(p) && wave.Get(i, p))
                    {
                        wp.InternalBan(i, p);
                    }
                }
            }

            return(Resolution.Undecided);
        }
Ejemplo n.º 19
0
 public void Init(WavePropagator wavePropagator)
 {
     filteredIndexPicker.Init(wavePropagator);
     wavePropagator.AddTracker(this);
 }
Ejemplo n.º 20
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);
        }
 // Don't run init twice
 void IPatternPicker.Init(WavePropagator wavePropagator)
 {
 }
Ejemplo n.º 22
0
 public void Init(WavePropagator wavePropagator)
 {
     underlying.Init(propagator);
 }
Ejemplo n.º 23
0
 public void Check(WavePropagator wavePropagator)
 {
     underlying.Check(propagator);
 }
Ejemplo n.º 24
0
 public void Init(WavePropagator wavePropagator)
 {
     wavePropagator.AddChoiceObserver(this);
     futureChoices = new Deque <int>();
     prevChoices   = new Deque <int>();
 }
Ejemplo n.º 25
0
 public void Init(WavePropagator wavePropagator)
 {
     wave        = wavePropagator.Wave;
     frequencies = wavePropagator.Frequencies;
 }
Ejemplo n.º 26
0
 public void Init(WavePropagator wavePropagator)
 {
     Init(wavePropagator.Wave, wavePropagator.Frequencies, wavePropagator.Topology.Mask);
     wavePropagator.AddTracker(this);
 }
Ejemplo n.º 27
0
 public Resolution Init(WavePropagator wp)
 {
     return(Check(wp));
 }
Ejemplo n.º 28
0
 public void Init(WavePropagator wavePropagator)
 {
     this.wave = wavePropagator.Wave;
 }
Ejemplo n.º 29
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.º 30
0
 public Resolution Check(WavePropagator wavePropagator)
 {
     return(underlying.Check(propagator));
 }