0
点赞
收藏
分享

微信扫一扫

@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起

@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起

@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起_旅行商问题

诗三百,一言以蔽之,曰:思无邪


问题描述一:什么是回溯法?

回溯法的解题步骤:

步骤一:探明问题的解空间。 

例如,对集合{1,2,3},求解其全排列。 

分析:

从集合中选定1,下一步有{1,2}和{1,3}两种排列方式 

从集合中选定2,下一步有{2,1}和{2,3}两种排列方式

从集合中选定3,下一步有{3,1}和{3,2}两种排列方式

如下图所示:

@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起_TSP问题_02


从集合中选定{1,2},下一步有{1,2,3}一种排列方式 

从集合中选定{1,3},下一步有{1,3,2}一种排列方式 

从集合中选定{2,1},下一步有{2,1,3}一种排列方式 

从集合中选定{2,3},下一步有{2,3,1}一种排列方式 

从集合中选定{3,1},下一步有{3,1,2}一种排列方式 

从集合中选定{3,2},下一步有{3,2,1}一种排列方式 


如下图所示:


@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起_路径规划_03

到此,问题的解空间大小为{{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}}。


步骤二:根据问题的解空间大小,设计算法,迭代或回溯求解


例如:

问题描述二:什么是全排列?

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。


解决方案一:枚举法求解全排列


算法一:迭代求解

算法伪代码:

定义解空间S1={1,2,3}
for a in 解空间:#定义循环1
从解空间中取出一元素a
for b in 解空间:#定义循环2
从解空间中取出一元素b
for c in 解空间:#定义循环3
从解空间中取出一元素c
定义新集合S2 = {}
如果a不等于b,b不等于c,a不等于c,则新集合S2 = {a,b,c}


使用Python实现:

def iterate_S(S,out=[]):
"""
作者:文方俊
日期:2022-02-06
功能:迭代法求解全排列
"""
for a in S1:
#从解空间中取出一元素a
for b in S1:
#从解空间中取出一元素b
for c in S1:
#从解空间中取出一元素c
S2=()
#如果a不等于b,b不等于c,a不等于c
if (a==b)+(b==c)+(a==c)==0:
#新集合S2 = {a,b,c}
S2 = (a,b,c)
print (S2)
out.append(S2)
return out

输出结果,如下:

