回溯演算法經典例子

2021-09-24 20:55:37 字數 3347 閱讀 9400

例如,對於 n=3 的 01-揹包問題,可以用完全二叉樹表示其解空間:

解空間樹的型別

子集樹:當所給問題是從 n 個元素的集合 s 中找出 s 滿足某種性質的子集時,相應的解空間樹稱為子集樹。

void

backtrack

(int t)

}}

排列樹:當所給問題是確定 n 個元素滿足某種性質的排列時,相應的解空間被稱為排列樹。

void

backtrack

(int t)

}}

回溯的過程:回溯法從根節點出發,以深度優先方式搜尋整個解空間。

這個開始節點成為活結點,也成為當前的擴充套件結點。在當前擴充套件結點處,搜尋向縱深方向移至乙個新結點,則這個新結點成為新的活結點,並成為當前的擴充套件結點。

如果當前擴充套件結點不能再移動,則當前擴充套件結點成為死結點,此時應該回溯到最近的活結點處。

直到在解空間中已無活結點則搜尋結束。

解題的步驟:

針對所給問題,定義問題的解空間

確定易於搜尋的解空間結構

以深度優先方式搜尋解空間,並在搜尋過程中用剪枝函式避免無效搜尋

問題:給定 n 個作業的集合 j=,每個作業 ji都有兩項任務分別在兩台機器上完成,每個作業必須先有機器1處理,然後由機器2處理。fji 是作業 i 在機器 j 上完成處理的時間。所有作業在機器2上完成處理的時間和稱為該作業排程的完成時間和,批處理作業排程即給出最優排程使得完成時間和最小。

解題思路:

可以確定解空間是一顆排列樹,設 x=[1,2,…,n] 是所給的 n 個作業,則相應的排列樹由 x[1:n] 的所有排列構成。

**:

public

class

flowshop

bestf = f;

}else}}

}}

問題:由14個「+」號和14個「-」號組成的符號三角形。2個同號下面是「+」號,2個異號下面是「-」號。

在一般情況下,符號三角形第一行有n個符號,該問題要求對於給定n計算有多少種不同的符號三角形。使其所含的+ — 個數相同。

解題思路:

用 x[1:n] 表示符號三角形的第一行的 n 個字元

**:

public

class

********s

}backtrack(1

);return sum;

}private

static

void

backtrack

(int t)

backtrack

(t+1);

for(

int j=

2;j<=t;j++

) count -= i;}}

}}

問題:在n×n格的西洋棋上擺放n個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。

解題思路:

用 x[1:n] 表示 n 後問題的解,x[i] 表示皇后 i 放在棋盤的第 i 行的第 j 列。不同列,則 x[i] 都不相同。斜線上不能相同即,對於兩個皇后(i,j) 和 (k,l),|i-k| =/= |j-l|。

**:

public

class

nqueen

backtrack(1

);return sum;

}private

static

boolean

place

(int k)

return

true;}

private

void

backtrack

(int t)}}

}

在動態規劃中有問題描述以及動態規劃的解題方法,這裡只討論回溯法的解法。

解題思路:

可用子集樹來表示解空間,在搜尋空間樹時,只要其左兒子結點是乙個可行點就進入,而右兒子只有在可能包含最優解時才進入,否則剪枝。

偽**:

static

double c;

//揹包容量

static

int n;

//物品數

static

double

w;//重量

static

double

p;//價值

static

double cw;

//當前重量

static

double cp;

//當前價值

static

double bestp;

//最優價值

private

static

void

backtrack

(int i)

if(cw + w[i]

<= c)if(

bound

(i+1

)>bestp)

//判斷右子樹的價值有沒可能超過左子樹

backtrack

(i+1);

//超過則進入右子樹

}

問題:售貨員要到n個城市去推銷商品,已知各城市之間的路程(代價)a,試選擇一條路,從第乙個城市出發經過每個城市一遍,最後回到出發城市所耗費的代價最小。

解題思路:

分析可知解空間是一棵排列樹,每一條從根節點到達葉子結點的路徑代表了n個頂點的一種排列。定義x[n]記錄可行解。

剪枝函式:兩個城市之間是否連通,到達當前為止的代價是否已經超過了最優代價,當前城市是否已經走過。

貪心演算法經典例子

貪心演算法總是作出在當前看來最好的選擇。也就是說貪心演算法並不從整體最優考慮,它所作出的選擇只是在某種意義上的區域性最優選擇。基本思想 貪心演算法並不從整體最優上加以考慮,它所做的選擇只是在某種意義上的區域性最優解。基本要素 最優子結構性質和貪心選擇性質。和動態規劃區別 動態規劃演算法中,每步所做的...

回溯演算法python 數獨問題 回溯演算法經典例題

之前我們已經簡單地說明了怎樣用回溯演算法解決數獨的問題,思路如下 從第乙個空格開始。依次嘗試 1 到 9 的數字,如果數字與盤面衝突就換成下乙個數字,如果不衝突就去往第二個空格 在第二個空格,同樣依次嘗試 1 到 9 的數字,如果與盤面衝突就換成下乙個數字,如果不衝突就去往第三個空格,以此類推 當最...

演算法 經典演算法

1 匹配演算法 匹配開始,從長的字串開始,匹配成功,長的和短的字串均向後匹配,而匹配失敗,則長的字串從開始的位置向後乙個字元,重新開始匹配,而短的字串則完全從頭開始。匹配演算法 param str1 長匹配字串 param str2 短的匹配字串 return 匹配成功 返回短字串在長字串開始的位置...