Пример #1
0
        /// <summary>
        /// Add all cases of the tests
        /// </summary>
        /// <returns></returns>
        private List <List <CandidateNode> > GetAllCasesTest()
        {
            CandidateNode root = SetCandidateNode(null, 0, BuildingTree());

            root.AddPath(root, new List <CandidateNode>());
            return(root.paths);
        }
Пример #2
0
    private static void Start()
    {
        while (openList.Count > 0)
        {
            // algorithm's logic goes here
            // get the square with the lowest F score
            var lowest = openList.Min(l => l.F_Score);
            current = openList.First(l => Math.Abs(l.F_Score - lowest) < 0.05);

            // add the current square to the closed list
            closedList.Add(current);

            // remove it from the open list
            openList.Remove(current);

            //if (closedList.FirstOrDefault(l => l.Position.x == targetLoc.x && l.Position.y == targetLoc.y) != null) //Original
            if (closedList.FirstOrDefault(l => Math.Abs(l.Position.x - targetLoc.x) < 0.05 && Math.Abs(l.Position.y - targetLoc.y) < 0.05) != null)
            {
                break;
            }

            var adjacentNodes = GetWalkableAdjacentNodes(current.Position, GlobalGameManager.Instance.validMapNodes);
            g++;

            foreach (var adjacentSquare in adjacentNodes)
            {
                // if this adjacent square is already in the closed list, ignore it
                if (closedList.FirstOrDefault(l => l.Position == adjacentSquare.Position) != null)
                {
                    continue;
                }

                // if it's not in the open list...
                if (openList.FirstOrDefault(l => l.Position == adjacentSquare.Position) == null)
                {
                    // compute its score, set the parent
                    adjacentSquare.G_Score = g;
                    adjacentSquare.H_Score = ComputeHScore(adjacentSquare.Position, targetLoc);
                    adjacentSquare.F_Score = adjacentSquare.G_Score + adjacentSquare.H_Score;
                    adjacentSquare.Parent  = current;

                    // and add it to the open list
                    openList.Insert(0, adjacentSquare);
                }
                else
                {
                    // test if using the current G score makes the adjacent square's F score
                    // lower, if yes update the parent because it means it's a better path
                    if (g + adjacentSquare.H_Score < adjacentSquare.F_Score)
                    {
                        adjacentSquare.G_Score = g;
                        adjacentSquare.F_Score = adjacentSquare.G_Score + adjacentSquare.H_Score;
                        adjacentSquare.Parent  = current;
                    }
                }
            }
        }
Пример #3
0
 private static void Init(Vector2 start, Vector2 destination)
 {
     current    = null;
     startLoc   = current;
     targetLoc  = destination;
     openList   = new List <CandidateNode>();
     closedList = new List <CandidateNode>();
     g          = 0;
     openList.Add(startLoc);
 }
Пример #4
0
                public List <CandidateNode> getNextCandidates()
                {
                    List <int> skipFigurates = new List <int>();

                    foreach (int x in nums)
                    {
                        Pair p;
                        figurateDict.TryGetValue(x, out p);
                        skipFigurates.Add(p.whichFigurate);
                    }

                    List <CandidateNode> newNodes = new List <CandidateNode>();

                    foreach (int a in nums)
                    {
                        for (int x = 0; x < 6; ++x)
                        {
                            // skip figurates we already have
                            if (!skipFigurates.Contains(x))
                            {
                                for (int i = 0; i < figurates[x].Length; ++i)
                                {
                                    if (isCyclicPair(a, figurates[x][i]) &&
                                        a != figurates[x][i] &&
                                        !figurateDict.ContainsKey(figurates[x][i]))
                                    {
                                        // create new node
                                        List <int> t = new List <int>();
                                        foreach (int b in nums)
                                        {
                                            t.Add(b);
                                        }
                                        t.Add(figurates[x][i]);
                                        Dictionary <int, Pair> d = new Dictionary <int, Pair>();
                                        Pair p;
                                        foreach (int key in figurateDict.Keys)
                                        {
                                            figurateDict.TryGetValue(key, out p);
                                            d.Add(key, p);
                                        }
                                        p = new Pair();
                                        p.whichFigurate = x;
                                        p.index         = i;
                                        d.Add(figurates[x][i], p);
                                        CandidateNode node = new CandidateNode(t, d);
                                        newNodes.Add(node);
                                    }
                                }
                            }
                        }
                    }
                    return(newNodes);
                }
        /// <summary>
        ///     Set relation of all Nodes in the Tree
        /// </summary>
        /// <param name="value"></param>
        /// <param name="pos"></param>
        /// <param name="quizs"></param>
        /// <returns></returns>
        public CandidateNode SetCandidateNode(Candidate value, int pos, int[] quizs)
        {
            var child = new CandidateNode
            {
                Candi = value
            };

            if (pos < quizs.Length)
            {
                foreach (var candi in QuestionSet.QuestionList.ElementAt(pos).Candidates)
                {
                    child.Children.Add(SetCandidateNode(candi, pos + 1, quizs));
                }
            }
            else
            {
                child.Children = null;
            }
            return(child);
        }
Пример #6
0
            private void backTrack(CandidateNode node)
            {
                // the decision tree is going to be built using recursion
                if (node.isSolution())
                {
                    // we've found the answer and must print it!
                    node.print();
                    return;
                }

                // if we haven't found the solution, then
                // we run our backtracking algorithm
                // Note that we don't prune any nodes early,
                // this algorithm is decidedly faster than the
                // original brute force algorithm that I'd been using
                // since this algorithm will eliminate certain choices
                // by virtue of the 'next candidate' function
                List <CandidateNode> nextCandidates = node.getNextCandidates();

                foreach (CandidateNode next in nextCandidates)
                {
                    backTrack(next);
                }
            }
Пример #7
0
            public void getSolution()
            {
                for (int x = 0; x < 6; ++x)
                {
                    for (int i = 0; i < figurates[x].Length; ++i)
                    {
                        List <int> start = new List <int>();
                        Dictionary <int, CandidateNode.Pair> figurateDict = new Dictionary <int, CandidateNode.Pair>();
                        CandidateNode.Pair p = new CandidateNode.Pair();
                        p.whichFigurate = x;
                        p.index         = i;
                        start.Add(figurates[x][i]);
                        figurateDict.Add(figurates[x][i], p);
                        CandidateNode root = new CandidateNode(start, figurateDict);
                        backTrack(root);
                    }
                }

                // we need to traverse a decision tree.... we need a backtracking algorithm!

                // we use each possible starting point as a root node since it would seem
                // a bit arduous to code the recursive calls to handle both the regular
                // recursive parts as well as the initial special case that starts the process off

                //    if(pieces.Count == 0)
                //    {
                //        pieces.Add(figurates[initialFigurate][initialFiguratePos]);
                //        hasPiece[initialFigurate] = true;
                //        thrownAway.Clear();
                //        throwAwayLevel = 0;
                //        return true;
                //    }

                //    // if we have all pieces, then we must check to see
                //    // if the entire set is cyclic
                //    if (pieces.Count == 6)
                //    {
                //        List<int> t = new List<int>();
                //        foreach(int x in pieces)
                //        {
                //            t.Add(x);
                //        }

                //        // debug print
                //        string s = "";
                //        foreach (int x in pieces)
                //            s += x + " ";
                //        Console.WriteLine("Answer: " + s);

                //        if(oneArrangementIsCyclic(t))
                //        {
                //            // we've found the answer and must print it!
                //            string s2 = "";
                //            foreach (int x in pieces)
                //                s2 += x + " ";
                //            Console.WriteLine("Answer: " + s2);
                //            return false;
                //        }
                //        else
                //        {
                //            // we haven't found the answer and must continue
                //            // our search
                //            goto NewSearch;
                //        }
                //    }



                //    // if another piece cannot be found then we must
                //    // reset this object, except we must be sure that
                //    // we do not re-use the same starting piece, thus
                //    // we begin the entire process again using the next
                //    // figurate piece
                //NewSearch:

                //    // we have something of a problem...
                //    // when we cannot find another piece, it's quite
                //    // possible that we need only backtrack one level
                //    // and we will find the answer so that is what we must do

                //    // remove the last element
                //    // and add it to the list of items that
                //    // are to be excluded from future piece
                //    // searches
                //    if(throwAwayLevel == 0)
                //    {
                //        // if the throwAwayLevel is zero then
                //        // we can safely assume the value hasn't been
                //        // set yet (since you must have something to throw away!)
                //        throwAwayLevel = pieces.Count;
                //        thrownAway.Clear();
                //    }
                //    else
                //    {
                //        if(throwAwayLevel != pieces.Count)
                //        {
                //            // here we know that we've backtracked
                //            // to a different number of pieces, and
                //            // can free the thrown away numbers
                //            throwAwayLevel = pieces.Count;
                //            thrownAway.Clear();
                //        }
                //    }
                //    thrownAway.Add(pieces[pieces.Count - 1]);
                //    pieces.Remove(pieces[pieces.Count - 1]);

                //    // reset flags for which pieces this object holds
                //    for (int i = 0; i < 6; ++i )
                //    {
                //        hasPiece[i] = false;
                //    }
                //    foreach (int x in pieces)
                //    {
                //        for (int i = 0; i < 6; ++i)
                //        {
                //            for (int j = 0; j < figurates[i].Length; ++j)
                //            {
                //                if (figurates[i][j] == x)
                //                {
                //                    hasPiece[i] = true;
                //                    break;
                //                }
                //            }
                //        }
                //    }

                //    // we have a small problem since calling this function
                //    // again will retrieve the piece that we threw away.....

                //    // ... here it becomes a bit more clear that we need something
                //    // of a backtracking algorithm....

                //    // I suppose we only need to track one level, that is if we
                //    // start throwing away pieces when we have 6 of them, then
                //    // we need only keep track of those thrown away as long as
                //    // we are picking up a 6th piece..... I'm not sure if this
                //    // reasoning makes sense but it's worth a shot!

                //    // as it turns out.. NOPE ... the line of reasoning that
                //    // I just attempted doesn't work! It's possible to re-enter
                //    // a previous decision that was found to be fruitless causing
                //    // a loop. You need a genuine backtracking algorithm to
                //    // handle this problem appropriately
                //    return findAnotherCyclicPiece();
            }