- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正尝试在我的 3D 网格中实现 A* 算法来寻路。我一直在学习教程,但没有找到有效的路径。我已经逐步查看我的代码以了解发生了什么,但我不知道如何解决问题。对于最基本的测试,我只使用 2-D 网格(它是 3-D,但只有一个 Z 选项,所以基本上是 2-D)。
这是它正在做的事情:
所以我们从 0,0(橙色)开始并希望到达 1,2(绿色)。首先,它计算橙色方 block 的两个选项,北和东,并针对 3 和 2.414 的 F 值获得 2 和 1.414 的距离。它移动到东广场 (0,1)。伟大的。但是现在它从 0,1 计算出两个空心正方形,即 1,1 和 0,2,它们的 g 值为 2,h 值(距离)为 1,因此它们的 F 值均为 3。
由于它们的 F 值为 3,而我们已经有一个 F 值为 3 的选项(从起点开始为 1,0),因此这两个选项将被忽略,即使它们显然是最佳选项。
然后它继续前进并切换到移动到 1,0,然后再次将 1,1 计算为 3,将 2,0 计算为 4.236。 1,1 的 f 值并不大于我们当前的 f 值,因此它被忽略,我们向上移动到 2,0。
2,0 只能向右移动。
2,1 只能向下移动,因为 2,2 是一个无效方 block ,但是移动到 1,1 的 f 值被保存为 3,所以它再次被忽略,让我们在 0,0 和 0,0 之间没有有效路径1,2。我错过了什么?
这是我的路径循环的片段。这里有一堆自定义结构,我正在使用 Unreal Engine 中的 TMap 来存储我的封闭列表,但我认为这对问题并不重要。以下是关于这些结构的简要说明:
PCell
: 保存单元格坐标PPair
: 将单元格坐标保存为 PCell 和 F 值FVectorInt
: 3-D整数 vector FPathCell
: 保存父坐标以及 f、g 和 h 值。cellDetails
是 FPathCell
的 3D 动态数组closedMap
是一个带有 <key, value>
的 TMap作为<IntVector, bool>
还有 locationIsWalkable(FVectorInt, StepDirection)
只是检查玩家是否可以从某个方向走到一个单元格的代码。你可以忽略那部分。
std::set<PPair> openList;
PPair originPair = PPair();
originPair.cell = PCell(i, j, k);
originPair.f = 0.0;
openList.insert(originPair);
bool foundDestination = false;
FPathCell destPair;
FVectorInt destCell;
while (!openList.empty() && !foundDestination)
{
iterations++;
PPair p = *openList.begin();
//Remove vertex
openList.erase(openList.begin());
//Add vertex to closed list
i = p.cell.i;
j = p.cell.j;
k = p.cell.k;
closedMap.Remove(FIntVector(i, j, k));
closedMap.Add(FIntVector(i, j, k), true);
double gNew, hNew, fNew;
//Generate movement options
//Option 1: NORTH (+X)
//Process if valid movement
if (locationIsWalkable(FVectorInt(i + 1, j, k), StepDirection::North))
{
FVectorInt check = FVectorInt(i + 1, j, k);
//If this cell is the destination
if (check == destination)
{
foundDestination = true;
//Set the parent of the destination cell
cellDetails[check.x][check.y][check.z].parent_i = i;
cellDetails[check.x][check.y][check.z].parent_j = j;
cellDetails[check.x][check.y][check.z].parent_k = k;
destPair = cellDetails[check.x][check.y][check.z];
destCell = check;
break;
}
//Else if this cell is not in the closed list
else if (!closedMap.FindRef(FIntVector(check.x, check.y, check.z)))
{
gNew = cellDetails[i][j][k].g + 1;
hNew = calculateHValue(check, destination);
fNew = gNew + hNew;
if (cellDetails[check.x][check.y][check.z].f == FLT_MAX ||
cellDetails[check.x][check.y][check.z].f > fNew) {
PPair cellPair = PPair();
cellPair.cell = PCell(check.x, check.y, check.z);
cellPair.f = fNew;
openList.insert(cellPair);
cellDetails[check.x][check.y][check.z].f = fNew;
cellDetails[check.x][check.y][check.z].g = gNew;
cellDetails[check.x][check.y][check.z].h = hNew;
cellDetails[check.x][check.y][check.z].parent_i = i;
cellDetails[check.x][check.y][check.z].parent_j = j;
cellDetails[check.x][check.y][check.z].parent_k = k;
}
}
}
//11 other movement options
}
inline bool operator<(const PPair& lhs, const PPair& rhs)
{
return lhs.f < rhs.f;
}
有 12 个移动选项(北、南、东、西、上+北、下+北等),但它们基本上都使用相同的代码,只是换掉了 check
。适当运动的 vector 。
最佳答案
Since their F values are 3 and we already have an option with an F value of 3 (1,0 from the starting point), these two options are ignored even though they are clearly the best options.
这一定是你的错误。这些选项不应被“忽略”,而是“延迟到它们成为下一个最佳选项”。这样做的方式是,在 A* 的每次迭代中,您应该选择 F 分数最低的开放单元格。
在您的示例中,展开0,1
(以获得0,2
和1,1
)后,您的开集应该看起来像:
(1,0):3 (1,1):3 (0,2):3
(也可以是这些的任何其他排列,因为它们具有相同的分数。)
现在假设它选择访问 1,0
。它将 2,0
添加到队列中,但是 1,1
和 0,2
应该仍然存在:
(1,1):3 (0,2):3 (2,0):4.236
由于 2,0
的 F-score 高于 1,1
或 0,2
,它不会尚未选择。相反,您的算法应在本次迭代中选择 1,1
或 0,2
,从而到达目的地 1,2
。
至于您的代码,您正在为 openList
使用 std::set
,这可以防止队列中有多个具有相同分数的实例。您可以使用 multiset
或 priority_queue
来解决这个问题。然而,A* 可以降低开放集中节点的权重,并且两种数据结构都不允许在亚线性时间内进行该操作。通过多次插入同一个节点(每次它的分数降低),并在它关闭后忽略任何弹出,您仍然会得到一个正确的算法,尽管不是最优的。
正确的 A* 实现通常使用二项式或斐波那契堆。不幸的是 C++ 没有它们。您可以在网络上找到实现这些功能的库。
关于c++ - A-Star 搜索算法找不到有效路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66077980/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!