简体   繁体   English

广度优先搜索算法不起作用导致无限循环

[英]Breadth First Search Algorithm Does Not Work Results in Infinite Loop

I am trying to do a BFS search where I dynamically create the Nodes of the graph as I search the State Space.我正在尝试进行 BFS 搜索,在搜索状态空间时动态创建图形的节点。 I followed the book but it does not work the frontier keeps on running and the explored set stays at the start value only.我跟着这本书,但它不起作用,边界继续运行,探索的集合只停留在起始值。 Please help, I have been stuck here for 4 days.请帮忙,我在这里卡了4天了。 Still a beginner programmer.仍然是初学者程序员。

Problem Class问题班

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    internal class Problem
    {
        public State start { get; set; }
        public State end { get; set; }

        public string[] action = { "UP", "LEFT", "DOWN", "RIGHT" };

        public Problem(State x, State y)
        {
            start = x;
            end = y;
        }

        public State Result(State s , string a)
        {
            State up;

            if (a == "UP" && s.X - 1 >= 0)
            {
                 up = new State(s.X - 1, s.Y);
               
            }
            else if (a == "LEFT" && s.Y - 1 >= 0)
            {
                up = new State(s.X, s.Y-1);
                
            }
            else if (a == "DOWN" && s.X + 1 <  5)
            {
                up = new State(s.X, s.Y+1);
               
            }
            else if( a == "RIGHT" && s.Y + 1 < 11)
            {
                up = new State(s.X + 1, s.Y);
                
            }
           
            return up;

           
        } 
    
        public bool GoalTest(Node<State> goal)
        {
            if (goal.Data.Equals(end))
            {
                return true;
            }
            return false;
        }
    
    }
}

Search Class搜索类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    internal class Search
    {
        public void BFS(Problem p)
        {
            Queue<Node<State>> frontier = new Queue<Node<State>>();
            HashSet<string> explored = new HashSet<string>();
            List<Node<State>> nNodes = new List<Node<State>>();

            Node<State> root = new Node<State>() {Data = p.start,};
            frontier.Enqueue(root);

            while(frontier.Count > 0)
            {
                Node<State> next = frontier.Dequeue();
                if(!explored.Add(next.Data.Data)) continue;
               

                next.Children = new List<Node<State>>();
                foreach(string action in p.action)
                {
                    next.Children.Add(new Node<State>() { Data = p.Result(next.Data, action), Parent = next });
                }

                for(int i = 0; i < next.Children.Count; i++)
                {
                    
                        if (p.GoalTest(next.Children[i]) == true)
                        {
                            //Solution(next.Children[i]);
                            break;
                        }
                        frontier.Enqueue(next.Children[i]);
                    
                }
            }
        }

        public void Solution(Node<State> n)
        {
            while(n.Parent != null)
            {
                Console.WriteLine(n.Parent.Data);
            }
        }
    }
}

Node Class节点类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    internal class Node<T>
    {
        public T Data { get; set; }
        public Node<T>? Parent { get; set; }
        public List<Node<T>> Children { get; set; }

    }
}

State Class州级

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    internal class State
    {
        public int X { get; set; }
        public int Y { get; set; }
        public string Data { get; }

        public State(int x, int y)
        {
            X = x;
            Y = y;
            Data = $"{X}-{Y}";
        }
    }
}

Main Program主程序

using Test;

State start = new State(0, 1);
State end = new State(3, 7);

Problem p = new Problem(start, end);

Search s = new Search();
s.BFS(p);

This is actually for my assignment hence I named it test.这实际上是我的任务,因此我将其命名为测试。
I am trying to implement the pseudocode from here: (Page 82) https://zoo.cs.yale.edu/classes/cs470/materials/aima2010.pdf我正在尝试从这里实现伪代码:(第 82 页) https://zoo.cs.yale.edu/classes/cs470/materials/aima2010.pdf

Update更新
It does not stuck now but it does not input anything into the console after the loop runs it is supposed to get the links between the goal node and the start node via the "Parent property" .它现在没有卡住,但是在循环运行后它没有向控制台输入任何内容,它应该通过"Parent property"获取目标节点和起始节点之间的链接。

You are never checking if nodes are already explored, so you will likely enter an infinite loop:您永远不会检查节点是否已被探索,因此您可能会进入无限循环:

explored.Add(next.Data.Data);

should be应该

if(!explored.Add(next.Data.Data)) continue;

But there might be other problems with the code.但是代码可能还有其他问题。 I would highly recommend reading Eric Lipperts articleHow to debug small programs since problems like this should be fairly easy to find and fix yourself with the help of a debugger.我强烈推荐阅读 Eric Lipperts 的文章如何调试小程序,因为这样的问题在调试器的帮助下应该很容易找到和解决。 Learning how to use a debugger is an invaluable skill that will make troubleshooting much easier.学习如何使用调试器是一项非常宝贵的技能,它将使故障排除变得更加容易。

I would also recommend removing all the strings from your program.我还建议从您的程序中删除所有字符串。 Instead you should create type representing a coordinate, ie a Point, or vector2Int.相反,您应该创建表示坐标的类型,即 Point 或 vector2Int。 I would recommend making this a readonly struct, and add ToString overload, IEquality<Point> implementation, operators for addition subtraction, equality etc. This type could then be used both for representing the state, and to represent the offsets.我建议将其设为只读结构,并添加ToString重载、 IEquality<Point>实现、加减运算符、相等等。然后,此类型既可用于表示状态,也可用于表示偏移量。 Such a type would be reusable for all kinds of different projects.这种类型将可用于各种不同的项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM