由旅行商問題認識何為狀態壓縮

動態規劃

動態規劃(dynamic programming)是運籌學的一個分支,是求解決策過程(decision process)最優化的數學方法。20世紀50年代初美國數學家R.E.Bellman等人在研究多階段決策過程(multistep decision process)的優化問題時,提出了著名的最優化原理(principle of optimality),把多階段過程轉化為一系列單階段問題,利用各階段之間的關系,逐個求解,創立了解決這類過程優化問題的新方法——動態規劃。

https://blog.csdn.net/hebtu666/article/category/8018091基礎總結

?

狀態壓縮

我們在進行動態規劃時,有時狀態相當復雜,看上去需要很多空間,比如一個數組才能表示一個狀態,那么就需要對狀態進行某種編碼,進行壓縮表示。

比如:狀態和某個集合有關,集合里可以有一些元素,沒有另一些元素,那么就可以用一個整數表示該集合,每個元素對應于一個bit,有該元素,則該bit就是1。

這個皇后問題就可以幫助理解https://blog.csdn.net/hebtu666/article/details/84631083

?

旅行商問題

?

旅行商問題(TravelingSalesmanProblem,TSP)是一個經典的組合優化問題。經典的TSP可以描述為:一個商品推銷員要去若干個城市推銷商品,該推銷員從一個城市出發,需要經過所有城市后,回到出發地。應如何選擇行進路線,以使總的行程最短。從圖論的角度來看,該問題實質是在一個帶權完全無向圖中,找一個權值最小的Hamilton回路。由于該問題的可行解是所有頂點的全排列,隨著頂點數的增加,會產生組合爆炸,它是一個NP完全問題。由于其在交通運輸、電路板線路設計以及物流配送等領域內有著廣泛的應用,國內外學者對其進行了大量的研究。早期的研究者使用精確算法求解該問題,常用的方法包括:分枝定界法、線性規劃法、動態規劃法等。但是,隨著問題規模的增大,精確算法將變得無能為力,因此,在后來的研究中,國內外學者重點使用近似算法或啟發式算法,主要有遺傳算法、模擬退火法、蟻群算法、禁忌搜索算法、貪婪算法和神經網絡等。

?

如圖,我們如何從0點出發,以最小代價走過所有的點?

?

分析

?

拋開這個圖,我們試想:我們可能從0點一次性走到哪些點呢?

只可能1點、2點、3點、4點(廢話)

我們如果知道了

1)從1點開始走,經過所有的點,最后走到了0點的最小距離;a

2)從2點開始走,經過所有的點,最后走到了0點的最小距離;b

3)從3點開始走,經過所有的點,最后走到了0點的最小距離;c

4)從4點開始走,經過所有的點,最后走到了0點的最小距離;d

請再次注意:

我們可能從0點一次性走到哪些點呢?

只可能1點、2點、3點、4點(廢話)

所以我們可以從0點走到1點,再從1點經過最小距離走到0點。

2點、3點、4點同理。

那么我們取min(a+3,b+MAX,c+4,d+MAX)即可。

3為0點走到1點的距離,4為0點走到3點的距離。

MAX代表此路不通。。

?

那我們繼續思考,abcd怎么求呢?其實同樣的:

?

比如:求a

從1點開始走,經過所有的點,最后走到了0點的最小距離;a

同樣的思考:我們可能從1點一次性走到哪些點呢?

答:可以走到0點、2點、3點、4點。

注意:由于問題要求為:只能經過每一個頂點一次,所以我們要去掉0點,因為我們經過0點,最后再到0點就會重復,所以,

“經過所有的點”是不準確的,是除0點的所有的點。

所以只有三個點可能從1點走過去,我們需要求:

1)從2點開始走,經過除0點所有的點,最后走到了0點的最小距離x

2)從3點開始走,經過除0點所有的點,最后走到了0點的最小距離y

3)從4點開始走,經過除0點所有的點,最后走到了0點的最小距離z

然后取min(x+到2點的距離,y+到3點的距離,z+到4點的距離)

?

歸納表達式

1)我們會發現,每一次狀態轉移其實對應的是一個點的集合:

以后還會有經過除1,2點,經過除1,2,3點等等。

?

2)還有從哪個點開始走:

這兩個條件就可以描述當前的狀態。

我們把上面的總結用公式表示出來:

S為已經訪問過的點的集合

v表示當前所在點。

那么dp[S][v]就表示為從點v出發訪問剩余點,最終返回0點的最小長度。

我們把剛才的求解過程用公式表達出來。

dp[S][v]=min(dp[S\bigcup {u}][u]+d(v,u)\mid u\euro S)

?這個符號我實在沒找到,理解意思。

?

壓縮

像這樣,狀態可以根據集合表示的DP,我們稱作狀態壓縮DP。

