动态规划求解TSP问题分析
{2} 3 {4} 3+f4(2, {4})=3+7=10* {4} 4 {2} 4+f4(4, {2})=4+7=11
{2} 3 {5} 3+f4(2, {5})=3+6=9* {5} 6 {2} 6+f4(5, {2})=6+3=9*
{4} 4 {5} 4+f4(4, {5})=4+8=12 {5} 6 {4} 6+f4(5, {4})=6+5=11*
动态规划求解TSP问题
1
货郎担问题(Traveling Salesman Problem)
设有n个城市, 其中每两个城市之间都有道路 相连, 城市i和城市j之间的距离为Cij。从某城 市出发周游所有城市, 经过每个城市一次且仅 一次, 最后回到出发地, 求总行程最短的周游路 线。对于一般的情况可以假设两城市之间往返 距离不相等。在此例中, 为了简化问题, 设往返 距离相等, 即Cij=Cji。
(i, S4) (2, {3})
J
Cij
{3} 3
S5
Cij+f5(j, S5)
ቤተ መጻሕፍቲ ባይዱ
3+f5(3, )=3+7=10
f4(i, S4)
j*
10
3
(2, {4}) {4} 5
5+f5(4, )=5+2=7
7
4
(2, {5}) {5} 1
1+f5(5, )=1+5=6
6
5
(3, {2}) {2} 3
3+f5(2, )=3+2=5
5
2
(3, {4}) {4} 4
4+f5(4, )=4+2=6
6
4
(3, {5}) {5} 6
6+f5(5, )=6+5=11
11
5
(4, {2}) {2} 5
5+f5(2, )=5+2=7
7
2
(4, {3}) {3} 4
4+f5(3, )=4+7=11
11
3
(4, {5}) {5} 3
3+f5(5, )=3+5=8
对于k=5, 有
f5(i, )=min{Cij+f6(1, )}=Ci1, d5(i, 1), i=2, 3, 4, 5 f5(i, )的值列表如下:
i f5(i, )
2
2
3
7
4
2
5
5
1
5
2
1
5
2
2
7
3
6
5
3
4
3
4
7
对于k=4, 有
f4(i, S4)=min{Cij+f5(j, S5)}, jS4, f4(i, S4)的值列表如下:
f3(i, S3) 9 14 6 10 9 11 9 6 15 11 8 12
j* 3 3, 5 5 2 2, 5 5 3 5 3 2, 3 2 3
10
J
Cij
S4
Cij+f4(j, S4)
{3} 3 {4} 3+f4(3, {4})=3+6=9* {4} 5 {3} 5+f4(4, {3})=5+11=16
{3} 3 {5} 3+f4(3, {5})=3+11=14* {5} 1 {3} 1+f4(5, {3})=1+13=14*
{4} 5 {5} 5+f4(4, {5})=5+8=13 {5} 1 {4} 1+f4(5, {4})=1+5=6*
8
5
(5, {2}) {2} 1
1+f5(2, )=1+2=3
3
2
(5, {3}) {3} 6
6+f5(3, )=6+7=13
13
3
(5, {4}) {4} 3
3+f5(4, )=3+2=5
5
4
8
对于k=3, 有
f3(i, S3)=min{Cij+f4(j, S4)}, jS3, f3(i, S3)的值 列表如下:
{2} 1 {3} 1+f4(2, {3})=1+10=11* {3} 6 {2} 6+f4(3, {2})=6+5=11*
{2} 1 {4} 1+f4(2, {4})=1+7=8* {4} 3 {2} 3+f4(4, {2})=3+7=10
{3} 6 {4} 6+f4(3, {4})=6+6=12* {4} 3 {3} 3+f4(4, {3})=3+11=14
3
动态规划模型构造
阶段k:已经历过的城市个数, 包括当前所在的 城市。k=1, 2, …, n, n+1, k=1表示出发时 位于起点, k=n+1表示结束时回到终点。
状态变量:xk=(i, Sk), 其中i表示当前所在的 城市, Sk表示尚未访问过的城市的集合。很明 显 S1={2, 3, …, n}, …, Sn=Sn+1=
{2} 5 {3} 5+f4(2, {3})=5+10=15 {3} 4 {2} 4+f4(3, {2})=4+5=9*
{2} 5 {5} 5+f4(2, {5})=5+6=11 {5} 3 {2} 3+f4(5, {2})=3+3=6*
{3} 4 {5} 4+f4(3, {5})=4+11=15* {5} 3 {3} 3+f4(5, {3})=3+13=16
其中表示空集。并且有 xn=(i, ), i=2, 3, …, n, xn+1=(1, )
4
动态规划模型构造
决策变量:dk=(i, j), 其中i为当前所在的城市, j为下一站将要到达的城市。
状态转移方程:若当前的状态为 xk=(i, Sk)
采取的决策为 dk=(i, j)
则下一步到达的状态为 xk+1=T(xk, dk)=(j , Sk\{j})
5
动态规划模型构造
阶段指标:vk(xk, dk)=Cij 最优指标函数:fk(xk)=fk(i, Sk) 表示从城市i出
发, 经过Sk中每个城市一次且仅一次, 最后返 回城市1的最短距离。 终端条件:fn+1(xn+1)=fn+1(1, )=0
6
实例——五个城市的货郎担问题
求解步骤如下:
2
这就是所谓的货郎担问题(TSP)。这个问题 与最短路径问题不同, 最短路径问题以当前所 在的位置作为状态变量, 而在货郎担问题中, 状 态变量除了要指明当前所在位置外, 还要指明 已经经过哪几个城市。
由于货郎担问题经过的路线是一条经过所有城 市的闭合回路, 因此从哪一点出发是无所谓的, 因此不妨设从城市1出发。
9
(i, S3) (2, {3, 4}) (2, {3, 5}) (2, {4, 5}) (3, {2, 4}) (3, {2, 5}) (3, {4, 5}) (4, {2, 3}) (4, {2, 5}) (4, {3, 5}) (5, {2, 3}) (5, {2, 4}) (5, {3, 4})
动态规划法,回溯法,分支限界法求解TSP问题实验报告
TSP问题算法实验报告指导教师:****名:***学号:**********提交日期:2015年11月目录总述 (2)动态规划法 (3)算法问题分析 (3)算法设计 (3)实现代码 (3)输入输出截图 (6)OJ提交截图 (6)算法优化分析 (6)回溯法 (6)算法问题分析 (6)算法设计 (7)实现代码 (7)输入输出截图 (9)OJ提交截图 (9)算法优化分析 (10)分支限界法 (10)算法问题分析 (10)算法设计 (10)实现代码 (10)输入输出截图 (15)OJ提交截图 (15)算法优化分析 (15)总结 (16)总述TSP问题又称为旅行商问题,是指一个旅行商要历经所有城市一次最后又回到原来的城市,求最短路程或最小花费,解决TSP可以用好多算法,比如蛮力法,动态规划法…具体的时间复杂的也各有差异,本次实验报告包含动态规划法,回溯法以及分支限界法。
动态规划法算法问题分析假设n个顶点分别用0~n-1的数字编号,顶点之间的代价存放在数组mp[n][n]中,下面考虑从顶点0出发求解TSP问题的填表形式。
首先,按个数为1、2、…、n-1的顺序生成1~n-1个元素的子集存放在数组x[2^n-1]中,例如当n=4时,x[1]={1},x[2]={2},x[3]={3},x[4]={1,2},x[5]={1,3},x[6]={2,3},x[7]={1,2,3}。
设数组dp[n][2^n-1]存放迭代结果,其中dp[i][j]表示从顶点i经过子集x[j]中的顶点一次且一次,最后回到出发点0的最短路径长度,动态规划法求解TSP问题的算法如下。
算法设计输入:图的代价矩阵mp[n][n]输出:从顶点0出发经过所有顶点一次且仅一次再回到顶点0的最短路径长度1.初始化第0列(动态规划的边界问题)for(i=1;i<n;i++)dp[i][0]=mp[i][0]2.依次处理每个子集数组x[2^n-1]for(i=1;i<n;i++)if(子集x[j]中不包含i)对x[j]中的每个元素k,计算d[i][j]=min{mp[i][k]+dp[k][j-1]};3.输出最短路径长度。
TSP问题分析动态规划,分支界限法,蛮力法
算法综合实验报告学号: 1004111115 姓名:李宏强一、实验内容:分别用动态规划、贪心及分支限界法实现对TSP问题(无向图)的求解,并至少用两个测试用例对所完成的代码进行正确性及效率关系上的验证。
二、程序设计的基本思想、原理和算法描述:(包括程序的数据结构、函数组成、输入/输出设计、符号名说明等)1、动态规划法(1)数据结构:利用二进制来表示集合,则集合S可由一个十进制数x相对应,此x所由一个十进制数x相对应,此x所对应的二进制数为y,如果y的第k位为1,则表示k存在集合S中。
例如:集合S={0,1}(其子集合为{}{0}{1}{01}),我们用二进制数11(所对应十进制数为3)表示S,11中右手边第1个数为1表示0在集合S中,右手边第二个数为1表示1在集合S中,其他位为0表示其它数字不在集合S中;同理,集合S={0,2}(其子集合为{}{0}{2}{02}可用二进制数101(所对应十进制数为5)表示(右手边第1个数为1表示0在集合S中,右手边第二个数为0表示1不在集合S中,右手边第3个数为1表示2在集合S中,则说明0,2在集合中,1不在集合中。
利用邻接矩阵表示任意两点之间的距离例如:mp[i][j]表示点i,j两点之间的距离。
(2)函数组成输入函数in()利用动态规划法算法实现的求解函数solve()主函数main()(3)输入/输出设计本程序可以通过键盘进行输入、屏幕进行输出。
(根据实际程序情况,还可以选择随机产生输入数据、将输出数据输出到文件等其它方式)这里采用随机产生输入数据,将数据输出在屏幕上的方式。
(4)符号名说明n 表示顶点个数。
mp[i][j] 表示顶点i和顶点j之间的距离。
dp[i][j] 表示顶点i经过集合S(用二进制表示的数为j)后回到起始点的最短路径和。
(5)算法描述某一个点i不经过任意点回到起始点的最短路径和为mp[i][0](默认初始点为0)dp[i][0] = mp[i][0]; (1<=i<n)点i经过集合S(二进制表示的数为j)的最短路径和为从点i经过集合S中的某一点k后再从该点出发,经过集合S-{k}的最小值。
动态规划解TSP问题
用动态规划方法编程求解下面的问题:某推销员要从城市v1 出发,访问其它城市v2,v3,…,v6 各一次且仅一次,最后返回v1。
D为各城市间的距离矩阵。
问:该推销员应如何选择路线,才能使总的行程最短?1、变量设定阶段k:已遍历过k个结点,k=1,2…6,7。
K=1表示刚从V1出发,k=7表示已回到起点V1状态变量Xk=(i,Sk):已遍历k个结点,当前位于i结点,还未遍历的结点集合为Sk。
则X1=(1,{2,3,4,5,6}),X6=(i,Φ),X7=(1,Φ)决策变量Uk=(i,j):已遍历k个结点,当前位于i结点,下一个结点选择j。
状态转移方程:X k+1 = T(Xk,Uk) = (j,Sk-{j})第k阶段的指标函数Vk = D[i,j]。
最优指标函数Fk(Xk) = Fk(i,Sk):已遍历k个结点,当前从i结点出发,访问Sk中的结点一次且仅一次,最后返回起点V1的最短距离。
则Fk(i,Sk) = min{ D[i,j] + F k+1(j,Sk-{j}) } 1≤k≤6F7(X7) = F7(1,Φ) = 02、分析:3、伪代码和时间复杂度为方便计算,结点编号改为0到5.(1)用一张二维表格F[][]表示F(i,Sk),行数是n,列数是2n-1。
(2)行号表示当前所在的结点i。
列号对应的五位二进制表示表示{V5,V4,V3,V2,V1}的一个子集,1表示在集合中,0表示不在集合中。
例如:00110表示的集合为{V3,V2},00000表示空集(3)再用一张n*2n-1的表格M[][]存储对应每个状态(i,Sk)所做的最优决策,以便回溯找最短路线。
伪代码:TSP(int D[][],int n)//输入n个顶点的有向图,矩阵D[][]是有向图的邻接矩阵//D[][]是原图的邻接矩阵//F[][]中存储阶段最短路径,M[][]中存储阶段最优策略, 行数是n,列数是2n-1//找到从V0出发,遍历所有城市一次且仅一次再回到V0的最短路径长度//并输出最短路径{for(i=0; i<n; i++)F[i][0] = D[i][0]; //初始化第0列,F6(i,Φ)= D[i,0]for(i=1; i<2n-1-1; i++) //列for(j=1; j<n; j++) //行if(j不在i的二进制表示对应的集合中)对于i对应集合中的每一个点k{计算D[j][k]+F[k][i-2k-1]并选择使之取得最小值min的k*;F[k][i] = min ; //填表,记录阶段最优值M[k][i] = k* ; //记录每个状态的最优决策k*}//i==2n-1-1 时对于i中的每个节点k计算D[0][k] + F[k][ [i-2k-1]并选择使之取得最小值min的k*F[0][ 2n -1-1] = min; //总最短路径 M[0][ 2n -1-1] = k*;//回溯查表M 输出最短路径 输出V0for(2n -1-1,j=0; i>0; ) { j = M[j][i];//下一步去往哪个结点 i = i –2j -1;//从i 表示的集合中删除j 输出Vj }}考虑算法中所做的加法和比较次数:∑k (k −1)(n −1k)n−1k=2 + (n -1) = (n -1)(n -2)2n -3 + (n -1) = O(n 22n )。
动态规划求解TSP问题
f5(i, )=min{Cij+f6(1, )}=Ci1, d5(i, 1), i=2, 3, 4, 5 f5(i, )的值列表如下:
1
i 2
f5(i, ) 2
5 3
5 1 2 7
2
2 3 3
3
4 5
7
2 5
6
4 4
5
7
对于k=4, 有
f4(i, S4)=min{Cij+f5(j, S5)}, jS4, f4(i, S4。并且有 xn=(i, ), i=2, 3, …, n,
xn+1=(1, )
4
动态规划模型构造
决策变量:dk=(i, j), 其中i为当前所在的城市, j为下一站将要到达的城市。 状态转移方程:若当前的状态为 xk=(i, Sk) 采取的决策为 dk=(i, j) 则下一步到达的状态为 xk+1=T(xk, dk)=(j , Sk\{j})
9
(i, S3) (2, {3, 4}) (2, {3, 5})
J {3} {4} {3} {5}
Cij 3 5 3 1
S4 {4} {3} {5} {3}
Cij+f4(j, S4) 3+f4(3, {4})=3+6=9* 5+f4(4, {3})=5+11=16 3+f4(3, {5})=3+11=14* 1+f4(5, {3})=1+13=14*
(1, S1) (1, {2, 3, 4, 5})
J {2} {3} {4} {5}
Cij 2 7 2 5
S2 {3, 4, 5} {2, 4, 5} {2, 3, 5} {2, 3, 4}
动态规划法,回溯法,分支限界法求解TSP问题实验报告材料
TSP问题算法实验报告指导教师:季晓慧姓名:辛瑞乾学号: 1004131114 提交日期: 2015年11月目录总述 (2)动态规划法 (3)算法问题分析 (3)算法设计 (3)实现代码 (3)输入输出截图 (6)OJ提交截图 (6)算法优化分析 (6)回溯法 (6)算法问题分析 (6)算法设计 (7)实现代码 (7)输入输出截图 (9)OJ提交截图 (10)算法优化分析 (10)分支限界法 (10)算法问题分析 (10)算法设计 (10)实现代码 (11)输入输出截图 (15)OJ提交截图 (16)算法优化分析 (16)总结 (16)总述TSP问题又称为旅行商问题,是指一个旅行商要历经所有城市一次最后又回到原来的城市,求最短路程或最小花费,解决TSP可以用好多算法,比如蛮力法,动态规划法…具体的时间复杂的也各有差异,本次实验报告包含动态规划法,回溯法以及分支限界法。
动态规划法算法问题分析假设n个顶点分别用0~n-1的数字编号,顶点之间的代价存放在数组mp[n][n]中,下面考虑从顶点0出发求解TSP问题的填表形式。
首先,按个数为1、2、…、n-1的顺序生成1~n-1个元素的子集存放在数组x[2^n-1]中,例如当n=4时,x[1]={1},x[2]={2},x[3]={3},x[4]={1,2},x[5]={1,3},x[6]={2,3},x[7]={1,2,3}。
设数组dp[n][2^n-1]存放迭代结果,其中dp[i][j]表示从顶点i经过子集x[j]中的顶点一次且一次,最后回到出发点0的最短路径长度,动态规划法求解TSP问题的算法如下。
算法设计输入:图的代价矩阵mp[n][n]输出:从顶点0出发经过所有顶点一次且仅一次再回到顶点0的最短路径长度1.初始化第0列(动态规划的边界问题)for(i=1;i<n;i++)dp[i][0]=mp[i][0]2.依次处理每个子集数组x[2^n-1]for(i=1;i<n;i++)if(子集x[j]中不包含i)对x[j]中的每个元素k,计算d[i][j]=min{mp[i][k]+dp[k][j-1]};3.输出最短路径长度。
Tsp问题的几种算法的分析
摘要本文分析比较了tsp问题的动态计划算法,分支界限法,近似等算法。
分析了旅行商问题的时刻度特点,针对启发式算法求解旅行商问题中存在的一些问题提出了改良算法。
此算法将群体分为假设干小子集,并用启发式交叉算子,以较好利用父代个体的有效信息,达到快速收敛的成效,实验说明此算法能提高寻优速度,解得质量也有所提高。
关键词:旅行商问题 TSPAbstractthis paper analyzed the time complexity of traveling salesman problem,then put forward some imprivement towards the genetic algorithm for solving this problen: divding the population into some small parent individual well.so it can quickly get into convergence, the experimental result indicates the impwoved algorithm can accelerate the apeed of finding solution and improve the precision. Keywords traveling salesman problem; genetic algorithm; subset; henristic crossover operator目录1、摘要--------------------------------------------------------------12、Abstract---------------------------------------------------------13、Tsp问题的提法------------------------------------------------24、回溯法求Tsp问题--------------------------------------------35、分支限界法求Tsp问题--------------------------------------76、近似算法求解Tsp问题-------------------------------------107、动态计划算法解Tsp问题----------------------------------12引言tsp问题刚提出时,很多人都以为很简单。
动态规划解TSP问题
用动态规划方法编程求解下面的问题:某推销员要从城市v1 出发,访问其它城市v2,v3,…,v6 各一次且仅一次,最后返回v1。
D 为各城市间的距离矩阵。
问:该推销员应如何选择路线,才能使总的行程最短?⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡=012201622561801011274516804323415105019232125301801250403020100654321v v v v v v D1、变量设定阶段k :已遍历过k 个结点,k=1,2…6,7。
K=1表示刚从V1出发,k=7表示已回到起点V1状态变量Xk=(i ,Sk):已遍历k 个结点,当前位于i 结点,还未遍历的结点集合为Sk 。
则X1=(1,{2,3,4,5,6}),X6=(i ,Φ),X7=(1,Φ)决策变量Uk=(i ,j):已遍历k 个结点,当前位于i 结点,下一个结点选择j 。
状态转移方程:X k+1 = T(Xk ,Uk) = (j ,Sk-{j}) 第k 阶段的指标函数Vk = D[i,j]。
最优指标函数Fk(Xk) = Fk(i ,Sk):已遍历k 个结点,当前从i 结点出发,访问Sk中的结点一次且仅一次,最后返回起点V1的最短距离。
则Fk(i ,Sk) = min{ D[i,j] + F k+1(j ,Sk-{j}) } 1≤k ≤6 F 7(X7) = F 7(1,Φ) = 02、分析:(1)k=6时,F6(i ,Φ) = min{D[i,1] + F7(X7)} = D[i,1] i=2,3,4,5,6(6)k=1时,F1(1,S1) = min{D[1,j] + F2(j,S2)}3、伪代码和时间复杂度为方便计算,结点编号改为0到5.(1)用一张二维表格F[][]表示F(i,Sk),行数是n,列数是2n-1。
(2)行号表示当前所在的结点i。
列号对应的五位二进制表示表示{V5,V4,V3,V2,V1}的一个子集,1表示在集合中,0表示不在集合中。
TSP问题分析动态规划-分支界限法-蛮力法教学文案
T S P问题分析动态规划-分支界限法-蛮力法算法综合实验报告学号: 1004111115 姓名:李宏强一、实验内容:分别用动态规划、贪心及分支限界法实现对TSP问题(无向图)的求解,并至少用两个测试用例对所完成的代码进行正确性及效率关系上的验证。
二、程序设计的基本思想、原理和算法描述:(包括程序的数据结构、函数组成、输入/输出设计、符号名说明等)1、动态规划法(1)数据结构:①利用二进制来表示集合,则集合S可由一个十进制数x相对应,此x所对应的二进制数为y,如果y的第k位为1,则表示k存在集合S中。
例如:集合S={0,1}(其子集合为{}{0}{1}{01}),我们用二进制数11(所对应十进制数为3)表示S,11中右手边第1个数为1表示0在集合S中,右手边第二个数为1表示1在集合S中,其他位为0表示其它数字不在集合S中;同理,集合S={0,2}(其子集合为{}{0}{2}{02}可用二进制数101(所对应十进制数为5)表示(右手边第1个数为1表示0在集合S中,右手边第二个数为0表示1不在集合S中,右手边第3个数为1表示2在集合S中,则说明0,2在集合中,1不在集合中。
②利用邻接矩阵表示任意两点之间的距离例如:mp[i][j]表示点i,j两点之间的距离。
(2)函数组成①输入函数in()②利用动态规划法算法实现的求解函数solve()③主函数main()(3)输入/输出设计本程序可以通过键盘进行输入、屏幕进行输出。
(根据实际程序情况,还可以选择随机产生输入数据、将输出数据输出到文件等其它方式)这里采用随机产生输入数据,将数据输出在屏幕上的方式。
(4)符号名说明① n 表示顶点个数。
② mp[i][j] 表示顶点i和顶点j之间的距离。
③ dp[i][j] 表示顶点i经过集合S(用二进制表示的数为j)后回到起始点的最短路径和。
(5)算法描述①某一个点i不经过任意点回到起始点的最短路径和为mp[i][0](默认初始点为0)dp[i][0] = mp[i][0]; (1<=i<n)②点i经过集合S(二进制表示的数为j)的最短路径和为从点i经过集合S中的某一点k后再从该点出发,经过集合S-{k}的最小值。
TSP-动态规划
动态规划算法总体思想 :
在每种情况下, 列出各种可能的局部解, 然后按 某些条件, 从局部解(或中间解)中挑选出可能产生 最佳解的结果,而扬弃其余。
TSP问题
从某一城市出发,遍历各城市一次且 仅一次,最后返回原地,求最短路径。 分析: 令T(Vi;V)表示从Vi出发, 经V各点一次, 最后返回Vi的路径 模型 T(Vi;V)=min{dij+T(Vj;V\{vj})} 要求的问题是:
TSP问题
从某一城市出发,遍历各城市一次且 仅一次,最后返回原地,求最短路径。 (3) T(V2;V3,V4)=20 T(V3;V2,V4)=19 T(V4;V2,V3)=18 (4) T(V1;V2,V3,V4)=min{d12+T(V2;V3, V4), d13+T(V3; V2,V4), d14+T(V4;V2,V3)} =min{6+20,7+19,9+18} =26 故最短路径为:1,2,4,3,1 1,3,4,2,1
TSP问题
复杂性估计:
T(V1;V2,V3,V4)
T(V2;V3,V4)
T(V2;V3) T(V2;V4)
T(V3;V2,V4)
T(V3;V2) T(V3;V4)
T(V4;V2,V3) T(V4;V2) T(V4;V3)
T(v34; φ)
T(V2;φ)
T(v3; φ)
算法总体思想
结论 :
动态规划虽然提供了一种解法,但也不是一种可 行的算法。
算法总体思想
最佳原理 :
假设为了解决某一优化问题,需要依次作出n个 决策D1,D2,…,Dn,如若这个决策是最优的,对于任 何一个整数k,1<k<n,不论前面k个是怎样的,以 后的最优决策只取决于由前面决策所确定的当前状态, 即以后的决策 DK+1,Dk+2,…,Dn也是当前最优的。
动态规划-TSP问题-最短超级串
动态规划-TSP问题-最短超级串2020-03-03 22:55:08问题描述:给定⼀个字符串数组 A,找到以 A 中每个字符串作为⼦字符串的最短字符串。
我们可以假设 A 中没有字符串是 A 中另⼀个字符串的⼦字符串。
⽰例 1:输⼊:["alex","loves","leetcode"]输出:"alexlovesleetcode"解释:"alex","loves","leetcode" 的所有排列都会被接受。
⽰例 2:输⼊:["catg","ctaagt","gcta","ttca","atgcatc"]输出:"gctaagttcatgcatc"提⽰:1 <= A.length <= 121 <= A[i].length <= 20问题求解:解法⼀:暴⼒求解⾸先我们要明确的就是,本题可以转化成图论的题⽬,就是在⼀个图中要遍历所有的节点⼀次,最后路径的最⼩值是多少。
(这⾥和TSP略有不同,即我们不需要返回起始节点)暴⼒求解,可以理解为全排列,只不过我们做了⼀些剪枝操作进⾏了加速。
时间复杂度:O(n!)int res = (int)1e9;List<Integer> path;int n;public String shortestSuperstring(String[] A) {n = A.length;int[][] graph = new int[n][n];for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {for (int k = Math.min(A[i].length(), A[j].length()); k >= 0; k--) {if (A[j].substring(0, k).equals(A[i].substring(A[i].length() - k))) {graph[i][j] = A[j].length() - k;break;}}}}helper(A, graph, 0, 0, 0, new ArrayList<>());StringBuffer sb = new StringBuffer();for (int i = 0; i < n; i++) {int node = path.get(i);String s = A[node];if (i == 0) sb.append(s);else sb.append(s.substring(s.length() - graph[path.get(i - 1)][node]));}return sb.toString();}private void helper(String[] A, int[][] graph, int k, int used, int curr, List<Integer> curr_p) {if (curr >= res) return;if (k == n) {res = curr;path = new ArrayList<>(curr_p);return;}for (int i = 0; i < n; i++) {if ((used & (1 << i)) != 0) continue;curr_p.add(i);helper(A, graph, k + 1, used | (1 << i), k == 0 ? A[i].length() : curr + graph[curr_p.get(curr_p.size() - 2)][i], curr_p);curr_p.remove(curr_p.size() - 1);}}解法⼆:DPdp[s][i] : 当前访问过的节点状态为s,且以i为结尾的最短路径。
