我有一个1000 x 1000的网格,其中一个人Q从起点A行进到停止点B.当Q从A开始时,他随机走,直到他到达B.通过随机行走,我的意思是对于Q当前的任何位置(i,j),Q可以相等地行进到(i + 1,j),(i-1,j),(i,j + 1),(i,j-1)可能性。如果Q以这种方式到达B,他会获得存储在B的宝藏,现在他想要追溯他从A到B的完全相同的路径,只是向后。
有没有办法在C ++中实现它而不在路径中明确存储路径?
答案 0 :(得分:2)
你可能会做这样的事情:
到达目的地后,反向移动移动计数种子,从计数到0,然后采取相反的步骤。
重点是移动计数和种子。假设随机种子是一个fornal函数,给定相同的输入,你应该总是得到相同的输出。您可以存储初始时间,修复时间步长,然后允许种子成为当前时间或其他时间步骤,但想法是允许种子与计数相关。
使用此方法,您应该只能使用开始时间和到达目标所需的滴答数量来提取路径。此外,还有一个额外的好处:您还可以存储在刻度线中到达目的地所需的时间,并获得取决于该时间状态的其他变量。
答案 1 :(得分:1)
使用可逆的伪随机生成器。
例如,对于线性同余生成器Y =(a.X + b)mod c,可能可以将关系反转为X =(a'.Y + b')mod c'。
使用这样的发电机,您可以沿着路径自由往返。
快速(但不支持理论)方法的建议:使用累加器并添加任意常量,忽略溢出;这个过程完全被减法反转。取两个独立的累加器位来形成随机数。
答案 2 :(得分:0)
您可以通过递归隐式存储它。
这个想法很简单:你测试你是否处于财富状态并且如果你是的话返回true
。否则,您随机选择一个不同的路径并返回其结果,以便处理路径或必要时回溯。改变这种方法以完全匹配你的循环正在做的事情不应该太难(例如,你可能只想在所有选项都耗尽后回溯)。
从每个函数返回后,您立即反向使用该路径。
bool walk_around(size_t x, size_t y) {
if(treasure(x, y)) return true;
if(better_abort()) return false;
size_t x2, y2;
randomly_choose(&x2, &y2);
if(walk_around(x2, y2))
{
std::cout << x << "," << y << "\n";
return true;
}
else return false;
}
请注意,此方法存在危险:线程堆栈(存储从函数返回的数据)通常限制为几MB。您所在的区域可能需要足够的空间(如果您的迷宫创建哈密尔顿路径,则需要1000 * 1000个递归调用),您可能需要增加此限制。快速谷歌搜索将找到适合您的操作系统的方法。
答案 3 :(得分:0)
尝试递归:
void travel(){
if(treasureFound())
return;
else {
NextStep p;
chooseNextStep(&p);
travel();
moveBackwards(&p);
return;
}
}
您也可以存储您的路径,但不必存储所有坐标,每次移动1 char
足以描述您的移动,例如'N' 'S' 'E' 'W'
我的示例中的NextStep
也可以是char
同样在我的示例中,如果您希望将数据存储在堆上而不是堆栈中,请使用指针!