传统算法总结
经典的传统算法可以分为两类:
①仅评估完整解的算法
②需要部分构造解的算法
1 枚举法
①求解SAT
思路:
产生所有长度为n的二进制串,从(0……000)到(1……111)共有2n个。枚举时将每个二进制串对应一个整数,每次给该整数加1,对每次产生新的二进制串对其进行评估:如果该串满足符合布尔表达式,其值为1,否则为0。
改进:
可以采用回溯的方法减少实际要搜索的串:将解空间根据变量x1的取值分成两个不相交的子空间。然后根据x2的取值将每个空间再分成两个不相交的子空间……,依此类推,直到第n个变量。这样将解空间组织成了树状结构,即可以使用深度优先的搜索算法。
推广:
F 求解SAT问题实质上是要生成n个二进制数字组成的所有2n个字符串。即生成所有的n元组(a1,a2,……an)。
F 该问题可以等价于求给定集合{x1,x2,……xn}的所有子集问题。因为可以假设二进制字符串中第j位为1,表示xj位于子集中。
F 该问题还可以推广到其他种类的n元组。例如每个aj是十进制数字。每个aj还可以定义不同的上限mj。
算法:
F 可以简单地通过控制逐位加一来实现。
F 当n比较小时,更可以简单地通过n重循环来实现。
②求解TSP
思路:
一是TSP问题可能不是全互联的,所以有些排列是非法的。
二是如何产生n个数的所有可能排列。
方法一:
生成对应于k的一个排列。
方法二:
递归法生成全排列。
方法三:
将一个排列转换成另一个排列;
并且不允许出现重复的排列;
直到生成所有的排列。
③求解NLP
可以通过采取适当的“粒度”,使得问题可以采用枚举法求解。
例如求f(x1,x2)的最大值(其中x1 Î[-1,3],x2Î[0,12]),
可以将x1的取值范围分为400个区间,将x2的取值范围分为600个区间,这样就可以对这样400´600=240000个单元进行枚举算法处理了。
2 局部搜索法
①求解SAT
对于某些类型的SAT问题,局部搜索算法的结果十分有效。所谓局部搜索,就是根据当前解连续反位若干个变量的值(由假变为真或者相反)。
procedure GSAT
begin
for (i=1; MAX-TRIES; i++)
t=随机产生一组真值指派;
for (j=1; MAX-FLIPS; j++)
if 满足公式