如何使用BFS算法只保留外部点
How to use the BFS algorithm to keep only the outer points?
假设我有一个 500x500 的 2D 网格(从 -250 到 250)。
网格的每个单元格都有一个特定的值,从 0 到 100。
我一直在尝试做的是从点 (0, 0) 开始保留值小于 50 的所有单元格的列表,但我不想保留所有点,而只保留外部点(周长、边界、值小于 50 的单元格没有 4 个相邻单元格的值小于 50)。
我实现算法的方式,我保留了所有点的列表。我应该如何修改它?如果可能的话,我想优化代码(我可以有更大的网格),所以我不想再次迭代。
pointList pointsWithValueBelow50; // The list of points with a value below 50
map<point, bool> pointDiscovered; // A map of the points we already passed through
point a = {0,0};
point b;
int value;
Queue q;
q.enqueue(a);
pointDiscovered[a] = true;
while(!q.isEmpty())
{
a = q.dequeue(a)
value = calculateValue(a); // Random method that verify if the points has a value below 50 in the grid
if (value < 50)
{
pointsWithValueBelow50.add(a);
b[0] = a[0]+1;
b[1] = a[1];
if(pointDiscovered[b] == false)
{
q.enqueue(b)
pointDiscovered[b] = true;
}
b[0] = a[0]-1;
b[1] = a[1];
if(pointDiscovered[b] == false)
{
q.enqueue(b)
pointDiscovered[b] = true;
}
b[0] = a[0];
b[1] = a[1]+1;
if(pointDiscovered[b] == false)
{
q.enqueue(b)
pointDiscovered[b] = true;
}
b[0] = a[0];
b[1] = a[1]-1;
if(pointDiscovered[b] == false)
{
q.enqueue(b)
pointDiscovered[b] = true;
}
}
}
如您所见,我将值低于 50 的所有点保留在我的列表中,而不是外部点。如何修改此代码?我应该使用其他算法吗?
让我们将单元格数组视为灰度图像(其中单元格值是像素强度)。您尝试执行的操作("查找边框")是图形中的常见问题,并且有一种众所周知的算法(行进方块)来查找列表等边框(具有列表的附加属性被排序,因此当您遍历列表时,您将绕过包含感兴趣区域的多边形的顶点。
行进方块是 O(单元格)(在最坏的情况下,它只需要查看每个单元格邻域一次),并且可以并行化以获得更高的性能。根据被视为相关过渡的内容以及您是只想查找一个边界还是所有边界,有许多变化。
那里有很多实现。我读过的最干净的一个是这里(LGPL;返回所有边界;可配置的阈值) - 将其从Java转换为C++应该相对简单。
抱歉,我忘了添加我的解决方案。不幸的是,我认为它内存很重,所以任何新的答案都会被欣然接受!
pointList pointsWithValueBelow50; // The list of points with a value below 50
pointList pointsBorder;
map<point, bool> pointDiscovered; // A map of the points we already passed through
map<point, bool> pointVisible; // The final visible points
map<point, point> pointParent; // A map of the parent point
point a = {0,0};
point b;
int value;
Queue q;
q.enqueue(a);
pointDiscovered[a] = true;
while(!q.isEmpty())
{
a = q.dequeue(a)
value = calculateValue(a); // Random method that verify if the points has a value below 50 in the grid
if (value < 50)
{
pointsWithValueBelow50.add(a);
b[0] = a[0]+1;
b[1] = a[1];
if(pointDiscovered[b] == false)
{
q.enqueue(b)
pointParent[b] = a
pointDiscovered[b] = true;
}
b[0] = a[0]-1;
b[1] = a[1];
if(pointDiscovered[b] == false)
{
q.enqueue(b)
pointParent[b] = a
pointDiscovered[b] = true;
}
b[0] = a[0];
b[1] = a[1]+1;
if(pointDiscovered[b] == false)
{
q.enqueue(b)
pointParent[b] = a
pointDiscovered[b] = true;
}
b[0] = a[0];
b[1] = a[1]-1;
if(pointDiscovered[b] == false)
{
q.enqueue(b)
pointParent[b] = a
pointDiscovered[b] = true;
}
}
else
{
if(pointVisible[pointParent[a]] == false)
{
pointVisible[pointParent[a]] = true;
pointsBorder.add(poinParent[a]);
}
}
}
这个想法很简单,如果我在一个值高于 50 的点,我们让父点知道他必须是可见的,因为他是"边界"点。
相关文章:
- 有根的二进制搜索树.保留与其父级的链接
- 为多个会话保留XPtr
- 在函数内部的声明中初始化数组,并在外部使用它
- 使外部项目可用于find_package CMake
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- C++:来自外部文件的Trivia
- 从函数角度看ID到文件路径的内部与外部映射
- C++:将外部库链接到dll库
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 节俭并发:未解决的外部问题
- 如何在c++中从git建立外部库
- 未解析的外部符号_MsiLocateComponentW@12.
- 如何使用对C函数和类对象的外部调用来处理C++头文件
- 保留对其他类的成员函数的引用
- 具有外部"c"和程序集的未定义函数
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 在C++中使用 gRPC 时未解析的外部符号
- 外部"C"不允许 C 标头使用C++保留字
- 如何使用BFS算法只保留外部点