zoukankan      html  css  js  c++  java
  • 状态压缩动态规划 -- 旅行商问题

    旅行商问题:

    N个点(N<16)的带权有向图D,求一条路径,使得这条路经过每一个点恰好一次。

    而且路径上边的权值和最小(或者最大),或者求一条具有这样性质的回路。



    状态压缩:

    将二进制表示十进制数N的点集,比方:

    10 = 0000000000001010 代表第1和3个点已经路过

    18 = 0000000000010010 代表第1和4个点已经路过

    一个整数就是一个点集。

    dp_arr[binary][to_]代表经过点集 binary 中,当前终点为to_,

    且路径最短的值。若该状态不存在就是INF



    状态转移:

    单点集合:状态存在dp_arr[1<<to_][to_] = 0;否则无穷大.

    非单点集合:

    dp_arr[binary][to] = min( dp_arr[from_bin][from_] + graph[from_][to] )

    from_为 from_ 与 to 右边相连,且dp_arr[from_bin][from_] 状态存在,

    且 dp_arr[from_bin][from_] 中的 from_bin 尚未包括 to 点信息的一系列点。状态不存在就为INF



    最后结果:

    min( dp_arr[( 1<<n ) – 1][to_] ) ( 0 <= to_ < N )



    python:

    INF = 1 << 10
    
    graph = [
        [0, 2, INF, 3],
        [INF, 0, 6, 1],
        [INF, 2, 0, 4],
        [5, 1, 3, 0]
    ]
    
    state_list = []
    citys = 4
    
    dp_arr = [ [ INF for i in xrange( citys ) ] for j in xrange( 1 << citys ) ]
    
    
    class State:
        def __init__( self, binary = None, end = None ):
            self.binary = binary
            self.end    = end
            
    
    def dp():
        for to_ in range( citys ):
            binary = 1 << to_
            end    = to_
            dp_arr[binary][end] = 0
            state_list.append( State( binary, end ) )
    
        while len( state_list ):
            pre      = state_list.pop()
            from_bin = pre.binary
            from_    = pre.end
            
            for to_ in xrange( citys ):
                binary = 1 << to_
                
                if binary & from_bin or graph[from_][to_] is INF:
                    continue
                
                binary    |= from_bin
                next_state = State( binary, to_ )
                distance   = dp_arr[from_bin][from_] + graph[from_][to_]
                state_list.append( next_state )
                dp_arr[binary][to_] = min( dp_arr[binary][to_], distance )
               
    
    if __name__ == '__main__':
        dp()
        ans = min( [ dp_arr[( 1 << citys ) - 1][to_] for to_ in xrange( citys ) ] )
        print ans    
    


  • 相关阅读:
    [CISCN2019 华北赛区 Day1 Web2]ikun
    [BJDCTF 2nd]简单注入
    [BJDCTF2020]ZJCTF,不过如此
    [BJDCTF2020]The mystery of ip
    [SWPU2019]Web1
    [WesternCTF2018]shrine
    [BJDCTF 2nd]假猪套天下第一
    [BJDCTF2020]Mark loves cat
    [GWCTF 2019]我有一个数据库
    C语言学习笔记_函数与函数库
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6756581.html
Copyright © 2011-2022 走看看