如何在Python中实现TSP的动态规划算法?
我想用Python中的动态规划算法解决TSP问题。问题是:如何在Python中实现TSP的动态规划算法?,python,algorithm,dynamic-programming,traveling-salesman,Python,Algorithm,Dynamic Programming,Traveling Salesman,我想用Python中的动态规划算法解决TSP问题。问题是: 输入:以点列表表示的城市。例如,[(1,2),(0.3,4.5),(9,3)…]。城市之间的距离定义为欧几里得距离 输出:此实例中旅行推销员旅行的最低成本,向下舍入到最接近的整数 伪代码是: Let A = 2-D array, indexed by subsets of {1, 2, ,3, ..., n} that contains 1 and destinations j belongs to {1, 2, 3,...n} 1
- 输入:以点列表表示的城市。例如,[(1,2),(0.3,4.5),(9,3)…]。城市之间的距离定义为欧几里得距离
- 输出:此实例中旅行推销员旅行的最低成本,向下舍入到最接近的整数
Let A = 2-D array, indexed by subsets of {1, 2, ,3, ..., n} that contains 1 and destinations j belongs to {1, 2, 3,...n}
1. Base case:
2. if S = {0}, then A[S, 1] = 0;
3. else, A[S, 1] = Infinity.
4.for m = 2, 3, ..., n: // m = subproblem size
5. for each subset of {1, 2,...,n} of size m that contains 1:
6. for each j belongs to S and j != 1:
7. A[S, j] = the least value of A[S-{j},k]+the distance of k and j for every k belongs to S that doesn't equal to j
8.Return the least value of A[{1,2..n},j]+the distance between j and 1 for every j = 2, 3,...n.
我的困惑是:
如何使用子集对列表进行索引,即如何在伪代码中高效地实现第5行。您可以将集合编码为整数:整数的第i位将表示第i个城市的状态(即,我们是否将其包含在子集中)。
例如,3510=1000112将表示城市{1、2、6}。这里我从最右边的一位开始计数,它代表城市1 为了使用子集的这种表示对列表进行索引,您应该创建长度2n的二维数组:
# Assuming n is given.
A = [[0 for i in xrange(n)] for j in xrange(2 ** n)]
这是因为使用n位整数可以表示{1,2,…,n}的每一个子集(记住,每一位只对应一个城市)
此表示为您提供了许多很好的可能性:
# Check whether some city (1-indexed) is inside subset.
if (1 << (i - 1)) & x:
print 'city %d is inside subset!' % i
# In particular, checking for city #1 is super-easy:
if x & 1:
print 'city 1 is inside subset!'
# Iterate over subsets with increasing cardinality:
subsets = range(1, 2 ** n)
for subset in sorted(subsets, key=lambda x: bin(x).count('1')):
print subset,
# For n=4 prints "1 2 4 8 3 5 6 9 10 12 7 11 13 14 15"
# Obtain a subset y, which is the same as x,
# except city #j (1-indexed) is removed:
y = x ^ (1 << (j - 1)) # Note that city #j must be inside x.
#检查某个城市(1索引)是否在子集内。
如果(1)重读你的问题。你应该做work@Alik但是如何使用集合来索引列表呢?S
是集合吗?实现a[S,j]有困难吗
Python索引?@Alik是的,我必须使用一个集合S来索引Python中的列表a。我不知道如何索引。现在我有了一个主意。使用一个n位整数来表示n个城市。如果第二位是1,那么第二个城市就在子集中。然后使用这个n位整数来索引列表。但是我不知道如何在用另一个n位整数表示的集合中的teger。例如,1001表示第一个和第四个城市在这个子集中,因此我可以使用9来索引列表。但是如何从0000中得到1001100 1010100011,作为两个城市的所有子集?你的想法实际上很好。你可以这样做
# INFINITY and n are defined somewhere above.
A = [[INFINITY for i in xrange(n)] for j in xrange(2 ** n)]
# Base case (I guess it should read "if S = {1}, then A[S, 1] = 0",
because otherwise S = {0} is not a valid index to A, according to line #1)
A[1][1] = 0
# Iterate over all subsets:
subsets = range(1, 2 ** n)
for subset in sorted(subsets, key=lambda x: bin(x).count('1')):
if not subset & 1:
# City #1 is not presented.
continue
for j in xrange(2, n + 1):
if not (1 << (j - 1)) & subset:
# City #j is not presented.
continue
for k in xrange(1, n + 1):
if k == j or not (1 << (k - 1)) & subset:
continue
A[subset][j] = min(A[subset][j], A[subset ^ (1 << (j - 1))][k] + get_dist(j, k))