常用演算法設計方法之迭代法
一、迭代法
迭代法是用於求方程或方程組近似根的一種常用的演算法設計方法。設方程為f(x)=0,用某種數學方法匯出等價的形式x=g(x),然後按以下步驟執行:
(1) 選乙個方程的近似根,賦給變數x0;
(2) 將x0的值儲存於變數x1,然後計算g(x1),並將結果存於變數x0;
(3) 當x0與x1的差的絕對值還小於指定的精度要求時,重複步驟(2)的計算。
若方程有根,並且用上述方法計算出來的近似根序列收斂,則按上述方法求得的x0就認為是方程的根。上述演算法用c程式的形式表示為:
【演算法】迭代法求方程的根
while ( fabs(x0-x1)>epsilon);
printf(「方程的近似根是%f/n」,x0);
} 迭代演算法也常用於求方程組的根,令
x=(x0,x1,…,xn-1)
設方程組為:
xi=gi(x) (i=0,1,…,n-1)
則求方程組根的迭代演算法可描述如下:
【演算法】迭代法求方程組的根
while (delta>epsilon);
for (i=0;i貪婪法是一種不追求最優解,只希望得到較為滿意解的方法。貪婪法一般可以快速得到滿意的解,因為它省去了為找最優解要窮盡所有可能而必須耗費的大量時間。貪婪法常以當前情況為基礎作最優選擇,而不考慮各種可能的整體情況,所以貪婪法不要回溯。
例如平時購物找錢時,為使找回的零錢的硬幣數最少,不考慮找零錢的所有各種發表方案,而是從最大面值的幣種開始,按遞減的順序考慮各幣種,先盡量用大面值的幣種,當不足大面值幣種的金額時才去考慮下一種較小面值的幣種。這就是在使用貪婪法。這種方法在這裡總是最優,是因為銀行對其發行的硬幣種類和硬幣面值的巧妙安排。如只有面值分別為1、5和11單位的硬幣,而希望找回總額為15單位的硬幣。按貪婪演算法,應找1個11單位面值的硬幣和4個1單位面值的硬幣,共找回5個硬幣。但最優的解應是3個5單位面值的硬幣。
【問題】 裝箱問題
問題描述:裝箱問題可簡述如下:設有編號為0、1、…、n-1的n種物品,體積分別為v0、v1、…、vn-1。將這n種物品裝到容量都為v的若干箱子裡。約定這n種物品的體積均不超過v,即對於0≤i<n,有0<vi≤v。不同的裝箱方案所需要的箱子數目可能不同。裝箱問題要求使裝盡這n種物品的箱子數要少。
若考察將n種物品的集合分劃成n個或小於n個物品的所有子集,最優解就可以找到。但所有可能劃分的總數太大。對適當大的n,找出所有可能的劃分要花費的時間是無法承受的。為此,對裝箱問題採用非常簡單的近似演算法,即貪婪法。該演算法依次將物品放到它第乙個能放進去的箱子中,該演算法雖不能保證找到最優解,但還是能找到非常好的解。不失一般性,設n件物品的體積是按從大到小排好序的,即有v0≥v1≥…≥vn-1。如不滿足上述要求,只要先對這n件物品按它們的體積從大到小排序,然後按排序結果對物品重新編號即可。裝箱演算法簡單描述如下:
ele;
typedef struct hnode
hnode;
void main()
else j->remainder-=a;
for (q=j->next;q!=null&&q->link!=null;q=q->link);
if (q==null)
else }
printf(「共使用了%d只箱子」,box_count);
printf(「各箱子裝物品情況如下:」);
for (j=box_h,i=1;j!=null;j=j->next,i++) }
【問題】 馬的遍歷
問題描述:在8×8方格的棋盤上,從任意指定的方格出發,為馬尋找一條走遍棋盤每一格並且只經過一次的一條路徑。
馬在某個方格,可以在一步內到達的不同位置最多有8個,如圖所示。如用二維陣列board[ ][ ]表示棋盤,其元素記錄馬經過該位置時的步驟號。另對馬的8種可能走法(稱為著法)設定乙個順序,如當前位置在棋盤的(i,j)方格,下乙個可能的位置依次為(i+2,j+1)、(i+1,j+2)、(i-1,j+2)、(i-2,j+1)、(i-2,j-1)、(i-1,j-2)、(i+1,j-2)、(i+2,j-1),實際可以走的位置盡限於還未走過的和不越出邊界的那些位置。為便於程式的同意處理,可以引入兩個陣列,分別儲存各種可能走法對當前位置的縱橫增量。
4 3
5 2
馬
6 1
7 0
對於本題,一般可以採用回溯法,這裡採用warnsdoff策略求解,這也是一種貪婪法,其選擇下一出口的貪婪標準是在那些允許走的位置中,選擇出口最少的那個位置。如馬的當前位置(i,j)只有三個出口,他們是位置(i+2,j+1)、(i-2,j+1)和(i-1,j-2),如分別走到這些位置,這三個位置又分別會有不同的出口,假定這三個位置的出口個數分別為4、2、3,則程式就選擇讓馬走向(i-2,j+1)位置。
由於程式採用的是一種貪婪法,整個找解過程是一直向前,沒有回溯,所以能非常快地找到解。但是,對於某些開始位置,實際上有解,而該演算法不能找到解。對於找不到解的情況,程式只要改變8種可能出口的選擇順序,就能找到解。改變出口選擇順序,就是改變有相同出口時的選擇標準。以下程式考慮到這種情況,引入變數start,用於控制8種可能著法的選擇順序。開始時為0,當不能找到解時,就讓start增1,重新找解。細節以下程式。
【程式】
# include
int delta_i[ ]=;
int delta_j[ ]=;
int board[8][8];
int exitn(int i,int j,int s,int a[ ])
return count;
}int next(int i,int j,int s)
if (step>64) break;
start++;
} while(step<=64)
for (i=0;i<8;i++)
scanf(「%*c」); } }
常用演算法設計方法之迭代法
迭代法是用於求方程或方程組近似根的一種常用的演算法設計方法。設方程為 f x 0 用某種數學方法匯出等價的形式 x g x 然後按以下步驟執行 1 選乙個方程的近似根,賦給變數x0 2 將x0 的值儲存於變數 x1,然後計算 g x1 並將結果存於變數x0 3 當x0與x1 的差的絕對值還小於指定的...
MATLAB之牛頓迭代法
1 迭代公式 將 f x 在點xk做taylor展開f x f xk f xk x xk 則有 x k 1 x k f x k f x k 2 牛頓法的幾何意義 由上式可知,如果如果我們選擇x0作為初始點,點 x0,f x0 的切線方程為y f x0 f x0 x x0 該切線方程與x軸交點的橫座標...
常用演算法設計方法 一 迭代法
迭代法是用於求方程或方程組近似根的一種常用的演算法設計方法。設方程為f x 0,用某種數學方法匯出等價的形式x g x 然後按以下步驟執行 1 選乙個方程的近似根,賦給變數x0 2 將x0的值儲存於變數x1,然後計算g x1 並將結果存於變數x0 3 當x0與x1的差的絕對值還小於指定的精度要求時,...