演算法分析
給定n
中物品和乙個容量為
c的揹包,物品
i的重量為
wi,其價值為
vi,揹包問題是如何選擇裝入揹包的物品(物品不可分割),使得裝入揹包的物品的價值為最大
,考慮到每種物品只有2
種選擇,即裝入揹包或不裝入揹包,並且物品數和揹包容量已給定,要計算裝入揹包物品的最大價值和最優裝入方案,可用回溯法搜尋子集樹的演算法進行求解
一
物品有n
種,揹包容量為
c,分別用
p[i]
和w[i]
儲存第i
種物品的價值和重量,用
x[i]標記第
i種物品是否裝入揹包,用
bestx[i]
儲存第i
種物品的最優裝載方案;
二. 用遞迴函式
backtrack (i,cp,cw)
來實現回溯法搜尋子集樹(形式引數
i表示遞迴深
度,n用來控制遞迴深度,形式引數cp和
cw表示當前總價值和總重量,
bestp
表示當前
最優總價值):
① 若i >n
,則演算法搜尋到乙個葉結點,判斷當前總價值是否最優:
1> 若
cp>bestp
,更新當前最優總價值為當前總價值(即
bestp=cp
),更新
裝載方案(即bestx[i]=x[i]( 1≤i
≤n));② 採用for
迴圈對物品
i裝與不裝兩種情況進行討論(0≤
j≤1):
1> x[i]=j;
2> 若總重量不大於揹包容量(即
cw+x[i]*w[i]<=c
),則更新當前總價
br="">
值和總重量(即
cw+=w[i]*x[i],cp+=p[i]*x[i]),
對物品i+1
呼叫遞迴函
數backtrack(i+1,cp,cw)
繼續進行裝載;
3> 函式
backtrack(i+1,cp,cw)
呼叫結束後則返回當前總價值和總重量
(即 cw-=w[i]*x[i],cp-=p[i]*x[i]
);4> 當
j>1
時,for
迴圈結束;
③ 當i=1
時,若已測試完所有裝載方案,外層呼叫就全部結束;
三主函式呼叫一次backtrack(1,0,0)
即可完成整個回溯搜尋過程,最終得到的
bestp
和bestx[i]
即為所求最大總價值和最優裝載方案。
.#include
int n,c,bestp;//物品的個數,揹包的容量,最大價值
int p[10000],w[10000],x[10000],bestx[10000];//物品的價值,物品的重量,
x[i]
暫存物品的選中情況
,物品的選中情況
void backtrack(int i,int cp,int cw)
} else
for(j=0;j<=1;j++)
} }
int main()
結果 1.
..輸入皇后個數:1
1 2...請輸入揹包最大容量:15
請輸入物品個數:3
請依次輸入物品的重量:
5 6 4
請依次輸入物品的價值:
7 5 9
最大價值為:21
被選中的物品依次是(0
表示未選中,
1表示選中
1 1 1
小結:回溯法是個好東西, 當自己對乙個問題沒有任何思路的時候就可以用回溯法, 雖然效率是乙個嚴重的問題, 但是卻能給問題乙個形象的解釋, 或者可以從回溯法想到乙個不錯的演算法也不一定
當遇到乙個可以用到回溯法的時候需要按照如下步驟進行:
1. 確定問題的乙個解空間樹, 這個解空間樹至少包含乙個你需要的那個解, 否則這個樹就完全沒有意義了
2. 組織好這棵樹, 弄明白這棵樹的每乙個節點代表什麼, 每乙個分支代表什麼
3. 從這棵樹的根節點不斷的向下深搜, 當遇到不合適的節點的時候直接跳過以這個節點為根的子樹
4. 當搜尋到了葉子節點的時候就回溯
分析
1...
八皇后問題
是十九世紀著名數學家高斯於1850
年提出的。
問題是:在8*8
的棋盤上擺放
8個皇后,使其不能互相攻擊,即任意的兩個皇后不能處在同意行,同一列,或同意斜線上。可以把八皇后問題拓展為
n皇后問題,即在
n*n的棋盤上擺放
n個皇后,使其任意兩個皇后都不能處於同一行、同一列或同一斜線上。
...每一行可以而且必須放乙個皇后,所以n
皇后問題的解可以用乙個
n元向量x=(
x1,x2
,.....x
n)表示,其中,1≤i
≤n且1≤
xi≤n,即第
n個皇后放在第i行第
xi列上。由於兩個皇后不能放在同一列上,所以,解向量x
必須滿足的約束條件為:xi
≠xj;若兩個皇后的擺放位置分別是(
i,xi
)和(j,x
j),在棋盤上斜率為-1
的斜線上,滿足條件
i-j=xi-x
j;在棋盤上斜率為
1的斜線上,滿足條件
i+j=xi+x
j;綜合兩種情況,由於兩個皇后不能位於同一斜線上,所以,解向量
x必須滿足的約束條件為
:|i-xi|
≠|j-xj|
1...#include
#include
int x[100];
bool place(int k)//考察皇后
k放置在
x[k]
列是否發生衝突
void queue(int n)
else if(x[k]<=n&&k
k=k+1;//放置下乙個皇后
else
}
}
void main()
..
八皇后問題(回溯法)
問題描述 八皇后問題是十九世紀著名數學家高斯於1850年提出的。問題是 在8 8的棋盤上擺放8個皇后,使其不能互相攻擊,即任意的兩個皇后不能處在同意行,同一列,或同意斜線上。可以把八皇后問題拓展為n皇后問題,即在n n的棋盤上擺放n個皇后,使其任意兩個皇后都不能處於同一行 同一列或同一斜線上。問題分...
回溯法 八皇后問題
八皇后問題是高斯於1850年提出的,這是乙個典型的回溯演算法的問題。八皇后問題的大意如下 西洋棋的棋盤有8 行 8 列共64個單元格,在棋盤上擺放八個皇后,使其不能互相攻擊,也就 是說任意兩個皇后都不能處於同一行 同一列或同一斜線上。問總共有多少種擺放方法,每一種擺 放方式是怎樣的。首先來分析八皇后...
八皇后問題 回溯法
在8 8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法 就拿四皇后來說吧 我們首先需要建立乙個一維陣列 這個陣列裡存放的就是皇后在該列合適的位置 這個陣列存放的是皇后放的行數,我們首先在第一列中找乙個可以放的地方,很明顯第乙個位置就可以...