(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
(1, 2, 3)的全排列:[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
>>>

思考:

迭代算法可采用以下方式一再优化,


集合{a,b,c}的长度若与集合S1的长度相等,则输出集合{a,b,c}为解空间中的一个正解。 


优化后的版本,

def iterate_S_Optimize(S1,out=[]):
"""
作者:文方俊
日期:2022-02-06
功能:迭代法求解全排列
"""
for a in S1:
#从解空间中取出一元素a
for b in S1:
#从解空间中取出一元素b
for c in S1:
#从解空间中取出一元素c
S2=(a,b,c) #新集合S2 = {a,b,c}
#如果a不等于b,b不等于c,a不等于c
if len(set(S2)) == len(set(S1)):
print (S2)
out.append(S2)
return out


输出结果为,

(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
(1, 2, 3)的全排列:[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]


解决方案二:回溯法求解全排列


初始集合S1为{1,2,3} 

定义可行解为S2为空,S2={}

遍历初始集合S1,

第1次遍历,得到S2={1} 

第2次遍历,得到S2={2}

第3次遍历,得到S2={3}

@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起_背包问题_04


初始集合S1为{1,2,3} 

若可行解S2为{1}, 

回溯,第1次遍历,得到S2={1,1} ;不满足集合条件,删除;

回溯,第2次遍历,得到S2={1,2}

回溯,第3次遍历,得到S2={1,3} 


初始集合S1为{1,2,3} 

若可行解S2为{2}, 

回溯,第1次遍历,得到S2={2,1} 

回溯,第2次遍历,得到S2={2,2};不满足集合条件,删除;

回溯,第3次遍历,得到S2={2,3} 


初始集合S1为{1,2,3} 

若可行解S2为{3}, 

回溯,第1次遍历,得到S2={3,1} 

回溯,第2次遍历,得到S2={3,2}

回溯,第3次遍历,得到S2={3,3} ;不满足集合条件,删除;


@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起_回溯法_05

初始集合S1为{1,2,3} 

若可行解S2为{1,2}, 

回溯,第1次遍历,得到S2={1,2,1} ;不满足集合条件,删除;

回溯,第2次遍历,得到S2={1,2,2};不满足集合条件,删除;

回溯,第3次遍历,得到S2={1,2,3} ;满足集合条件;


初始集合S1为{1,2,3} 

若可行解S2为{1,3}, 

回溯,第1次遍历,得到S2={1,3,1} ;不满足集合条件,删除;

回溯,第2次遍历,得到S2={1,3,2};满足集合条件;

回溯,第3次遍历,得到S2={1,3,3} ;不满足集合条件,删除;


初始集合S1为{1,2,3} 

若可行解S2为{2,1}, 

回溯,第1次遍历,得到S2={2,1,1} ;不满足集合条件,删除;

回溯,第2次遍历,得到S2={2,1,2};不满足集合条件,删除;

回溯,第3次遍历,得到S2={2,1,3} ;满足集合条件;


初始集合S1为{1,2,3} 

若可行解S2为{2,3}, 

回溯,第1次遍历,得到S2={2,3,1} ;满足集合条件;

回溯,第2次遍历,得到S2={2,3,2};不满足集合条件,删除;

回溯,第3次遍历,得到S2={2,3,3} ;不满足集合条件,删除;


初始集合S1为{1,2,3} 

若可行解S2为{3,1}, 

回溯,第1次遍历,得到S2={3,1,1} ;不满足集合条件,删除;

回溯,第2次遍历,得到S2={3,1,2};满足集合条件;

回溯,第3次遍历,得到S2={3,1,3} ;不满足集合条件,删除;


初始集合S1为{1,2,3} 

若可行解S2为{3,2}, 

回溯,第1次遍历,得到S2={3,2,1} ;满足集合条件;

回溯,第2次遍历,得到S2={3,2,2};不满足集合条件,删除;

回溯,第3次遍历,得到S2={3,2,3} ;不满足集合条件,删除;



@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起_旅行商问题_06


算法伪代码:

"""
作者:文方俊
日期:2022-02-06
功能:回溯法求解全排列
"""
初始化解空间S1
定义可行解空间S
定义函数backtrack(S1,S):
if len(S1)==len(S):
return
#定义循环1
for a in 解空间S1:
#S中增加一个元素
S={a}
如果 a 不在S中,
#回溯求解
backtrack(S1,S+{a})


采用Python实现,

示例代码如下:

#回溯法求解全排列
def backtrack(S,result,out):
"""
作者:文方俊
日期:2022-02-06
功能:回溯法求解全排列
Email:wfj268@qq.com
"""
if len(result)==len(S):
out.append(result)
return
for elem in S:
if elem not in result:
backtrack(S,result+[elem],out)
return out


算法测试代码,如下:


S1= (1,2,3,4)
out = backtrack(S1, [],[])
print ("{}的全排列:".format(S1))
for o in out:
print (o)


算法输出,如下:

(1, 2, 3, 4)的全排列:
[1, 2, 3, 4]
[1, 2, 4, 3]
[1, 3, 2, 4]
[1, 3, 4, 2]
[1, 4, 2, 3]
[1, 4, 3, 2]
[2, 1, 3, 4]
[2, 1, 4, 3]
[2, 3, 1, 4]
[2, 3, 4, 1]
[2, 4, 1, 3]
[2, 4, 3, 1]
[3, 1, 2, 4]
[3, 1, 4, 2]
[3, 2, 1, 4]
[3, 2, 4, 1]
[3, 4, 1, 2]
[3, 4, 2, 1]
[4, 1, 2, 3]
[4, 1, 3, 2]
[4, 2, 1, 3]
[4, 2, 3, 1]
[4, 3, 1, 2]
[4, 3, 2, 1]
>>>


回溯法求解全排列优化一,

for循环部分代码可嵌套实现,示例代码如下,优化后的代码还剩下4行。


#回溯法求解全排列优化一
def backtrack_optimize_V1(S,result,out):
"""
作者:文方俊
日期:2022-02-06
功能:回溯法求解全排列
Email:wfj268@qq.com
"""
if len(result)==len(S):
out.append(result)
return
[backtrack(S,result+[elem],out) for elem in S if elem not in result]
return out

算法输出:

(1, 2, 3, 4)的全排列:
[1, 2, 3, 4]
[1, 2, 4, 3]
[1, 3, 2, 4]
[1, 3, 4, 2]
[1, 4, 2, 3]
[1, 4, 3, 2]
[2, 1, 3, 4]
[2, 1, 4, 3]
[2, 3, 1, 4]
[2, 3, 4, 1]
[2, 4, 1, 3]
[2, 4, 3, 1]
[3, 1, 2, 4]
[3, 1, 4, 2]
[3, 2, 1, 4]
[3, 2, 4, 1]
[3, 4, 1, 2]
[3, 4, 2, 1]
[4, 1, 2, 3]
[4, 1, 3, 2]
[4, 2, 1, 3]
[4, 2, 3, 1]
[4, 3, 1, 2]
[4, 3, 2, 1]
>>>


问题描述三:什么是0-1背包问题?

背包问题举例:


假定有6件物品A,B,C,D,E,F,其中A的重量为25,价值为8.8;B的重量为6.5,价值为25;C的重量为75,价值为0.65;D的重量为15,价值为17.5;E的重量为35,价值为7.5;F的重量为62,价值为0.91。背包限制重量为80,问,怎么挑选物品使得背包的总价值最大?

@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起_TSP问题_07


对于0-1背包问题,每一种物品选择记为1,不选择记为0; 

例如解空间的一个解可为{1,1,1,1,1,1},此时总重量为25+6.5+75+15+35+62 = 218.5,总价值为8.8+25+0.65+17.5+7.5+0.91=60.35999999999999

全部解如下:

背包选择[0, 0, 0, 0, 0, 0]的总重量为0,总价值为0
背包选择[0, 0, 0, 0, 0, 1]的总重量为62,总价值为0.91
背包选择[0, 0, 0, 0, 1, 0]的总重量为35,总价值为7.5
背包选择[0, 0, 0, 0, 1, 1]的总重量为97,总价值为8.41
背包选择[0, 0, 0, 1, 0, 0]的总重量为15,总价值为17.5
背包选择[0, 0, 0, 1, 0, 1]的总重量为77,总价值为18.41
背包选择[0, 0, 0, 1, 1, 0]的总重量为50,总价值为25.0
背包选择[0, 0, 0, 1, 1, 1]的总重量为112,总价值为25.91
背包选择[0, 0, 1, 0, 0, 0]的总重量为75,总价值为0.65
背包选择[0, 0, 1, 0, 0, 1]的总重量为137,总价值为1.56
背包选择[0, 0, 1, 0, 1, 0]的总重量为110,总价值为8.15
背包选择[0, 0, 1, 0, 1, 1]的总重量为172,总价值为9.06
背包选择[0, 0, 1, 1, 0, 0]的总重量为90,总价值为18.15
背包选择[0, 0, 1, 1, 0, 1]的总重量为152,总价值为19.06
背包选择[0, 0, 1, 1, 1, 0]的总重量为125,总价值为25.65
背包选择[0, 0, 1, 1, 1, 1]的总重量为187,总价值为26.56
背包选择[0, 1, 0, 0, 0, 0]的总重量为6.5,总价值为25
背包选择[0, 1, 0, 0, 0, 1]的总重量为68.5,总价值为25.91
背包选择[0, 1, 0, 0, 1, 0]的总重量为41.5,总价值为32.5
背包选择[0, 1, 0, 0, 1, 1]的总重量为103.5,总价值为33.41
背包选择[0, 1, 0, 1, 0, 0]的总重量为21.5,总价值为42.5
背包选择[0, 1, 0, 1, 0, 1]的总重量为83.5,总价值为43.41
背包选择[0, 1, 0, 1, 1, 0]的总重量为56.5,总价值为50.0
背包选择[0, 1, 0, 1, 1, 1]的总重量为118.5,总价值为50.91
背包选择[0, 1, 1, 0, 0, 0]的总重量为81.5,总价值为25.65
背包选择[0, 1, 1, 0, 0, 1]的总重量为143.5,总价值为26.56
背包选择[0, 1, 1, 0, 1, 0]的总重量为116.5,总价值为33.15
背包选择[0, 1, 1, 0, 1, 1]的总重量为178.5,总价值为34.059999999999995
背包选择[0, 1, 1, 1, 0, 0]的总重量为96.5,总价值为43.15
背包选择[0, 1, 1, 1, 0, 1]的总重量为158.5,总价值为44.059999999999995
背包选择[0, 1, 1, 1, 1, 0]的总重量为131.5,总价值为50.65
背包选择[0, 1, 1, 1, 1, 1]的总重量为193.5,总价值为51.559999999999995
背包选择[1, 0, 0, 0, 0, 0]的总重量为25,总价值为8.8
背包选择[1, 0, 0, 0, 0, 1]的总重量为87,总价值为9.71
背包选择[1, 0, 0, 0, 1, 0]的总重量为60,总价值为16.3
背包选择[1, 0, 0, 0, 1, 1]的总重量为122,总价值为17.21
背包选择[1, 0, 0, 1, 0, 0]的总重量为40,总价值为26.3
背包选择[1, 0, 0, 1, 0, 1]的总重量为102,总价值为27.21
背包选择[1, 0, 0, 1, 1, 0]的总重量为75,总价值为33.8
背包选择[1, 0, 0, 1, 1, 1]的总重量为137,总价值为34.709999999999994
背包选择[1, 0, 1, 0, 0, 0]的总重量为100,总价值为9.450000000000001
背包选择[1, 0, 1, 0, 0, 1]的总重量为162,总价值为10.360000000000001
背包选择[1, 0, 1, 0, 1, 0]的总重量为135,总价值为16.950000000000003
背包选择[1, 0, 1, 0, 1, 1]的总重量为197,总价值为17.860000000000003
背包选择[1, 0, 1, 1, 0, 0]的总重量为115,总价值为26.950000000000003
背包选择[1, 0, 1, 1, 0, 1]的总重量为177,总价值为27.860000000000003
背包选择[1, 0, 1, 1, 1, 0]的总重量为150,总价值为34.45
背包选择[1, 0, 1, 1, 1, 1]的总重量为212,总价值为35.36
背包选择[1, 1, 0, 0, 0, 0]的总重量为31.5,总价值为33.8
背包选择[1, 1, 0, 0, 0, 1]的总重量为93.5,总价值为34.709999999999994
背包选择[1, 1, 0, 0, 1, 0]的总重量为66.5,总价值为41.3
背包选择[1, 1, 0, 0, 1, 1]的总重量为128.5,总价值为42.209999999999994
背包选择[1, 1, 0, 1, 0, 0]的总重量为46.5,总价值为51.3
背包选择[1, 1, 0, 1, 0, 1]的总重量为108.5,总价值为52.209999999999994
背包选择[1, 1, 0, 1, 1, 0]的总重量为81.5,总价值为58.8
背包选择[1, 1, 0, 1, 1, 1]的总重量为143.5,总价值为59.709999999999994
背包选择[1, 1, 1, 0, 0, 0]的总重量为106.5,总价值为34.449999999999996
背包选择[1, 1, 1, 0, 0, 1]的总重量为168.5,总价值为35.35999999999999
背包选择[1, 1, 1, 0, 1, 0]的总重量为141.5,总价值为41.949999999999996
背包选择[1, 1, 1, 0, 1, 1]的总重量为203.5,总价值为42.85999999999999
背包选择[1, 1, 1, 1, 0, 0]的总重量为121.5,总价值为51.949999999999996
背包选择[1, 1, 1, 1, 0, 1]的总重量为183.5,总价值为52.85999999999999
背包选择[1, 1, 1, 1, 1, 0]的总重量为156.5,总价值为59.449999999999996
背包选择[1, 1, 1, 1, 1, 1]的总重量为218.5,总价值为60.35999999999999
>>>


解决方案一:回溯法求解0-1背包问题

对有6件物品的背包,每件物品有选择或者不选择放进背包,形状如一棵决策树。

如下图所示为2件物品的所有背包选择,包括{11,10,01,00}。

@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起_回溯法_08

对6件物品的0-1背包问题的所有解,形如:

[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 1, 1]
[0, 0, 0, 1, 0, 0]
[0, 0, 0, 1, 0, 1]
[0, 0, 0, 1, 1, 0]
[0, 0, 0, 1, 1, 1]
[0, 0, 1, 0, 0, 0]
[0, 0, 1, 0, 0, 1]
[0, 0, 1, 0, 1, 0]
[0, 0, 1, 0, 1, 1]
[0, 0, 1, 1, 0, 0]
[0, 0, 1, 1, 0, 1]
[0, 0, 1, 1, 1, 0]
[0, 0, 1, 1, 1, 1]
[0, 1, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 1]
[0, 1, 0, 0, 1, 0]
[0, 1, 0, 0, 1, 1]
[0, 1, 0, 1, 0, 0]
[0, 1, 0, 1, 0, 1]
[0, 1, 0, 1, 1, 0]
[0, 1, 0, 1, 1, 1]
[0, 1, 1, 0, 0, 0]
[0, 1, 1, 0, 0, 1]
[0, 1, 1, 0, 1, 0]
[0, 1, 1, 0, 1, 1]
[0, 1, 1, 1, 0, 0]
[0, 1, 1, 1, 0, 1]
[0, 1, 1, 1, 1, 0]
[0, 1, 1, 1, 1, 1]
[1, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 1]
[1, 0, 0, 0, 1, 0]
[1, 0, 0, 0, 1, 1]
[1, 0, 0, 1, 0, 0]
[1, 0, 0, 1, 0, 1]
[1, 0, 0, 1, 1, 0]
[1, 0, 0, 1, 1, 1]
[1, 0, 1, 0, 0, 0]
[1, 0, 1, 0, 0, 1]
[1, 0, 1, 0, 1, 0]
[1, 0, 1, 0, 1, 1]
[1, 0, 1, 1, 0, 0]
[1, 0, 1, 1, 0, 1]
[1, 0, 1, 1, 1, 0]
[1, 0, 1, 1, 1, 1]
[1, 1, 0, 0, 0, 0]
[1, 1, 0, 0, 0, 1]
[1, 1, 0, 0, 1, 0]
[1, 1, 0, 0, 1, 1]
[1, 1, 0, 1, 0, 0]
[1, 1, 0, 1, 0, 1]
[1, 1, 0, 1, 1, 0]
[1, 1, 0, 1, 1, 1]
[1, 1, 1, 0, 0, 0]
[1, 1, 1, 0, 0, 1]
[1, 1, 1, 0, 1, 0]
[1, 1, 1, 0, 1, 1]
[1, 1, 1, 1, 0, 0]
[1, 1, 1, 1, 0, 1]
[1, 1, 1, 1, 1, 0]
[1, 1, 1, 1, 1, 1]
>>>

求解此问题可采用回溯法。

算法实现伪代码:

#算法伪代码
#作者:文方俊
#日期:2022-02-07
#功能:回溯法求解背包选择
#Email:wfj268@qq.com

初始化背包;
对每一件物品的背包选择0或1;
背包选择物品记为1,保存为{1};背包不选择物品记为0,保存为{0};
回溯所有物品


算法Python实现,

def bag_of_choices(goods,choices,result,out):
"""
作者:文方俊
日期:2022-02-07
功能:回溯法求解背包选择
Email:wfj268@qq.com
"""
if len(result) == len(goods):
out.append(result)
return
for choice in choices:
bag_of_choices(goods,choices,result+[choice],out)
return out


算法测试代码:

"""
作者:文方俊
日期:2022-02-07
功能:回溯法求解背包选择
Email:wfj268@qq.com
"""
out = bag_of_choices_optimize_V1(goods_values,[0,1],[],[])
for o in out:
print (o)


算法执行结果:

[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 1, 1]
[0, 0, 0, 1, 0, 0]
[0, 0, 0, 1, 0, 1]
[0, 0, 0, 1, 1, 0]
[0, 0, 0, 1, 1, 1]
[0, 0, 1, 0, 0, 0]
[0, 0, 1, 0, 0, 1]
[0, 0, 1, 0, 1, 0]
[0, 0, 1, 0, 1, 1]
[0, 0, 1, 1, 0, 0]
[0, 0, 1, 1, 0, 1]
[0, 0, 1, 1, 1, 0]
[0, 0, 1, 1, 1, 1]
[0, 1, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 1]
[0, 1, 0, 0, 1, 0]
[0, 1, 0, 0, 1, 1]
[0, 1, 0, 1, 0, 0]
[0, 1, 0, 1, 0, 1]
[0, 1, 0, 1, 1, 0]
[0, 1, 0, 1, 1, 1]
[0, 1, 1, 0, 0, 0]
[0, 1, 1, 0, 0, 1]
[0, 1, 1, 0, 1, 0]
[0, 1, 1, 0, 1, 1]
[0, 1, 1, 1, 0, 0]
[0, 1, 1, 1, 0, 1]
[0, 1, 1, 1, 1, 0]
[0, 1, 1, 1, 1, 1]
[1, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 1]
[1, 0, 0, 0, 1, 0]
[1, 0, 0, 0, 1, 1]
[1, 0, 0, 1, 0, 0]
[1, 0, 0, 1, 0, 1]
[1, 0, 0, 1, 1, 0]
[1, 0, 0, 1, 1, 1]
[1, 0, 1, 0, 0, 0]
[1, 0, 1, 0, 0, 1]
[1, 0, 1, 0, 1, 0]
[1, 0, 1, 0, 1, 1]
[1, 0, 1, 1, 0, 0]
[1, 0, 1, 1, 0, 1]
[1, 0, 1, 1, 1, 0]
[1, 0, 1, 1, 1, 1]
[1, 1, 0, 0, 0, 0]
[1, 1, 0, 0, 0, 1]
[1, 1, 0, 0, 1, 0]
[1, 1, 0, 0, 1, 1]
[1, 1, 0, 1, 0, 0]
[1, 1, 0, 1, 0, 1]
[1, 1, 0, 1, 1, 0]
[1, 1, 0, 1, 1, 1]
[1, 1, 1, 0, 0, 0]
[1, 1, 1, 0, 0, 1]
[1, 1, 1, 0, 1, 0]
[1, 1, 1, 0, 1, 1]
[1, 1, 1, 1, 0, 0]
[1, 1, 1, 1, 0, 1]
[1, 1, 1, 1, 1, 0]
[1, 1, 1, 1, 1, 1]
>>>


优化后的背包选择算法:

def bag_of_choices_optimize_V1(goods,choices,result,out):
"""
作者:文方俊
日期:2022-02-07
功能:回溯法求解背包选择优化
Email:wfj268@qq.com
"""
if len(result) == len(goods):
out.append(result)
return
[bag_of_choices(goods,choices,result+[choice],out) for choice in choices]
return out


有了全部背包选择,结合背包限制重量,可确定背包问题的可行解空间。

设计判别函数,给出背包选择的可行性与否。

判别函数设计如下:

def judge(choice, goods_weights, MAX_WEIGHT):
"""
作者:文方俊
日期:2022-02-07
功能:背包选择判别函数
Email:wfj268@qq.com
"""
total = 0
for i in range(len(goods_weights)):
if choice[i]:
total += goods_weights[i]
if total > 0 and total <= MAX_WEIGHT:
return True
return False


背包选择价值计算:

def bag_of_values(choices, goods_weights, goods_values):
"""
作者:文方俊
日期:2022-02-07
功能:背包选择价值计算
Email:wfj268@qq.com
"""
for choice in choices:
total_value,total_weight = 0, 0
#可行背包解
if judge(choice, goods_weights, MAX_WEIGHT):
for i in range(len(goods_weights)):
if choice[i]:
total_value += goods_values[i]
total_weight += goods_weights[i]
print ("背包选择{}的总重量为{},总价值为{}".format(choice,total_weight, total_value))


测试代码:

#test
goods_weights = (25, 6.5, 75, 15, 35, 62)
goods_values = (8.8, 25, 0.65, 17.5, 7.5, 0.91)
MAX_WEIGHT = 80
choices = bag_of_choices_optimize_V1(goods_values,[0,1],[],[])
bag_of_values(choices, goods_weights, goods_values)


算法执行结果:

背包选择[0, 0, 0, 0, 0, 1]的总重量为62,总价值为0.91
背包选择[0, 0, 0, 0, 1, 0]的总重量为35,总价值为7.5
背包选择[0, 0, 0, 1, 0, 0]的总重量为15,总价值为17.5
背包选择[0, 0, 0, 1, 0, 1]的总重量为77,总价值为18.41
背包选择[0, 0, 0, 1, 1, 0]的总重量为50,总价值为25.0
背包选择[0, 0, 1, 0, 0, 0]的总重量为75,总价值为0.65
背包选择[0, 1, 0, 0, 0, 0]的总重量为6.5,总价值为25
背包选择[0, 1, 0, 0, 0, 1]的总重量为68.5,总价值为25.91
背包选择[0, 1, 0, 0, 1, 0]的总重量为41.5,总价值为32.5
背包选择[0, 1, 0, 1, 0, 0]的总重量为21.5,总价值为42.5
背包选择[0, 1, 0, 1, 1, 0]的总重量为56.5,总价值为50.0
背包选择[1, 0, 0, 0, 0, 0]的总重量为25,总价值为8.8
背包选择[1, 0, 0, 0, 1, 0]的总重量为60,总价值为16.3
背包选择[1, 0, 0, 1, 0, 0]的总重量为40,总价值为26.3
背包选择[1, 0, 0, 1, 1, 0]的总重量为75,总价值为33.8
背包选择[1, 1, 0, 0, 0, 0]的总重量为31.5,总价值为33.8
背包选择[1, 1, 0, 0, 1, 0]的总重量为66.5,总价值为41.3
背包选择[1, 1, 0, 1, 0, 0]的总重量为46.5,总价值为51.3
>>>



问题描述四:什么是TSP(旅行商问题)?

问题:

一辆货车满载从北京出发,途径上海、合肥、广州、成都4个城市卸货,要求每个城市只经过一次,最后返回北京。怎么走总里程最短?

这是一个典型的TSP(旅行商)问题。

收集数据如下:

#北京-上海:1244千米

#北京-合肥:1044千米

#北京-广州:2174千米

#北京-成都:1854千米

#成都-上海:2095千米

#成都-合肥:1615千米

#成都-广州:1954千米

#广州-上海:1529千米

#广州-合肥:1257千米

#合肥-上海:472千米



解决方案一:回溯法求解TSP(旅行商问题)

标记北京:0,上海:1,合肥:2,广州:3,成都:4

算法实现伪代码:

"""
作者:文方俊
日期:2022-02-07
功能:旅行商(TSP)问题最短路径规划实现伪代码
Email:wfj268@qq.com

"""
TSP问题算法实现伪代码:
步骤S0:标记出发地集合S;
步骤S1:回溯法求解集合S的全排列T;
步骤S2:遍历T中所有路径,计算距离,建立路径与距离对应的字典M;
步骤S3:对照字典M,找出最短距离对应的全部最短路径;
步骤S4:算法结束。


算法执行结果,如下:

北京 -> 上海 -> 合肥 -> 广州 -> 成都 -> 北京,总里程:6781千米
北京 -> 上海 -> 合肥 -> 成都 -> 广州 -> 北京,总里程:7459千米
北京 -> 上海 -> 广州 -> 合肥 -> 成都 -> 北京,总里程:7499千米
北京 -> 上海 -> 广州 -> 成都 -> 合肥 -> 北京,总里程:7386千米
北京 -> 上海 -> 成都 -> 合肥 -> 广州 -> 北京,总里程:8385千米
北京 -> 上海 -> 成都 -> 广州 -> 合肥 -> 北京,总里程:7594千米
北京 -> 合肥 -> 上海 -> 广州 -> 成都 -> 北京,总里程:6853千米
北京 -> 合肥 -> 上海 -> 成都 -> 广州 -> 北京,总里程:7739千米
北京 -> 合肥 -> 广州 -> 上海 -> 成都 -> 北京,总里程:7779千米
北京 -> 合肥 -> 广州 -> 成都 -> 上海 -> 北京,总里程:7594千米
北京 -> 合肥 -> 成都 -> 上海 -> 广州 -> 北京,总里程:8457千米
北京 -> 合肥 -> 成都 -> 广州 -> 上海 -> 北京,总里程:7386千米
北京 -> 广州 -> 上海 -> 合肥 -> 成都 -> 北京,总里程:7644千米
北京 -> 广州 -> 上海 -> 成都 -> 合肥 -> 北京,总里程:8457千米
北京 -> 广州 -> 合肥 -> 上海 -> 成都 -> 北京,总里程:7852千米
北京 -> 广州 -> 合肥 -> 成都 -> 上海 -> 北京,总里程:8385千米
北京 -> 广州 -> 成都 -> 上海 -> 合肥 -> 北京,总里程:7739千米
北京 -> 广州 -> 成都 -> 合肥 -> 上海 -> 北京,总里程:7459千米
北京 -> 成都 -> 上海 -> 合肥 -> 广州 -> 北京,总里程:7852千米
北京 -> 成都 -> 上海 -> 广州 -> 合肥 -> 北京,总里程:7779千米
北京 -> 成都 -> 合肥 -> 上海 -> 广州 -> 北京,总里程:7644千米
北京 -> 成都 -> 合肥 -> 广州 -> 上海 -> 北京,总里程:7499千米
北京 -> 成都 -> 广州 -> 上海 -> 合肥 -> 北京,总里程:6853千米
北京 -> 成都 -> 广州 -> 合肥 -> 上海 -> 北京,总里程:6781千米
最短运输路径:北京 -> 上海 -> 合肥 -> 广州 -> 成都 -> 北京,最短运输距离:6781千米
最短运输路径:北京 -> 成都 -> 广州 -> 合肥 -> 上海 -> 北京,最短运输距离:6781千米
>>>


采用Python编程语言实现,

步骤一,回溯法求解旅行商(TSP)问题路径规划


def routes_plan(ID_START_CITY, S1, DISTANCE_BETWEEN_CITIES):
"""
作者:文方俊
日期:2022-02-07
功能:旅行商(TSP)问题路径规划
Email:wfj268@qq.com

ID_START_CITY :number : 出发地
S1 :list : 途径城市
DISTANCE_BETWEEN_CITIES : array :城市之间的距离
"""
out = backtrack_optimize_V1(S1, [],[])
min_distance, best_route, route_distance_map = float('inf'), None, {}
for o in out:
route = cities[ID_START_CITY]+" -> "
total_distance, ind_front, ind_rear = 0, ID_START_CITY, None
for ind in o:
ind_rear = ind
total_distance += DISTANCE_BETWEEN_CITIES[ind_front][ind_rear]
ind_front = ind_rear
route += cities[ind] + " -> "
#返回出发点
route += cities[ID_START_CITY]
total_distance += DISTANCE_BETWEEN_CITIES[ind_rear][ID_START_CITY]
if min_distance > total_distance:
min_distance = total_distance
best_route = route
route_distance_map[route] = total_distance
print (route+",总里程:{}千米".format(total_distance))
return (min_distance, best_route, route_distance_map)


步骤二,旅行商(TSP)问题最短路径规划


def best_routes_plan(route_distance_map, min_distance):
"""
作者:文方俊
日期:2022-02-07
功能:旅行商(TSP)问题最短路径规划
Email:wfj268@qq.com

route_distance_map :dict : 路径与距离对照字典
min_distance :number : 最短距离

"""
best_routes = {}
for key in route_distance_map.keys():
if route_distance_map[key] == min_distance:
best_routes[key] = min_distance
return best_routes


步骤三,输出旅行商(TSP)问题最短路径规划

def print_all_best_routes(route_distance_map, min_distance):
"""
作者:文方俊
日期:2022-02-07
功能:输出旅行商(TSP)问题最短路径规划
Email:wfj268@qq.com

route_distance_map :dict : 路径与距离对照字典
min_distance :number : 最短距离

"""
best_routes = best_routes_plan(route_distance_map, min_distance)
for route in best_routes.keys():
print ("最短运输路径:{},最短运输距离:{}千米".format(route, best_routes[route]))


步骤4:设定不同出发地,自由选择最短路径规划

def make_routes_plan(ID_START_CITY, ID_CITIES):
"""
作者:文方俊
日期:2022-02-07
功能:设定不同出发地输出旅行商(TSP)问题最短路径规划
Email:wfj268@qq.com

ID_CITIES : number : 出发地
ID_CITIES : list : 途径
"""
#S1 = [0,1,2,3,4]
#ID_START_CITY = 0
S1 = ID_CITIES.copy()
S1.remove(ID_START_CITY)
(min_distance, best_route, route_distance_map) = routes_plan(ID_START_CITY, S1, DISTANCE_BETWEEN_CITIES)
print_all_best_routes(route_distance_map, min_distance)


算法测试代码:

"""
作者:文方俊
日期:2022-02-07
功能:旅行商(TSP)问题最短路径规划实现测试代码
Email:wfj268@qq.com

"""

#测试数据
cities = { 0 : "北京", 1 : "上海", 2 : "合肥", 3 : "广州", 4 : "成都" }
DISTANCE_BETWEEN_CITIES = (
(0,1244,1044,2174,1854),
(1244,0,472,1529,2095),
(1044,472,0,1257,1615),
(2174,1529,1257,0,1954),
(1854,2095,1615,1954,0)
)
ID_START_CITY = 0
ID_CITIES = [0,1,2,3,4]
make_routes_plan(ID_START_CITY, ID_CITIES)


算法执行结果:


北京 -> 上海 -> 合肥 -> 广州 -> 成都 -> 北京,总里程:6781千米
北京 -> 上海 -> 合肥 -> 成都 -> 广州 -> 北京,总里程:7459千米
北京 -> 上海 -> 广州 -> 合肥 -> 成都 -> 北京,总里程:7499千米
北京 -> 上海 -> 广州 -> 成都 -> 合肥 -> 北京,总里程:7386千米
北京 -> 上海 -> 成都 -> 合肥 -> 广州 -> 北京,总里程:8385千米
北京 -> 上海 -> 成都 -> 广州 -> 合肥 -> 北京,总里程:7594千米
北京 -> 合肥 -> 上海 -> 广州 -> 成都 -> 北京,总里程:6853千米
北京 -> 合肥 -> 上海 -> 成都 -> 广州 -> 北京,总里程:7739千米
北京 -> 合肥 -> 广州 -> 上海 -> 成都 -> 北京,总里程:7779千米
北京 -> 合肥 -> 广州 -> 成都 -> 上海 -> 北京,总里程:7594千米
北京 -> 合肥 -> 成都 -> 上海 -> 广州 -> 北京,总里程:8457千米
北京 -> 合肥 -> 成都 -> 广州 -> 上海 -> 北京,总里程:7386千米
北京 -> 广州 -> 上海 -> 合肥 -> 成都 -> 北京,总里程:7644千米
北京 -> 广州 -> 上海 -> 成都 -> 合肥 -> 北京,总里程:8457千米
北京 -> 广州 -> 合肥 -> 上海 -> 成都 -> 北京,总里程:7852千米
北京 -> 广州 -> 合肥 -> 成都 -> 上海 -> 北京,总里程:8385千米
北京 -> 广州 -> 成都 -> 上海 -> 合肥 -> 北京,总里程:7739千米
北京 -> 广州 -> 成都 -> 合肥 -> 上海 -> 北京,总里程:7459千米
北京 -> 成都 -> 上海 -> 合肥 -> 广州 -> 北京,总里程:7852千米
北京 -> 成都 -> 上海 -> 广州 -> 合肥 -> 北京,总里程:7779千米
北京 -> 成都 -> 合肥 -> 上海 -> 广州 -> 北京,总里程:7644千米
北京 -> 成都 -> 合肥 -> 广州 -> 上海 -> 北京,总里程:7499千米
北京 -> 成都 -> 广州 -> 上海 -> 合肥 -> 北京,总里程:6853千米
北京 -> 成都 -> 广州 -> 合肥 -> 上海 -> 北京,总里程:6781千米
最短运输路径:北京 -> 上海 -> 合肥 -> 广州 -> 成都 -> 北京,最短运输距离:6781千米
最短运输路径:北京 -> 成都 -> 广州 -> 合肥 -> 上海 -> 北京,最短运输距离:6781千米
>>>


设定不同的出发地,算法测试结果,如下: 

测试代码:

"""
作者:文方俊
日期:2022-02-07
功能:旅行商(TSP)问题最短路径规划实现测试代码
Email:wfj268@qq.com

"""

#测试数据
cities = { 0 : "北京", 1 : "上海", 2 : "合肥", 3 : "广州", 4 : "成都" }
DISTANCE_BETWEEN_CITIES = (
(0,1244,1044,2174,1854),
(1244,0,472,1529,2095),
(1044,472,0,1257,1615),
(2174,1529,1257,0,1954),
(1854,2095,1615,1954,0)
)
ID_START_CITY = 0
ID_CITIES = [0,1,2,3,4]
##make_routes_plan(ID_START_CITY, ID_CITIES)

for ID_START_CITY in ID_CITIES:
print ("\n出发地:{}".format(cities[ID_START_CITY]))
make_routes_plan(ID_START_CITY, ID_CITIES)
ID_CITIES = [0,1,2,3,4]


设定不同的出发地,算法测试执行结果,如下: 

(1)出发地:北京

出发地:北京
北京 -> 上海 -> 合肥 -> 广州 -> 成都 -> 北京,总里程:6781千米
北京 -> 上海 -> 合肥 -> 成都 -> 广州 -> 北京,总里程:7459千米
北京 -> 上海 -> 广州 -> 合肥 -> 成都 -> 北京,总里程:7499千米
北京 -> 上海 -> 广州 -> 成都 -> 合肥 -> 北京,总里程:7386千米
北京 -> 上海 -> 成都 -> 合肥 -> 广州 -> 北京,总里程:8385千米
北京 -> 上海 -> 成都 -> 广州 -> 合肥 -> 北京,总里程:7594千米
北京 -> 合肥 -> 上海 -> 广州 -> 成都 -> 北京,总里程:6853千米
北京 -> 合肥 -> 上海 -> 成都 -> 广州 -> 北京,总里程:7739千米
北京 -> 合肥 -> 广州 -> 上海 -> 成都 -> 北京,总里程:7779千米
北京 -> 合肥 -> 广州 -> 成都 -> 上海 -> 北京,总里程:7594千米
北京 -> 合肥 -> 成都 -> 上海 -> 广州 -> 北京,总里程:8457千米
北京 -> 合肥 -> 成都 -> 广州 -> 上海 -> 北京,总里程:7386千米
北京 -> 广州 -> 上海 -> 合肥 -> 成都 -> 北京,总里程:7644千米
北京 -> 广州 -> 上海 -> 成都 -> 合肥 -> 北京,总里程:8457千米
北京 -> 广州 -> 合肥 -> 上海 -> 成都 -> 北京,总里程:7852千米
北京 -> 广州 -> 合肥 -> 成都 -> 上海 -> 北京,总里程:8385千米
北京 -> 广州 -> 成都 -> 上海 -> 合肥 -> 北京,总里程:7739千米
北京 -> 广州 -> 成都 -> 合肥 -> 上海 -> 北京,总里程:7459千米
北京 -> 成都 -> 上海 -> 合肥 -> 广州 -> 北京,总里程:7852千米
北京 -> 成都 -> 上海 -> 广州 -> 合肥 -> 北京,总里程:7779千米
北京 -> 成都 -> 合肥 -> 上海 -> 广州 -> 北京,总里程:7644千米
北京 -> 成都 -> 合肥 -> 广州 -> 上海 -> 北京,总里程:7499千米
北京 -> 成都 -> 广州 -> 上海 -> 合肥 -> 北京,总里程:6853千米
北京 -> 成都 -> 广州 -> 合肥 -> 上海 -> 北京,总里程:6781千米
最短运输路径:北京 -> 上海 -> 合肥 -> 广州 -> 成都 -> 北京,最短运输距离:6781千米
最短运输路径:北京 -> 成都 -> 广州 -> 合肥 -> 上海 -> 北京,最短运输距离:6781千米


(2)出发地:上海

出发地:上海
上海 -> 北京 -> 合肥 -> 广州 -> 成都 -> 上海,总里程:7594千米
上海 -> 北京 -> 合肥 -> 成都 -> 广州 -> 上海,总里程:7386千米
上海 -> 北京 -> 广州 -> 合肥 -> 成都 -> 上海,总里程:8385千米
上海 -> 北京 -> 广州 -> 成都 -> 合肥 -> 上海,总里程:7459千米
上海 -> 北京 -> 成都 -> 合肥 -> 广州 -> 上海,总里程:7499千米
上海 -> 北京 -> 成都 -> 广州 -> 合肥 -> 上海,总里程:6781千米
上海 -> 合肥 -> 北京 -> 广州 -> 成都 -> 上海,总里程:7739千米
上海 -> 合肥 -> 北京 -> 成都 -> 广州 -> 上海,总里程:6853千米
上海 -> 合肥 -> 广州 -> 北京 -> 成都 -> 上海,总里程:7852千米
上海 -> 合肥 -> 广州 -> 成都 -> 北京 -> 上海,总里程:6781千米
上海 -> 合肥 -> 成都 -> 北京 -> 广州 -> 上海,总里程:7644千米
上海 -> 合肥 -> 成都 -> 广州 -> 北京 -> 上海,总里程:7459千米
上海 -> 广州 -> 北京 -> 合肥 -> 成都 -> 上海,总里程:8457千米
上海 -> 广州 -> 北京 -> 成都 -> 合肥 -> 上海,总里程:7644千米
上海 -> 广州 -> 合肥 -> 北京 -> 成都 -> 上海,总里程:7779千米
上海 -> 广州 -> 合肥 -> 成都 -> 北京 -> 上海,总里程:7499千米
上海 -> 广州 -> 成都 -> 北京 -> 合肥 -> 上海,总里程:6853千米
上海 -> 广州 -> 成都 -> 合肥 -> 北京 -> 上海,总里程:7386千米
上海 -> 成都 -> 北京 -> 合肥 -> 广州 -> 上海,总里程:7779千米
上海 -> 成都 -> 北京 -> 广州 -> 合肥 -> 上海,总里程:7852千米
上海 -> 成都 -> 合肥 -> 北京 -> 广州 -> 上海,总里程:8457千米
上海 -> 成都 -> 合肥 -> 广州 -> 北京 -> 上海,总里程:8385千米
上海 -> 成都 -> 广州 -> 北京 -> 合肥 -> 上海,总里程:7739千米
上海 -> 成都 -> 广州 -> 合肥 -> 北京 -> 上海,总里程:7594千米
最短运输路径:上海 -> 北京 -> 成都 -> 广州 -> 合肥 -> 上海,最短运输距离:6781千米
最短运输路径:上海 -> 合肥 -> 广州 -> 成都 -> 北京 -> 上海,最短运输距离:6781千米


(3)出发地:合肥

出发地:合肥
合肥 -> 北京 -> 上海 -> 广州 -> 成都 -> 合肥,总里程:7386千米
合肥 -> 北京 -> 上海 -> 成都 -> 广州 -> 合肥,总里程:7594千米
合肥 -> 北京 -> 广州 -> 上海 -> 成都 -> 合肥,总里程:8457千米
合肥 -> 北京 -> 广州 -> 成都 -> 上海 -> 合肥,总里程:7739千米
合肥 -> 北京 -> 成都 -> 上海 -> 广州 -> 合肥,总里程:7779千米
合肥 -> 北京 -> 成都 -> 广州 -> 上海 -> 合肥,总里程:6853千米
合肥 -> 上海 -> 北京 -> 广州 -> 成都 -> 合肥,总里程:7459千米
合肥 -> 上海 -> 北京 -> 成都 -> 广州 -> 合肥,总里程:6781千米
合肥 -> 上海 -> 广州 -> 北京 -> 成都 -> 合肥,总里程:7644千米
合肥 -> 上海 -> 广州 -> 成都 -> 北京 -> 合肥,总里程:6853千米
合肥 -> 上海 -> 成都 -> 北京 -> 广州 -> 合肥,总里程:7852千米
合肥 -> 上海 -> 成都 -> 广州 -> 北京 -> 合肥,总里程:7739千米
合肥 -> 广州 -> 北京 -> 上海 -> 成都 -> 合肥,总里程:8385千米
合肥 -> 广州 -> 北京 -> 成都 -> 上海 -> 合肥,总里程:7852千米
合肥 -> 广州 -> 上海 -> 北京 -> 成都 -> 合肥,总里程:7499千米
合肥 -> 广州 -> 上海 -> 成都 -> 北京 -> 合肥,总里程:7779千米
合肥 -> 广州 -> 成都 -> 北京 -> 上海 -> 合肥,总里程:6781千米
合肥 -> 广州 -> 成都 -> 上海 -> 北京 -> 合肥,总里程:7594千米
合肥 -> 成都 -> 北京 -> 上海 -> 广州 -> 合肥,总里程:7499千米
合肥 -> 成都 -> 北京 -> 广州 -> 上海 -> 合肥,总里程:7644千米
合肥 -> 成都 -> 上海 -> 北京 -> 广州 -> 合肥,总里程:8385千米
合肥 -> 成都 -> 上海 -> 广州 -> 北京 -> 合肥,总里程:8457千米
合肥 -> 成都 -> 广州 -> 北京 -> 上海 -> 合肥,总里程:7459千米
合肥 -> 成都 -> 广州 -> 上海 -> 北京 -> 合肥,总里程:7386千米
最短运输路径:合肥 -> 上海 -> 北京 -> 成都 -> 广州 -> 合肥,最短运输距离:6781千米
最短运输路径:合肥 -> 广州 -> 成都 -> 北京 -> 上海 -> 合肥,最短运输距离:6781千米


(4)出发地:广州

出发地:广州
广州 -> 北京 -> 上海 -> 合肥 -> 成都 -> 广州,总里程:7459千米
广州 -> 北京 -> 上海 -> 成都 -> 合肥 -> 广州,总里程:8385千米
广州 -> 北京 -> 合肥 -> 上海 -> 成都 -> 广州,总里程:7739千米
广州 -> 北京 -> 合肥 -> 成都 -> 上海 -> 广州,总里程:8457千米
广州 -> 北京 -> 成都 -> 上海 -> 合肥 -> 广州,总里程:7852千米
广州 -> 北京 -> 成都 -> 合肥 -> 上海 -> 广州,总里程:7644千米
广州 -> 上海 -> 北京 -> 合肥 -> 成都 -> 广州,总里程:7386千米
广州 -> 上海 -> 北京 -> 成都 -> 合肥 -> 广州,总里程:7499千米
广州 -> 上海 -> 合肥 -> 北京 -> 成都 -> 广州,总里程:6853千米
广州 -> 上海 -> 合肥 -> 成都 -> 北京 -> 广州,总里程:7644千米
广州 -> 上海 -> 成都 -> 北京 -> 合肥 -> 广州,总里程:7779千米
广州 -> 上海 -> 成都 -> 合肥 -> 北京 -> 广州,总里程:8457千米
广州 -> 合肥 -> 北京 -> 上海 -> 成都 -> 广州,总里程:7594千米
广州 -> 合肥 -> 北京 -> 成都 -> 上海 -> 广州,总里程:7779千米
广州 -> 合肥 -> 上海 -> 北京 -> 成都 -> 广州,总里程:6781千米
广州 -> 合肥 -> 上海 -> 成都 -> 北京 -> 广州,总里程:7852千米
广州 -> 合肥 -> 成都 -> 北京 -> 上海 -> 广州,总里程:7499千米
广州 -> 合肥 -> 成都 -> 上海 -> 北京 -> 广州,总里程:8385千米
广州 -> 成都 -> 北京 -> 上海 -> 合肥 -> 广州,总里程:6781千米
广州 -> 成都 -> 北京 -> 合肥 -> 上海 -> 广州,总里程:6853千米
广州 -> 成都 -> 上海 -> 北京 -> 合肥 -> 广州,总里程:7594千米
广州 -> 成都 -> 上海 -> 合肥 -> 北京 -> 广州,总里程:7739千米
广州 -> 成都 -> 合肥 -> 北京 -> 上海 -> 广州,总里程:7386千米
广州 -> 成都 -> 合肥 -> 上海 -> 北京 -> 广州,总里程:7459千米
最短运输路径:广州 -> 合肥 -> 上海 -> 北京 -> 成都 -> 广州,最短运输距离:6781千米
最短运输路径:广州 -> 成都 -> 北京 -> 上海 -> 合肥 -> 广州,最短运输距离:6781千米


(5)出发地:成都

出发地:成都
成都 -> 北京 -> 上海 -> 合肥 -> 广州 -> 成都,总里程:6781千米
成都 -> 北京 -> 上海 -> 广州 -> 合肥 -> 成都,总里程:7499千米
成都 -> 北京 -> 合肥 -> 上海 -> 广州 -> 成都,总里程:6853千米
成都 -> 北京 -> 合肥 -> 广州 -> 上海 -> 成都,总里程:7779千米
成都 -> 北京 -> 广州 -> 上海 -> 合肥 -> 成都,总里程:7644千米
成都 -> 北京 -> 广州 -> 合肥 -> 上海 -> 成都,总里程:7852千米
成都 -> 上海 -> 北京 -> 合肥 -> 广州 -> 成都,总里程:7594千米
成都 -> 上海 -> 北京 -> 广州 -> 合肥 -> 成都,总里程:8385千米
成都 -> 上海 -> 合肥 -> 北京 -> 广州 -> 成都,总里程:7739千米
成都 -> 上海 -> 合肥 -> 广州 -> 北京 -> 成都,总里程:7852千米
成都 -> 上海 -> 广州 -> 北京 -> 合肥 -> 成都,总里程:8457千米
成都 -> 上海 -> 广州 -> 合肥 -> 北京 -> 成都,总里程:7779千米
成都 -> 合肥 -> 北京 -> 上海 -> 广州 -> 成都,总里程:7386千米
成都 -> 合肥 -> 北京 -> 广州 -> 上海 -> 成都,总里程:8457千米
成都 -> 合肥 -> 上海 -> 北京 -> 广州 -> 成都,总里程:7459千米
成都 -> 合肥 -> 上海 -> 广州 -> 北京 -> 成都,总里程:7644千米
成都 -> 合肥 -> 广州 -> 北京 -> 上海 -> 成都,总里程:8385千米
成都 -> 合肥 -> 广州 -> 上海 -> 北京 -> 成都,总里程:7499千米
成都 -> 广州 -> 北京 -> 上海 -> 合肥 -> 成都,总里程:7459千米
成都 -> 广州 -> 北京 -> 合肥 -> 上海 -> 成都,总里程:7739千米
成都 -> 广州 -> 上海 -> 北京 -> 合肥 -> 成都,总里程:7386千米
成都 -> 广州 -> 上海 -> 合肥 -> 北京 -> 成都,总里程:6853千米
成都 -> 广州 -> 合肥 -> 北京 -> 上海 -> 成都,总里程:7594千米
成都 -> 广州 -> 合肥 -> 上海 -> 北京 -> 成都,总里程:6781千米
最短运输路径:成都 -> 北京 -> 上海 -> 合肥 -> 广州 -> 成都,最短运输距离:6781千米
最短运输路径:成都 -> 广州 -> 合肥 -> 上海 -> 北京 -> 成都,最短运输距离:6781千米
>>>



@全文完。。。

@联系方式:wfj268@qq.com

@喜欢的话,

@记得蒙田曾说过:风不会对漫无目的者有所牵挂,以此共勉!

@收藏+关注+点赞

@祝新年快乐,虎虎生威!



@回溯法求解0-1背包问题,TSP旅行商问题有妙招,从全排列说起_路径规划_09






举报

相关推荐

0 条评论