传统的n后问题使用的是回溯法解决的,但是一旦问题的规模过大,那么计算时间复杂度是不能够接受的,
这里有一种启发式局部搜索的n皇后问题,由sosic和顾均提出,可以计算皇后数量超过1000,当皇后数量超过1000的时候,计算时间反而会下降,每一次运行的时间为O(n^2),算法伪代码为
输入:皇后数量N
输出:解t(i)
Begin
Do
(1) 产生一个随机解t(i)(i=1,2,3,…n)
(2) For all I,j; where 皇后t(i)或t(j)用冲突 do
(2.1) if 交换t(i)与t(j)能减少冲突
(2.2) then 交换 t(i)与t(j)
Endif
Endfor
Until 解无冲突
End
疑问:这个方法的第(2)步结束条件是什么伪代码中并没有说明,我假设是遍历完了所有的I,和j
对于每个皇后,由于采用的数据结构的原因,不存在横线上和纵列的冲突的可能,只有可能是斜线上的冲突,并且在检查交换t(i)与t(j)能否减少冲突的时候,只涉及8条斜线,因此检查的时间为常数时间,每次运行for的时间为O(n^2),
当输入数据n过大的时候,这种方法能够在较短的时间内得到很多的可行解
这种方法适用于一个题目,让你求其有效解,你可以生成一个初始解,然后对解里面的每个元素进行在指定领域里面的一种操作,如果操作能降低错误程度,那么就执行,否则查看下个元素,
如果查看完所有的元素后还是有错误,从新随机生成初始元素,然后再次查看所有元素,进行调整
这里采用随机重启的方法,因为n皇后问题的解很多,但是对于某些可行解比较少的例子,比如大部分的TSP问题,随机重启的效率并不高
但是局部搜索算法很可能过早的陷入局部最优解陷阱,解决的方法是重新随机生成初始解,然后继续局部搜索,或者是对之前的最优解进行扰动之后,再次随机搜索,看是否能得到更好的解,
比如解决TSP问题著名的LK算法,新的初始解采用对已有最好解进行“双桥”扰动的方法,作为新的初始解