狀態和某個集合有關,集合里可以有一些元素,沒有另一些元素,那么就可以用一個整數表示該集合,每個元素對應于一個bit,有該元素,則該bit就是1。?

本題來說,所有點都在集合里就是11111

哪個點沒在,對應的位就為0

?

注意:對于狀態不是整數而是集合的情況,通常不太容易確定DP的順序,如果確實不好想順序,可以通過記憶化搜索來做。

集合S,如果對于任意S(i)<S(j),那么一定有i<j。所以確定了順序。

?

確定dp表的大小,有n個城市,從0開始編號,那么dp表的行數就是n,列數就是2^(n-1)

int n;
int d[MAX_N][MAX_N];//鄰接矩陣
int dp[1<<MAX_N][MAX_N];

對于數字x,要看它的第i位是不是1,那么可以通過 (x >>i) & 1取出那一位來看

先用足夠大的值初始化dp數組,不要影響結果,然后核心代碼:

for(int S = (1<<n)-2 ; S >= 0 ; s--)//每一個集合
{for(int v = 0 ; v < n ; v++)//每一個出發點{for(int u = 0 ; u < n ; u++)//訪問每一個點{if(!(S>>u&1))//判斷是否在集合中{dp[S][v] = min(dp[S][v] , dp[S | 1<<u][u]+d[v][u]);}}}
}

?

總結

?

當我們把狀態壓縮應用到動態規劃中,可以用來精簡狀態,節約空間,也方便轉移。

最常見的就是用二進制來表是狀態,利用各種位移運算,就可以實現O(1)的轉移。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445465.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445465.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445465.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c++基礎學習(06)--(時間,輸入輸出,數據結構)

文章目錄目錄1.時間2.輸入輸出數據結構目錄 1.時間 當前日期和時間 下面的實例獲取當前系統的日期和時間&#xff0c;包括本地時間和協調世界時&#xff08;UTC&#xff09;。 #include <iostream> #include <ctime>using namespace std;int main( ) {// 基于當前…

Abstract Self-Balancing Binary Search Tree

二叉搜索樹 二叉查找樹&#xff08;Binary Search Tree&#xff09;&#xff0c;&#xff08;又&#xff1a;二叉搜索樹&#xff0c;二叉排序樹&#xff09;它或者是一棵空樹&#xff0c;或者是具有下列性質的二叉樹&#xff1a; 若它的左子樹不空&#xff0c;則左子樹上所有結…

AVL Tree

前言 希望讀者 了解二叉搜索樹 了解左旋右旋基本操作 https://blog.csdn.net/hebtu666/article/details/84992363 直觀感受直接到文章底部&#xff0c;有正確的調整策略動畫&#xff0c;自行操作。 二叉搜索樹 二叉查找樹&#xff08;Binary Search Tree&#xff09;&a…

c++基礎學習(07)--(類)

文章目錄目錄類與對象1.類成員函數2.類訪問修飾符3.構造函數與析構函數4.拷貝構造函數5. 友元函數6.內聯函數7.this指針8.指向類的指針9.類的靜態成員目錄 類與對象 #include <iostream>using namespace std;class Box {public:double length; // 長度double breadth;…

【大總結1】數據結構與傳統算法總結

由于時間和水平有限&#xff0c;肯定有錯誤或者寫得不好的地方 歡迎在文章下評論指出。 涉及語言&#xff1a; py3&#xff1a;注重算法本身的知識 c/c&#xff1a;實現基礎數據結構和算法 java&#xff1a;實現較復雜數據結構 一、概述 c語言知識體系 算法體系參考 課上筆…

c++基礎學習(08)--(繼承、重載、多態、虛函數)

文章目錄目錄1.繼承2.重載3.多態 && 虛函數目錄 1.繼承 #include <iostream>using namespace std;// 基類 class Shape {public:void setWidth(int w){width w;}void setHeight(int h){height h;}protected:int width;int height; };// 派生類 class Rectang…

圖的應用

1. 圖的應用總覽 在數據結構中圖的應用很廣泛&#xff0c;本文主要從以下四個方面介紹&#xff1a; ①最小生成樹&#xff1a;給定一個無向網絡&#xff0c;在該網的所有生成樹中&#xff0c;使得各邊權數之和最小的那棵生成樹稱為該網的最小生成樹&#xff0c;也叫最小代價…

c++基礎學習(09)--(數據抽象、數據封裝、接口)

文章目錄目錄1.數據抽象2.數據封裝3.抽象接口類目錄 1.數據抽象 數據抽象&#xff1a;就是把它當做黑箱子使用&#xff0c;內部實現與外部接口分開 C類實現數據抽象&#xff0c;如sort()函數&#xff0c;ostream的cout對象 #include <iostream> using namespace std…

