枚举算法为解TSP/VRP问题的方法之一,为精确算法。
枚举算法的特点是简单,但运算量大,问题的规模越大,执行的速度越慢。如果枚举范围太大(一般以两百万次为限),在时间上就难以承受。
在解决旅行商问题时,以顶点1为起点和终点,然后求{2…N}的一个全排列,使路程1→{2…N}的一个全排列→1上所有边的权(代价)之和最小。所有可能解由(2,3,4,…,N)的不同排列决定。
为便于进一步讨论,介绍一下解空间树结构。在解空间树中的每一个结点确定所求问题的一个问题状态(problem state)。由根结点到其它结点的所有路径则确定了这个问题的状态空间(state space)。解状态(solution states)表示一些问题状态S,对于这些问题状态,由根到S的那条路径确定了这解空间中的一个元组。答案状态(answer states)表示一些解状态S,对于这些解状态而言,由根到S的这条路径确定了这问题的一个解(即满足隐式约束条件)。解空间的树结构称为状态空间树(state pace tree)。
对于旅行商问题,一旦给出一种状态空间树,那么就可以先系统地生成问题状态,接着确定这些问题状态中的哪些状态是解状态,最后确定哪些解状态是答案状态,从而将问题解出。
如果已生成一个结点而它的所有子结点还没有全部生成,则这个结点叫做活结点。当前正在生成其子结点的活结点叫E-结点。不再进一步扩展或者其子结点已全部生成的生成结点就是死结点。在生成问题状态的两种方法中,都要用一张活结点表。为了生成问题状态,采用两种不同的方法:
(1) 在第一种方法中,当前的E-结点R一旦生成一个新的子节点C,这个子结点就变成一个新的E-结点,当完全检测了子树C之后,R结点就再次成为E-结点。这相当于问题状态的深度优先生成。
(2) 在第二种状态生成方法中,一个E-结点一直保持到死结点为止。
这两种方法中,将用限界函数去杀死还没有全部生成其子结点的那些活结点。如果旅行商问题要求找出全部解,则要生成所有的答案结点。使用限界函数的深度优先结点生成方法称为回溯法。E-结点一直保持到死为止的状态生成方法称为分支限界法。