Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 解决难题(最佳解决方案)_C++_Algorithm_A Star_Heuristics - Fatal编程技术网

C++ 解决难题(最佳解决方案)

C++ 解决难题(最佳解决方案),c++,algorithm,a-star,heuristics,C++,Algorithm,A Star,Heuristics,我有一个3x3的数字拼图,如下所示: 3 | 5 | 2 7 | 8 | 9 1 | 6 | 4 作为解决方案: 1 | 2 | 3 4 | 5 | 6 7 | 8 | 9 规则是,在得到解决方案之前,我只能移动附近的“碎片” 我的想法是计算偏移量,然后将其运行到一个“奇特”的算法中,以获得一个有效的解决方案。但是,我只能考虑使用bruteforce并检查程序执行的步骤数量,以找到最有效的步骤 我的意思是: (2, 0) | (0, 1) | (-1, 0) (0, 1) | (0,

我有一个3x3的数字拼图,如下所示:

3 | 5 | 2
7 | 8 | 9
1 | 6 | 4
作为解决方案:

1 | 2 | 3
4 | 5 | 6
7 | 8 | 9
规则是,在得到解决方案之前,我只能移动附近的“碎片”

我的想法是计算偏移量,然后将其运行到一个“奇特”的算法中,以获得一个有效的解决方案。但是,我只能考虑使用bruteforce并检查程序执行的步骤数量,以找到最有效的步骤

我的意思是:

(2,  0) | (0,  1) | (-1,  0)
(0,  1) | (0,  1) | ( 0,  1)
(0, -2) | (1, -1) | (-2, -1)
这是笛卡尔平面中x和y的偏移量。我得到了以下计算偏移量的结果,但没有考虑“花式算法”


是否有一种有效的方法来求解不使用BruttFror的最小解?

< P>可以考虑网格作为节点(图的一部分)。< /P> 让我们编写网格

abc
def
ghi
作为单行
abcdefghi

您从node
352789164
开始,希望到达node
123456789

节点的邻居是通过应用交换可以到达的所有节点。 e、 g
123456789
对邻居

[
  213456789, 132456789,
  123546789, 123465789,
  123456879, 123456798,
  423156789, 153426789,
  126453789, 123756489,
  123486759, 123459786
]
然后,您可以通过提供以下内容应用*:

  • d(nodeA,nodeB)=权重(nodeA,nodeB)=1
    (所有掉期成本为1)
  • h(节点)
    =获得解决方案所需的最小交换次数

有最小<代码> h <代码>,考虑对错置的数字进行计数。

  • 如果有偶数个错位数字,则至少需要“一半”交换
  • 如果你有奇数个错放的数字,那么一半+1(例如目标123的312需要2次交换)
下面是我从中复制粘贴代码的js示例

函数h(节点){
常数s=''+节点
设错位=0
对于(设i=0;i{
常数arr=[[1,2]、[2,3]、[4,5]、[5,6]、[7,8]、[8,9]、[1,4]、[2,5]、[3,6]、[4,7]、[5,8]、[6,9]]
函数makePermFunc([a,b]){
a--
b--
返回函数(节点){
常量s=(''+节点)
常数da=parseInt(s[a])
常量db=parseInt(s[b])
常数powa=9-a-1
恒功率=9-b-1
节点-=da*10**powa
节点-=db*10**powb
节点+=da*10**powb
节点+=db*10**powa
返回节点
}
}
常量funcs=arr.map(makePermFunc)
返回节点=>funcs.map(f=>f(节点))
})();
//https://en.wikipedia.org/wiki/A*_搜索算法
函数路径(cameFrom,当前){
const total_path=[当前]
while(cameFrom.has(当前)){
当前=cameFrom.get(当前)
取消移位的总路径(当前)
}
返回总路径
}
//A*查找从起点到目标的路径。
//h是启发式函数。h(n)估计从节点n达到目标的成本。
功能A_星(开始、目标、h){
//可能需要(重新)扩展的已发现节点集。
//最初,只有开始节点是已知的。
const openSet=新集合([开始])
//对于节点n,cameFrom[n]是当前已知的从start到n的最便宜路径上紧靠其前面的节点。
const cameFrom=新映射()
//对于节点n,gScore[n]是目前已知的从start到n的最便宜路径的成本。
const gScore=新映射()
gScore.set(开始,0)
//对于节点n,fScore[n]:=gScore[n]+h(n)。
const fScore=新映射()
fScore.set(启动,h(启动))
while(openSet.size){
//当前:=openSet中具有最低fScore[]值的节点
让电流
设bestScore=Number.MAX\u SAFE\u整数
for(openSet的let节点){
const score=fScore.get(节点)
如果(分数<最佳分数){
最佳分数
当前=节点
}
}
如果(当前==目标){
返回U路径(cameFrom,当前)
}
openSet.delete(当前)
交换(当前).forEach(邻居=>{
//d(当前,邻居)是从当前到邻居的边的权重
//暂定_gScore是通过电流从起点到相邻点的距离
const暂定_gScore=gScore.get(当前)+d(当前,邻居)
如果(!gScore.has(neighbor)|暂定_gScore(''+x).split(/(…)/).filter(x=>x).join('\n')).join('\n----\n'))

console.log('a more basic one:',a_Star(123654987123456789,h))
碎片是如何移动的?你交换它们吗?哎呀。对但仅在X轴或Y轴上。不要斜移,我可能有个主意。我会做一些事情,然后发布一个解决方案,看看你是否喜欢。你需要设计一个好的启发式方法,你可以与*或*相结合。查看模式数据库、线性冲突和曼哈顿距离启发法。我的想法是使用数组上的地址交换将值移动到正确的位置,并根据它们的新位置重新计算相对位置。这将使用一个单独的
int[]values=int[3][3]{}数组以跟踪实际单元格值。我花了一个小时来研究它,似乎它可能会奏效。其他有更多时间的人可能会让它工作。