吃豆人游戲開發

這個文章怎么突然這么多人看啊。請大家多關注我其他文章啊 html&#xff1a; <html> <head> <meta charset"utf8"> <title>html5 pacman吃豆人游戲代碼</title><style>body{background-color: #292929}*{padding:0;margin:0;}.w…

c++基礎學習(10)--(文件、流、異常處理、動態內存、命名空間)

文章目錄目錄1.文件和流2.異常處理3.動態內存4.命名空間目錄 1.文件和流 注意 文件打開方式中的in和out都是相對于內存&#xff08;計算機&#xff09;而言的&#xff0c;計算機讀取文件&#xff0c;是將數據從磁盤中的文件讀入到內存中&#xff0c;所以用的是in #include &…

數據結構和算法(02)---字符串(c++)

文章目錄目錄一.c風格的字符串與操作函數1.c風格字符串2.c風格字符串處理函數二.c中的字符串與操作函數1.c中的string類2.string類的基本操作3.string類的操作匯總目錄 數據結構&#xff1a; 邏輯結構&#xff1a;數組&#xff0c;棧&#xff0c;隊列&#xff0c;字符串&#x…

如何學習數據結構和算法——大佬文章匯總

第一篇 第二篇、 作者&#xff1a;左程云 我分別說一下國內和國外的行情。 國內的話&#xff0c;一般來講&#xff0c;工資高的公司在面試時算法和數據結構題目的比重較大&#xff0c;工資一般的公司比重較小。當然同樣公司的不同崗位&#xff0c;要求也會不同&#xff0c;…

c++基礎學習(13)--(STL、標準庫)

文章目錄目錄1. STL教程2.標準庫3.有用的資源目錄 1. STL教程 #include <iostream> #include <vector> using namespace std;int main() {// 創建一個向量存儲 intvector<int> vec; int i;// 顯示 vec 的原始大小cout << "vector size " &…

哈夫曼實現文件壓縮解壓縮(c語言)

寫一個對文件進行壓縮和解壓縮的程序&#xff0c;功能如下&#xff1a; ① 可以對純英文文檔實現壓縮和解壓&#xff1b; ② 較好的界面程序運行的說明。 介紹哈夫曼&#xff1a; 效率最高的判別樹即為哈夫曼樹 在計算機數據處理中&#xff0c;霍夫曼編碼使用變長編碼表對源…

c++基礎學習(11)--(模板、預處理器、信號處理)

文章目錄目錄1.模板2.預處理器3.信號處理目錄 1.模板 模板是泛型編程的基礎&#xff0c;泛型編程&#xff1a;以一種獨立于任何特定類型的方式 #include <iostream> #include <string>using namespace std;template <typename T> inline T const& Max…

java 面向對象必懂概述

&#xff08;這是大體框架&#xff0c;以后部分知識細寫&#xff09; 1 抽象過程 所有編程語言都提供抽象機制。可以認為&#xff0c;人們能解決的問題的復雜性直接取決于抽象的類型和質量。 類型&#xff1a;指的是所抽象的是什么。 匯編語言是對底層機器語言的輕微抽象…

c++基礎學習(12)--(多線程、Web編程)

文章目錄目錄1.多線程2.web編程目錄 1.多線程 #include <iostream> // 必須的頭文件 #include <pthread.h>using namespace std;#define NUM_THREADS 5// 線程的運行函數 void* say_hello(void* args) {cout << "Hello Runoob&#xff01;" <&…

《Head First設計模式》第九章(1)迭代器模式

迭代器模式 因為這一章涉及到兩個模式&#xff0c;內容有點多&#xff0c;還有一個組合模式留到下一篇寫吧。 有許多種方法可以把對象堆起來成為一個集合&#xff08;collection&#xff09;。你可以把它們放進數組、堆棧、列表或者是散列表&#xff08;Hashtable&#xff09…

Java內存模型常見問題

1.什么是內存模型&#xff1f; 在多核系統中&#xff0c;處理器一般有一層或者多層的緩存&#xff0c;這些的緩存通過加速數據訪問&#xff08;因為數據距離處理器更近&#xff09;和降低共享內存在總線上的通訊&#xff08;因為本地緩存能夠滿足許多內存操作&#xff09;來提高…

數據結構和算法(03)---棧和隊列(c++)

文章目錄目錄一.棧1.棧的基本操作2.使用C模板類實現棧二.隊列1.隊列的基本操作2.循環隊列**循環隊列順序存儲****循環隊列鏈式存儲**3.雙端隊列目錄 數據結構&#xff1a; 邏輯結構&#xff1a;數組&#xff0c;棧&#xff0c;隊列&#xff0c;字符串&#xff0c;樹&#xff0c…