Coursera Algorithm II PA5

这次作业题要求实现25个点的TSP问题

TSP的非递归动规解法本身就有一定的难度,但本题的重点却是内存优化,因为25点的 TSP 动规解法需要的内存较多

 

为了优化空间复杂度,这里引入了两个技巧:

1. Gosper's hack

2. Combinadic

 

首先,还是要清楚了解TSP解法的状态转移方程,这里对状态转移方程做了详细的介绍,且带有伪代码

1. 我们用二进制来表示集合 S ,比如5个点的TSP问题,00111 表示集合S中有第1,2,3个点,00111 就表示大小为 3 的一个集合。

2. 从伪代码中,可以看出,我们需要枚举大小为 n 的集合 S,然后计算 C(S,k)

Gosper's hack 能够以 o(1) 的时间计算出大小为 n 的下一个集合S,比如从 00111 -> 01011。

3. 对于 C(S,k),假如使用二进制来表示集合S,我们需要的空间是 int dp[x][y], 其中 x 为2^25, y 为 25,每一个int类型还需要4字节的空间,需要的总空间超过1G,这太高了

因此,我们需要引入另一种保存状态的机制:Combinatorial number system

用一个例子来说明组合数系统:假设对于5个点的TSP问题,我们要描述大小为 3 的所有集合(比如,00111),用朴素的二进制表示方法总是需要(2^5)的空间,但组合数系统用index来描述集合,如下表:

   Index           表示的集合
0 {0, 1, 2} 1 {0, 1, 3} 2 {0, 1, 4} 3 {0, 2, 3} 4 {0, 2, 4} 5 {0, 3, 4} 6 {1, 2, 3} 7 {1, 2, 4} 8 {1, 3, 4} 9 {2, 3, 4}

从上面的表中可以看出,我们仅需要 10 个数就能表示所有的集合,这样,对于5个点的TSP问题用 (2^4)即可完成大小为3的所有集合的标注。

那么,对于大小为 25 的TSP问题,我们可以节省多少空间呢?

朴素二进制表示方法 (2^25)*25*4,这个上面已经计算过了,大于1G

压缩后的方法         (c(25,13))*25*4, 其中 c(25,13)是从25个点中选取13 个点,这是使用压缩方法后需要内存大小的极值,经计算,不会超过300MB

我们已经看到状态压缩的内存优势,但不禁要问,如何从 01110 这样任意一个集合转化成对应的 index 呢?是时候让 Combinadic 登场了,这里链接提供了index, 集合的转换例子,比如10个点的TSP问题,0101001011对应的index是72, 计算公式是 C(8,5) + C(6,4) + C(3,3) + C(1,2) + C(0,1),第二个参数递减,第一个参数是不为0的那些位数

72   C(8,5) + C(6,4) + C(3,3) + C(1,2) + C(0,1)   0101001011        (8,6,3,1,0)

 

有了这两个技巧,25个点的TSP 问题就不用担心内存的问题了。

对于几百个点的TSP问题,用 local search 随机算法比较合适, youtube 上有一个视频,动态的展现出 local search 求解几百个点的tsp问题,很是震撼。

 

转载于:https://www.cnblogs.com/zhouzhuo/p/3758253.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值