zoukankan      html  css  js  c++  java
  • 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问题,很是震撼。

  • 相关阅读:
    word 软换行与硬换行
    正态分布(normal distribution)与偏态分布(skewed distribution)
    hdu1043Eight (经典的八数码)(康托展开+BFS)
    TCP和UDP的区别
    SDUT2608(Alice and Bob)
    The Six Types of Rails Association
    排序算法c语言描述---堆排序
    Jenkins的plugin开发
    SDUTRescue The Princess(数学问题)
    【数据库系列】之存储过程与触发器
  • 原文地址:https://www.cnblogs.com/zhouzhuo/p/3758253.html
Copyright © 2011-2022 走看看