我正在嘗試進行 BFS 搜索,在搜索狀態空間時動態創建圖形的節點。我跟著這本書,但它不起作用,邊界繼續運行,探索的集合只停留在起始值。請幫忙,我在這里卡了4天了。仍然是初學者程式員。
問題班
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;
}
}
}
搜索類
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);
}
}
}
}
節點類
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; }
}
}
州級
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}";
}
}
}
主程式
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);
這實際上是我的任務,因此我將其命名為測驗。
我正在嘗試從這里實作偽代碼:(第 82 頁)
https://zoo.cs.yale.edu/classes/cs470/materials/aima2010.pdf
更新
它現在沒有卡住,但是在回圈運行后它沒有向控制臺輸入任何內容它應該通過“父屬性”獲取目標節點和開始節點之間的鏈接。
uj5u.com熱心網友回復:
您永遠不會檢查節點是否已被探索,因此您可能會進入無限回圈:
explored.Add(next.Data.Data);
應該
if(!explored.Add(next.Data.Data)) continue;
但是代碼可能還有其他問題。我強烈推薦閱讀 Eric Lipperts 的文章如何除錯小程式,因為這樣的問題在除錯器的幫助下應該很容易找到和解決。學習如何使用除錯器是一項非常寶貴的技能,它將使故障排除變得更加容易。
我還建議從您的程式中洗掉所有字串。相反,您應該創建表示坐標的型別,即 Point 或 vector2Int。我建議將其設為只讀結構,并添加ToString多載、IEquality<Point>實作、加減法運算子、相等等。然后這種型別既可以用于表示狀態,也可以用于表示偏移量。這種型別將可用于各種不同的專案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/478418.html
上一篇:在資料結構中查找書籍的搜索功能
下一篇:python中A*實作的優化
