- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在调用
时遇到段错误auto n1=std::make_shared<Node>(n,n->x+i,n->y+j);
经过几次递归调用。奇怪的是它总是在同一时间点。谁能发现问题?这是一个动态规划问题的实现,在这里我正在累积一条路径的成本。我已经简化了成本函数,但在这个例子中问题仍然存在。
void HorizonLineDetector::dp(std::shared_ptr<Node> n)
{
n->cost= 1 + n->prev->cost;
//Check if we reached the last column(done!)
if (n->x==current_edges.cols-1)
{
//Save the info in the last node if it's the cheapest path
if (last_node->cost > n->cost)
{
last_node->cost=n->cost;
last_node->prev=n;
}
}
else
{
//Check for neighboring pixels to see if they are edges, launch dp with all the ones that are
for (int i=0;i<2;i++)
{
for (int j=-1;j<2;j++)
{
if (i==0 && j==0) continue;
if (n->x+i >= current_edges.cols || n->x+i < 0 ||
n->y+j >= current_edges.rows || n->y+j < 0) continue;
if (current_edges.at<char>(n->y+j,n->x+i)!=0)
{
auto n1=std::make_shared<Node>(n,n->x+i,n->y+j);
//n->next.push_back(n1);
nlist.push_back(n1);
dp(n1);
}
}
}
}
}
class Node
{
public:
Node(){}
Node(std::shared_ptr<Node> p,int x_,int y_){prev=p;x=x_;y=y_;lost=0;}
Node(Node &n1){x=n1.x;y=n1.y;cost=n1.cost;lost=n1.lost;prev=n1.prev;}//next=n1.next;}
std::shared_ptr<Node> prev; //Previous and next nodes
int cost; //Total cost until now
int lost; //Number of steps taken without a clear path
int x,y;
Node& operator=(const Node &n1){x=n1.x;y=n1.y;cost=n1.cost;lost=n1.lost;prev=n1.prev;}//next=n1.next;}
Node& operator=(Node &&n1){x=n1.x;y=n1.y;cost=n1.cost;lost=n1.lost;prev=n1.prev;n1.prev=nullptr;}//next=n1.next;n1.next.clear();}
};
最佳答案
您的代码看起来像病态路径搜索,因为它几乎检查每条路径并且不跟踪它已经检查过的路径,您可以获得不止一种方法。
这将构建等于最长路径长度的递归深度,然后是下一个最长路径,然后...向下到最短路径。即,类似于 O(# of pixels)深度。
这很糟糕。而且,由于调用堆栈深度有限,会使您崩溃。
简单的解决方案是将 dp
修改为 dp_internal
,并让 dp_internal
返回节点的 vector
处理下一步。然后编写 dp
,它调用 dp_internal
并重复其返回值。
std::vector<std::shared_ptr<Node>>
HorizonLineDetector::dp_internal(std::shared_ptr<Node> n)
{
std::vector<std::shared_ptr<Node>> retval;
...
if (current_edges.at<char>(n->y+j,n->x+i)!=0)
{
auto n1=std::make_shared<Node>(n,n->x+i,n->y+j);
//n->next.push_back(n1);
nlist.push_back(n1);
retval.push_back(n1);
}
...
return retval;
}
然后 dp
变成:
void HorizonLineDetector::dp(std::shared_ptr<Node> n)
{
std::vector<std::shared_ptr<Node>> nodes={n};
while (!nodes.empty()) {
auto node = nodes.back();
nodes.pop_back();
auto new_nodes = dp_internal(node);
nodes.insert(nodes.end(), new_nodes.begin(), new_nodes.end());
}
}
但是 (A) 当排队节点的数量变得异常大时,这可能会崩溃,并且 (B) 这只是对递归导致崩溃的补丁,不会让你的算法变得更糟。
使用 A*。
这涉及跟踪您访问过哪些节点以及下一步要处理哪些节点及其当前路径成本。
然后,您可以使用试探法来确定您应该首先检查接下来要处理的那些。如果您在某种网格上,启发式方法是在没有任何阻碍的情况下使用尽可能短的距离。
加上到达节点到进程的成本,加上从该节点到目的地的启发式距离。找到总计最少 的节点到进程。处理那个:您将其标记为已访问,并将其所有相邻节点添加到要处理的节点列表中。
切勿将节点添加到节点列表中以处理您已经访问过的节点(因为这是多余的工作)。
一旦您有了解决方案,修剪节点列表以针对当前路径值大于或等于您的解决方案的任何节点进行处理。如果您知道您的启发式算法很强(不可能更快到达目的地),您甚至可以根据启发式算法和当前成本的总和进行修剪。同样,不要添加到要处理的节点列表中,如果它会被本段修剪。
结果是您的算法在一条相对狭窄的线上搜索目标,然后向外扩展,试图找到绕过任何障碍的方法。如果有一条相对直接的路线,就会使用它,甚至不会触及宇宙的其余部分。
您可以对 A* 进行许多优化,甚至还有不依赖启发式的替代解决方案。但是从 A* 开始。
关于c++ - 使用智能指针时递归函数中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36083173/
在本教程中,您将借助示例了解 JavaScript 中的递归。 递归是一个调用自身的过程。调用自身的函数称为递归函数。 递归函数的语法是: function recurse() {
我的类(class) MyClass 中有这段代码: public new MyClass this[int index] { get {
我目前有一个非常大的网站,大小约为 5GB,包含 60,000 个文件。当前主机在帮助我将站点转移到新主机方面并没有做太多事情,我想的是在我的新主机上制作一个简单的脚本以 FTP 到旧主机并下载整个
以下是我对 AP 计算机科学问题的改编。书上说应该打印00100123我认为它应该打印 0010012但下面的代码实际上打印了 3132123 这是怎么回事?而且它似乎没有任何停止条件?! publi
fun fact(x: Int): Int{ tailrec fun factTail(y: Int, z: Int): Int{ if (y == 0) return z
我正在尝试用c语言递归地创建线性链表,但继续坚持下去,代码无法正常工作,并出现错误“链接器工具错误 LNK2019”。可悲的是我不明白发生了什么事。这是我的代码。 感谢您提前提供的大力帮助。 #inc
我正在练习递归。从概念上讲,我理解这应该如何工作(见下文),但我的代码不起作用。 请告诉我我做错了什么。并请解释您的代码的每个步骤及其工作原理。清晰的解释比只给我有效的代码要好十倍。 /* b
我有一个 ajax 调用,我想在完成解析并将结果动画化到页面中后调用它。这就是我陷入困境的地方。 我能记忆起这个功能,但它似乎没有考虑到动画的延迟。即控制台不断以疯狂的速度输出值。 我认为 setIn
有人愿意用通俗易懂的语言逐步解释这个程序(取自书籍教程)以帮助我理解递归吗? var reverseArray = function(x,indx,str) { return indx == 0 ?
目标是找出数组中整数的任意组合是否等于数组中的最大整数。 function ArrayAdditionI(arr) { arr.sort(function(a,b){ return a -
我在尝试获取 SQL 查询所需的所有数据时遇到一些重大问题。我对查询还很陌生,所以我会尽力尽可能地描述这一点。 我正在尝试使用 Wordpress 插件 NextGen Gallery 进行交叉查询。
虽然网上有很多关于递归的信息,但我还没有找到任何可以应用于我的问题的信息。我对编程还是很陌生,所以如果我的问题很微不足道,请原谅。 感谢您的帮助:) 这就是我想要的结果: listVariations
我一整天都在为以下问题而苦苦挣扎。我一开始就有问题。我不知道如何使用递归来解决这个特定问题。我将非常感谢您的帮助,因为我的期末考试还有几天。干杯 假设有一个包含“n”个元素的整数数组“a”。编写递归函
我有这个问题我想创建一个递归函数来计算所有可能的数字 (k>0),加上数字 1 或 2。数字 2 的示例我有两个可能性。 2 = 1+1 和 2 = 2 ,对于数字 3 两个 poss。 3 = 1+
目录 递归的基础 递归的底层实现(不是重点) 递归的应用场景 编程中 两种解决问题的思维 自下而上(Bottom-Up) 自上而下(Top-
0. 学习目标 递归函数是直接调用自己或通过一系列语句间接调用自己的函数。递归在程序设计有着举足轻重的作用,在很多情况下,借助递归可以优雅的解决问题。本节主要介绍递归的基本概念以及如何构建递归程序。
我有一个问题一直困扰着我,希望有人能提供帮助。我认为它可能必须通过递归和/或排列来解决,但我不是一个足够好的 (PHP) 程序员。 $map[] = array("0", "1", "2", "3")
我有数据 library(dplyr, warn.conflicts = FALSE) mtcars %>% as_tibble() %>% select(mpg, qsec) %>% h
在 q 中,over 的常见插图运算符(operator) /是 implementation of fibonacci sequence 10 {x,sum -2#x}/ 1 1 这确实打印了前 1
我试图理解以下代码片段中的递归调用。 static long fib(int n) { return n <= 1 ? n : fib(n-1) + fib(n-2); } 哪个函数调用首先被
我是一名优秀的程序员,十分优秀!