【发布时间】:2013-06-11 12:47:19
【问题描述】:
我在一个简单的 Winforms 应用程序中实现了 A*-pathfinding。还可以在网格上定义障碍物,以便代理可以在它们周围导航。
问题是我的代理无法预见路径。这就是为什么他并不总是选择最优路径。
Here you can see my exact problem.
如何让探路者预测较短的路径?一旦代理走错路,也会出现死胡同的问题。
此方法获取相邻单元格并计算值:
public void addAdjascent(Vector pos)
{
foreach(Cell cell in allCells)
{
bool containedInClosedList = closedList.Any(c => c.id == cell.id);
if (!containedInClosedList)
{
if (cell.positionCR.X == pos.X - 1 && cell.positionCR.Y == pos.Y)
{
bool containedInBlockedList = blockedList.Any(c => c.id == cell.id);
if(!containedInBlockedList)
{
cell.H = calcH(goal,cell);
cell.G = calcG(start, cell);
cell.F = cell.G + cell.H;
openList.Add(cell);
}
}
if (cell.positionCR.X == pos.X + 1 && cell.positionCR.Y == pos.Y)
{
bool containedInBlockedList = blockedList.Any(c => c.id == cell.id);
if (!containedInBlockedList)
{
cell.H = calcH(goal, cell);
cell.G = calcG(start, cell);
cell.F = cell.G + cell.H;
openList.Add(cell);
}
}
if (cell.positionCR.X == pos.X && cell.positionCR.Y == pos.Y - 1)
{
bool containedInBlockedList = blockedList.Any(c => c.id == cell.id);
if (!containedInBlockedList)
{
cell.H = calcH(goal, cell);
cell.G = calcG(start, cell);
cell.F = cell.G + cell.H;
openList.Add(cell);
}
}
if (cell.positionCR.X == pos.X && cell.positionCR.Y == pos.Y + 1)
{
bool containedInBlockedList = blockedList.Any(c => c.id == cell.id);
if (!containedInBlockedList)
{
cell.H = calcH(goal, cell);
cell.G = calcG(start, cell);
cell.F = cell.G + cell.H;
openList.Add(cell);
}
}
if (cell.positionCR.X == pos.X - 1 && cell.positionCR.Y == pos.Y - 1)
{
bool containedInBlockedList = blockedList.Any(c => c.id == cell.id);
if (!containedInBlockedList)
{
cell.H = calcH(goal, cell);
cell.G = calcG(start, cell);
cell.F = cell.G + cell.H;
openList.Add(cell);
}
}
if (cell.positionCR.X == pos.X - 1 && cell.positionCR.Y == pos.Y + 1)
{
bool containedInBlockedList = blockedList.Any(c => c.id == cell.id);
if (!containedInBlockedList)
{
cell.H = calcH(goal, cell);
cell.G = calcG(start, cell);
cell.F = cell.G + cell.H;
openList.Add(cell);
}
}
if (cell.positionCR.X == pos.X + 1 && cell.positionCR.Y == pos.Y - 1)
{
bool containedInBlockedList = blockedList.Any(c => c.id == cell.id);
if (!containedInBlockedList)
{
cell.H = calcH(goal, cell);
cell.G = calcG(start, cell);
cell.F = cell.G + cell.H;
openList.Add(cell);
}
}
if (cell.positionCR.X == pos.X + 1 && cell.positionCR.Y == pos.Y + 1)
{
bool containedInBlockedList = blockedList.Any(c => c.id == cell.id);
if (!containedInBlockedList)
{
cell.H = calcH(goal, cell);
cell.G = calcG(start, cell);
cell.F = cell.G + cell.H;
openList.Add(cell);
}
}
}
}
}
这里是计算G和H值的代码:
public int calcG(Vector start,Cell cell)
{
int distance = closedList.Count;
return distance;
}
public int calcH(Vector goal, Cell cell)
{
int distance;
int distanceX = (goal.X) - cell.positionCR.X;
int distanceY = (goal.Y) - cell.positionCR.Y;
if (distanceX < 0)
{
distanceX = distanceX * -1;
}
if (distanceY < 0)
{
distanceY = distanceY * -1;
}
distance = distanceX + distanceY;
return distance;
}
最后我计算出我想踩的下一个单元格:
public void step()
{
addAdjascent(stepPos);
bool foundDestination = false;
int min = 8000;
foreach(Cell openCell in openList)
{
if (openCell.F < min)
{
min = openCell.F;
}
}
if(openList.Count > 0)
{
foreach (Cell openCell in openList)
{
if (openCell.positionCR.X == goal.X && openCell.positionCR.Y == goal.Y)
{
closedList.Add(openCell);
stepPos = openCell.positionCR;
foundDestination = true;
}
}
}
if(!foundDestination)
{
closedList.Add(openList.First(item => item.F == min));
stepPos = openList.First(item => item.F == min).positionCR;
}
openList.Clear();
}
【问题讨论】:
-
那属于你的算法问题。
-
你能告诉我们你的代码吗?
-
+1 太酷了!不过不确定它与 WinForms 有什么关系。
-
这个 A* 怎么样?您显然没有使用 A* 计算最佳路径,然后执行该路径。您只是在接受 A* 的第一个猜测。您只使用了 A* 算法的一个循环,并指责它在找到实际最佳路径之前没有做与循环相同的事情。
-
@RenéWolferink:非常感谢,在这里也找到了一个非常好的:dotnetperls.com/pathfinding
标签: c# winforms optimization path-finding a-star