예제 #1
0
        public override int Evaluate(PuzzleState state, PuzzleState goalState)
        {
            int manhanttanDist = 0;

            var possibleRowConflicts = new Dictionary <int, List <Tuple <int, int> > >();
            var possibleColConflicts = new Dictionary <int, List <Tuple <int, int> > >();

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    int val = state.Board[i, j];
                    if (val == 0)
                    {
                        continue;
                    }

                    var correctPos = goalState.GetSpace(val);
                    manhanttanDist += ManhattanDistanceHeuristic.ManhattanDistance(i, j, correctPos.Row, correctPos.Col);

                    // check for linear conflicts in the horizontal + vertical direction

                    if (i == correctPos.Row && j != correctPos.Col)
                    {
                        if (!possibleRowConflicts.ContainsKey(i))
                        {
                            possibleRowConflicts[i] = new List <Tuple <int, int> >();
                        }

                        possibleRowConflicts[i].Add(Tuple.Create(j, correctPos.Col));
                    }

                    if (j == correctPos.Col && i != correctPos.Row)
                    {
                        if (!possibleColConflicts.ContainsKey(j))
                        {
                            possibleColConflicts[j] = new List <Tuple <int, int> >();
                        }

                        possibleColConflicts[j].Add(Tuple.Create(i, correctPos.Row));
                    }
                }
            }

            // Calculate the # of linear conflicts

            int linearConflicts = 0;

            foreach (List <Tuple <int, int> > possibleConflicts in possibleRowConflicts.Values.Concat(possibleColConflicts.Values))
            {
                Tuple <int, int> conflict = possibleConflicts.First();

                linearConflicts += possibleConflicts.Skip(1).Count(x => (x.Item1 > conflict.Item1 && x.Item2 < conflict.Item2) ||
                                                                   (x.Item1 <conflict.Item1 && x.Item2> conflict.Item2));
            }

            return(manhanttanDist + 2 * linearConflicts);
        }
예제 #2
0
파일: Heuristics.cs 프로젝트: spec2e/cs4701
        public override int Evaluate(PuzzleState state, PuzzleState goal)
        {
            var manhattanDistanceOff = 0;

            var possibleRowConflicts = new Dictionary <byte, List <Tuple <byte, byte> > >();
            var possibleColConflicts = new Dictionary <byte, List <Tuple <byte, byte> > >();

            for (byte i = 0; i < 4; i++)
            {
                for (byte j = 0; j < 4; j++)
                {
                    var val = state.Board[i, j];

                    if (val == 0)
                    {
                        continue; // skip the blank
                    }

                    var correctPlace = goal.GetSpace(val);
                    manhattanDistanceOff += ManhattanDistanceHeuristic.ManhattanDistance(i, j, correctPlace.Row, correctPlace.Col);

                    // now check for linear conflicts

                    // in correct row and wrong column?
                    if (i == correctPlace.Row && j != correctPlace.Col)
                    {
                        if (!possibleRowConflicts.ContainsKey(i))
                        {
                            possibleRowConflicts[i] = new List <Tuple <byte, byte> >();
                        }
                        possibleRowConflicts[i].Add(Tuple.Create(j, correctPlace.Col));
                    }

                    // in correct col and wrong row?
                    if (j == correctPlace.Col && i != correctPlace.Row)
                    {
                        if (!possibleColConflicts.ContainsKey(j))
                        {
                            possibleColConflicts[j] = new List <Tuple <byte, byte> >();
                        }
                        possibleColConflicts[j].Add(Tuple.Create(i, correctPlace.Row));
                    }
                }
            }

            var linearConflicts = 0;

            foreach (var possibleConflicts in possibleRowConflicts.Values.Concat(possibleColConflicts.Values))
            {
                var conflict = possibleConflicts.First();

                linearConflicts += possibleConflicts.Skip(1).Count(x => (x.Item1 > conflict.Item1 && x.Item2 < conflict.Item2) ||
                                                                   (x.Item1 <conflict.Item1 && x.Item2> conflict.Item2));
            }

            return(manhattanDistanceOff + 2 * linearConflicts);
        }