1 2 3 4 5 6 7 8
1 3 5 2 6 8 4 7
1 4 2 7 5 8 3 6
现在我为简单的游戏(跳棋,n-queens,tic-tac-toe)构建了自己的回溯算法,但是我使用的这些算法都是用空白画布开始的,不需要这种类型的实现。我要求的是一些指导和见解,或链接到这个问题的更多信息,因为所有给出的是关于一页半,主要是谈论组合1 2 3 4如何实际上与1相同4 3 2在这个特殊的问题。这需要使用回溯方法来完成,而这正是让我感到困惑的原因。如果我们能够自由地找到解决方案,我可以很容易地做到。任何帮助表示赞赏。
谢谢!
答案 0 :(得分:0)
我认为你必须添加有关谁已经回到已经回溯算法状态的人的信息:
1
。您将2
放在他旁边,并将此“配对”记录在当前的部分解决方案中。 (字面上只是一对无序的总统ID。实现一对无序数字的简单方法是让该类的构造函数在该对的第一个元素中存储较小的ID,并在第二个元素中存储较大的ID元素。)所以你有一个部分解决方案1 2 …
,配对1-2
。1 2 3 4 5 6 7 8
,则会保存配对1-2
,2-3
,3-4
,4-5
,5-6
,6-7
,7-8
,1-8
。现在,在进行搜索时,您有一个部分解决方案x y z …
- 到目前为止坐的最后一位总统是z
,此部分解决方案中的配对是x-y
和y-z
。要担任下一任总统,你需要看看每位总统:
z
配对。 如果没有这样的总统,您将丢弃部分解决方案并回溯。
那就是说,我正在这里工作,所以如果我错过任何边缘情况,你应该通过使用简单的暴力实施并比较结果来实际进行双重检查。
答案 1 :(得分:0)
非常粗略的伪代码将如下所示:
global flag // I know it is a bad practice but can't think of a better idea at this point
back (PresidentList, chairNumber, computedList)
if (PresidentList.size() == 0)
if (computedList doesn't violate any global distribution)
add computedList to globalList
add distirbution of computedList to global distirbution
set flag;
else return;
else if (flag is set and chairNumber > 2) return;
else if (flag is set and chairNumber = 2) un set flag; return;
else if (chairNumber == maxChairs-1)
// at this point there should be only one president in PresidentList
if (PresidentList.back() can sit with computedList.back() and computedList.front())
remove president from PreseidentList, add president to computedList
back(PresidenList, chairNumber+1,computedList)
else return;
else
for every president in PresidentList
if (president can sit with computedList.back())
remove president from PreseidentList, add president to computedList
back(PresidentList,chairNumber+1,computedList);
你总是根据全球分布变量检查总统是否可以坐在其他总统附近。
在main函数中,只运行一个PresidentList
的循环,该循环将以{1}}开始,该总统作为第一个。
标志的概念如下:当您向全局列表添加分发和列表时,back
已经运行了许多分支,这些分支与您刚刚添加的列表具有相同的前缀,因此已经不好了。要关闭所有这些列表,强制后退停止分支并返回到可以在列表中设置新的第二个元素进行计算的点,即如果函数的最后一个back
分支则返回循环。 / p>