有一块板,其中有m * m个盒子,每个盒子都分配一个非零整数,除了一个标记为0的盒子,并被视为空置。只有空盒子的垂直和水平邻居可以向它移动而离开它们为了解决这个难题,我们必须按照价值递增的顺序排列盒子,最后(盒子的右下角)有一个空盒子(标有零的盒子)。但是和所有其他工程师一样,我们非常懒惰,并希望以最少的步骤解决它。
那么我们应该遵循什么方法,除了回溯。
m是订单500 ..即500x500板。
答案 0 :(得分:0)
您只需对数组进行排序即可找到目标状态。假设您的目标状态为g
,那么解决这个难题的简单但效率低的算法将是:
void solve()
{
if(current_state == g)
return;
foreach(choice c in shifting_choices)
{
// shift neighbour
apply choice;
solve();
undo choice;
}
}
在上面的算法choices
基本上是移动zeroth
块包围的块。
要改进算法,您可以使用A *(最好的第一个)。为了找到最佳选择,您可以使用Manhattan Distance
。它基本上是在拼图中到达另一个块所需的步骤。请考虑以下事项:
6 2 1
5 0 3
4 7 8
在上述情况下,您可以移动2, 5, 3, 7
,但要找到最佳行动,请考虑目标状态:
8 7 6
5 4 3
2 1 0
当您将块移动到zeroth
块时,您正在更改两个块的位置。计算这两个区块的曼哈顿距离与其在目标状态内的位置之和。最优先选择的最佳选择是:
Moving 2: 2 + 3 = 5
Moving 3: 1 + 1 = 2
Moving 7: 1 + 1 = 2
Moving 5: 1 + 2 = 3
你可以通过检查他们之前的位置来打破3到7之间的关系,3在正确的位置,因此7是当地最佳选择。