Beispiel #1
0
        public void Constrain_GroupsConstraintsAsExpected()
        {
            int size    = 4;
            int boxSize = 2;

            int[] possibleValues   = new int[] { 1, 3, 5, 7 };
            var   puzzle           = new Puzzle(size);
            var   matrix           = ExactCoverGraph.Create(puzzle);
            var   squareObjectives = new HashSet <Objective>(matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities());

            Assert.True(new BoxUniquenessConstraint().TryConstrain(puzzle, matrix));

            Assert.Equal(
                size * possibleValues.Length + squareObjectives.Count,
                matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities().Count());
            Dictionary <int, HashSet <int> > boxIndicesToValues = new();

            for (int i = 0; i < size; ++i)
            {
                boxIndicesToValues[i] = new HashSet <int>();
            }
            Assert.All(matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities(),
                       concreteObjective =>
            {
                if (squareObjectives.Contains(concreteObjective))
                {
                    return;
                }
                IObjective objective = concreteObjective;
                var possibilities    = objective.GetUnknownDirectPossibilities().Cast <Possibility>().ToArray();
                int boxIndex         = Boxes.CalculateBoxIndex(possibilities[0].Coordinate, boxSize);
                int value            = possibilities[0].Index;
                Assert.DoesNotContain(value, boxIndicesToValues[boxIndex]);
                boxIndicesToValues[boxIndex].Add(value);
                var boxCoordinates = Boxes.YieldUnsetCoordsForBox(boxIndex, boxSize, puzzle).ToArray();
                Assert.Equal(boxCoordinates.Length, possibilities.Length);
                Assert.All(possibilities, p =>
                {
                    Assert.Contains(p.Coordinate, boxCoordinates);
                    Assert.Equal(value, p.Index);
                });
                Assert.All(boxCoordinates, c => Assert.NotNull(possibilities.SingleOrDefault(p => p.Coordinate == c)));
            });
            Assert.All(
                boxIndicesToValues.Values,
                values => Assert.Equal(new HashSet <int> {
                0, 1, 2, 3
            }, values));
        }
Beispiel #2
0
        public void YieldUnsetForBox_ReturnsAllUnsetCoordsInBox()
        {
            var puzzle = new Puzzle(new int?[][] {
                new int?[] { 1, null, null, 2 },
                new int?[] { null, null, 1, null },
                new int?[] { null, 1, null, null },
                new int?[] { 3, null, 4, null }
            });
            int box      = 1;
            var allUnset = new List <Coordinate>(Boxes.YieldUnsetCoordsForBox(box, boxSize: 2, puzzle: puzzle));

            Assert.Equal(2, allUnset.Count);
            Assert.Equal(new HashSet <Coordinate> {
                new(0, 2), new(1, 3)
            }, new HashSet <Coordinate>(allUnset));
        /// <inheritdoc/>
        public bool UpdateAll()
        {
            Debug.Assert(
                _puzzle is not null && _helper is not null,
                $"Must initialize heuristic before calling {nameof(UpdateAll)}.");
            int size = _puzzle.Size;
            var possibleValuesToCheck = new BitVector[size];
            var coordinatesToCheck    = new Coordinate[size][];

            for (int boxIdx = 0; boxIdx < size; ++boxIdx)
            {
                possibleValuesToCheck[boxIdx] = _boxTracker.GetMissingValuesForBox(boxIdx);
                coordinatesToCheck[boxIdx]    = Boxes.YieldUnsetCoordsForBox(boxIdx, _boxSize, _puzzle).ToArray();
            }
            return(_helper.UpdateIfUnique(possibleValuesToCheck, coordinatesToCheck));
        }