回溯算法——收费公路重建问题python实现
来源:互联网 发布:阮佳 黄光剑 网络战 编辑:程序博客网 时间:2024/05/01 08:02
收费公路重建问题
数据结构与算法分析(C语言描述)原书第二版,P304 回溯算法:
书中给出了详细分析,并给出了伪代码,根据书上的伪代码,写了个python实现的。
简单一点说这个问题就是根据给定的条件求N个未知数,N个未知数分别代表公路上的N个点(也可以当作坐标轴上的N个点),
这里用[x1, x2, x3,...,xN]表示,而给定的条件为任意两个点间距离的集合及{|xi - xj|, i,j=1,2,3,...,N 且 i!=j},根据统计学知识可知,这
个集合的元素有N*(N-1)/2个(从N个元素中任取两个的方法数)。
如果给定一个解[x1, x2, x3,...,xN],那么将每个元素加上同一个常量C那么又能得到一组满足条件的解,所以这里直接将x1=0,即只
求x1=0时的一组解;
x1=0之后,这里对于xN就应该等于集合{|xi - xj|, i,j=1,2,3,...,N 且 i!=j}中的最大值,还拿书上的例子:
集合D = {1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6, 7, 8, 10} 共15个元素,可得出共有6个点[x1, x2, x3, x4, x5, x6],
1. 确定了x1 = 0, x6 = 10,从D中删除10得到剩下的集合 {1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6, 7, 8},其中最大的
元素为8,那么这里将x5 = 8,或者将x2 = 2,这两种情况相互对称,要么都有解,要么都无解,这里设置x5 = 8; 并将8从D中删除
2. 确定了 x1 = 0, x5 = 8, x6 = 10, 剩下的集合D为{1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6, 7},最大元素为7
到此要分两种情况了,x4 = 7 或者 x2 = x6 - 7=3:
首先假设x4 = 7 ,接下来验证假设对不对:
如果假设正确,那么x4与前面几步中确定的x1, x5和x6之间的距离,肯定都在剩下的集合D中,
将这些距离删除掉剩下集合{2, 2, 3, 3, 4, 5, 5, 5, 6}:
如果前面假设不正确,说明x4 = 7不能导出解,所以需要回溯回去,考虑x2 = x6-7=3的情况;接着在分两种情况:x3 = 6 或 x2 = 4,同样是假定一种情况正确然后与前面确定的或者假定正确的x求
距离如果正确则从集合中删除,直到集合被删空(即找到解了)
代码:
# -*- coding: cp936 -*-import sysclass turnpike_problem: def __init__(self, n, D): self.x = [0]*(n+1)#从x[1:]表示解 self.n = n self.D = D[:] self.D.sort() def place(self, n, D, left, right): found_flag = False if len(D) == 0: #print '^_^: ',self.x[1:] return True Dmax = max(D) tmpD = D[:] set_right = True for i in range(1, left)+range(right+1, n+1): if abs(self.x[i]-Dmax) not in tmpD: set_right = False break tmpD.remove(abs(self.x[i]-Dmax)) if set_right == True: self.x[right] = Dmax for i in range(1, left)+range(right+1, n+1): D.remove(abs(self.x[i]-Dmax)) found_flag = self.place(n, D, left, right-1) if found_flag == False: for i in range(1, left)+range(right+1, n+1): D.append(abs(self.x[i]-Dmax)) #D.sort() if found_flag == False: tmpD = D[:] set_left = True for i in range(1, left)+range(right+1, n+1): if abs(self.x[n]-Dmax-self.x[i]) not in tmpD: set_left = False break tmpD.remove(abs(self.x[n]-Dmax-self.x[i])) if set_left == True: self.x[left] = self.x[n]-Dmax for i in range(1, left)+range(right+1, n+1): D.remove(abs(self.x[n]-Dmax-self.x[i])) found_flag = self.place(n, D, left+1, right) if found_flag == False: for i in range(1, left)+range(right+1, n+1): D.append(abs(self.x[n]-Dmax-self.x[i])) #D.sort() return found_flag def turnpike(self, n, D): self.x[n] = max(D) D.remove(self.x[n]) self.x[n-1] = max(D) D.remove(self.x[n-1]) if self.x[n]-self.x[n-1] in D: D.remove(self.x[n]-self.x[n-1]) return self.place(n, D, 2, n-2) else: return False def show(self): if self.turnpike(self.n, self.D): print 'found:', self.x[1:] else: print 'not'def main(): sys.setrecursionlimit(1000) #D = [1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 6, 7, 8, 10] D = [1, 2, 2, 3, 4, 5] t = turnpike_problem(4, D) t.show()if __name__ == '__main__': main()
- 回溯算法——收费公路重建问题python实现
- 收费公路重建问题——回溯算法实现
- 回溯算法—公路收费点重建问题
- 回溯算法--收费公路重建问题
- 《数据结构与算法分析》回溯算法——收费公路重建问题详解
- 数据结构与算法分析 ——回溯算法之收费公路重建问题
- 收费公路重建问题,回溯、递归
- 收费公路重建问题
- 收费公路重建问题C语言
- 《DSAA》 10.5.1 收费公路重建问题
- 公路重建问题
- 收费公路重建问题(可发现所有同度点集)C语言
- n皇后问题——回溯算法
- N皇后问题——回溯算法
- NPC问题——回溯算法、聚类分析
- NPC问题——回溯算法、聚类分析
- 回溯算法——八皇后问题
- 装载问题——搜索回溯算法
- Hession矩阵
- iOS 判断屏幕尺寸、分辨率
- temami防辐射服帮助宝宝摆脱环境“污染”
- 核雕图案的寓意(上)
- oracle 闪回数据归档 分区表
- 回溯算法——收费公路重建问题python实现
- Android中文API(126) —— Message
- Kafka与FlumeNG整合
- mac下svn常用基本操作
- 矩形的个数
- Android之Service
- 防辐射服能用多久
- 可编辑的select框实验
- UVa 10167 - Birthday Cake