递归优化
Optimisation on recursion
我目前正在研究一种算法,在某个时刻,我必须遍历图像并对具有相同属性的像素进行分组。我从最左上角的像素开始,使用递归:从输入像素,我可以获得相邻像素的高度,如果第一个像素具有相同的属性,那么我通过将该像素作为输入像素来调用相同的函数。
这里有一些代码(请记住,这仍在进行中)。基本呼叫方:
// R.A.G.
for( std::vector<Cell*>::iterator iterCell = cellVec.begin();
iterCell != cellVec.end(); ++iterCell )
{
Cell* mother = (*iterCell);
if( mother->visited != true )
{
mother->visited = true;
}
CheckNeighbors( mother );
}
递归函数:
void
CheckNeighbors( Cell* mother )
{
Cell* cell = nullptr;
// Get the neighbours for the cell.
// 5 6 7
// 4 c 0
// 3 2 1
if( (cell=CheckCell( 1, 0, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( 1, 1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( 0, 1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( -1, 1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( -1, 0, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( -1, -1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( 0, -1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
if( (cell=CheckCell( 1, -1, mother )) != mother )
{
mother = cell;
CheckNeighbors( mother );
}
}
我如何检查细胞:
Cell*
CheckCell( int x, int y, Cell* cell )
{
// Here a cell is one pixel, but it depends on the size of the window we choose.
// So for an image of 640*480, windowSize = 1, w = 640, h = 480
x += cell->window.x()/windowSize;
y += cell->window.y()/windowSize;
// The cell at (x, y) coordinates is not in the map
if( x < 0 || x >= w || y < 0 || y >= h ) return cell;
// Get the neighbor cell in (x, y)
// NB: cellVec has been filled up earlier and contains all the cells
Cell* neighbor = cellVec.at( (y*w) + x );
// The neighbor cell has already been visited
if( neighbor->visited ) return cell;
// The neighbor cell is of the same class as the mother cell
if( neighbor->cClass != cell->cClass ) return cell;
// Set the region number for the neighbor
neighbor->visited = true;
return neighbor;
}
所以我的问题是:我确信这是可以改进的,但我想知道如何改进。我应该使用其他递归吗?如何改进这种递归?我读过这篇关于尾调用优化的文章,但在我的案例中,由于我不能丢弃调用者的状态,所以这是不适用的。但是,我还有别的把戏可以用吗?
谢谢你的回答,我希望我已经足够明确了。
注意:如果我有一个单色的图像,大小为640*480,单元格大小为2*2像素,我有153765个调用。当然还有一个单元格大小为1*1的segfault。我知道我可以增加堆栈的大小,但我更愿意找到另一个解决方案。
您正在做的是整体填充,实现为深度优先搜索。
要改进它,您可以:
- 将其记为广度优先搜索
- 使用堆栈实现深度优先搜索。这仍然是相同的想法,但使用堆栈而不是递归应该会使代码更快,使用更少的内存
使用迭代方法会更快,因为你已经在一个向量中拥有了所有元素,并且可以线性地运行它。这对缓存更友好,并且可以消除所有偏移的东西
// Copy all elements starting from the selected cell pointed to by the iterator, if
// they are equal to the cell
void checkAllCells(vector<Cell*> input, vector<Cell*>::iterator it; vector<Cell*> output)
{
auto localIt = it;
while( localIt != input.end())
{
if ((*localIt)->class == (*it)->class)
{
output.pushback(*it);
}
}
}
注意,您不需要像visited
等那样记账,因为从第一个元素开始,您会发现所有其他元素都是相等的。如果你取第二个元素,你知道,你已经在考虑前面的元素
相关文章:
- 尾递归函数未被 g++ 优化
- 优化 BigInt 递归函数
- 优化递归问题以计算超级数字
- 无限模板递归,因为没有布尔表达式优化,只有 gcc
- 自上而下的递归下降解析:依靠尾声优化
- 现代编译器优化如何将递归转换为返回常数
- 优化递归函数
- 优化此递归函数[Boggle resolver]
- 微优化-访问递归成员时的编译器优化
- 递归Finbonacci优化
- 在turbo c++中,可以将一个普通递归函数转换为尾递归函数来对其进行优化
- 为什么当递归函数结果相乘时,g++ 仍然优化尾递归
- 尝试优化和理解打印数字除数的递归函数的运行时
- 递归查找优化
- 优化递归函数
- 叮当无限尾递归优化
- constexpr函数求值可以做尾递归优化吗?
- 递归优化
- 编译器中的c++迭代vs递归优化
- gcc优化递归函数吗?怎么做