回溯法演算法思想解決最小機器重量設計問題
簡單理解回溯法
最小機器重量問題處理
一、回溯法
1.基本概念:
(1)回溯法
回溯演算法是一種選優搜尋法,按選優條件向前搜尋,以達到目標。簡單的說是在搜尋過程中尋找問題的解,當發現已不滿足求解條件時,就回溯返回,嘗試別的路徑。
當探索到某一步時,發現原先選擇不是目前的最優解或不滿足問題條件時,就退回一步重新選擇,並減去當前步驟的節點對應的值,這種方法為回溯法。
(2)剪枝函式:
一般回溯法會走剪枝函式,因為你回溯了,已經走了這個步驟,走過處理的邏輯,當前節點的資料存在參與計算。你退回上一步,則需要減去當前步驟的資料是吧。編寫去除這些節點資料的函式就是剪枝函式。
2.回溯法解題步驟
(1)針對所給問題,確定問題的解空間: 首先應明確定義問題的解空間,問題的解空間應至少包含問題的一個(最優)解。
(2)確定結點的擴充套件搜尋規則
(3)以深度優先方式搜尋解空間,並在搜尋過程中用剪枝函式避免無效搜尋。
二、最小機器重量設計問題
1.問題描述
設某一機器由n個部件組成,每一種部件都可以從m個不同的供應商處購得。設 wij 是從供應商j處購得的部件 i 的重量, cij 是相應的價格。試設計一個演算法,給出總價格不超過 c 的最小重量機器設計。
2.問題分析
初始化供應商數量及部件數量,然後初始化部件的一些屬性作為測試資料。程式關鍵點是中間變數的總價值sumprice取較小的那個,總重量sumWeight與最小重量c的比對是否達到最小,最優。
問題是求所選購部件的總價格sumprice不超過c (sumprice < c) 的最小機器重量min{sumweight1, sumweight2} 。這裡採用的是窮舉法計算所有的組合情況下的總重量及總價值,同時判斷總價格不超過c的情況下,比對最小總重量與當前總重量,取較小的一個。
說明:
宣告變數總重量sumweight為0,初始化第一個最小總重量sumweight為第一個部件在第一家供應商的重量。
宣告變數總價格sumprice為0,初始化第一個總價格sumprice為第一個部件在第一家供應商的重量。
注意:
前提是機器由n個部件構成,所以注意要求的部件個數是確定的。
3.程式碼實現
package common.test;
/**
* 1.最小重量機器設計問題:
* 設某一機器由n個部件組成,每一種部件都可以從m個不同的供應商處購得。
* 設 wij 是從供應商j處購得的部件 i 的重量, cij 是相應的價格。
* 2.試設計一個演算法,給出總價格不超過 c 的最小重量機器設計。
* @author niaonao
*
*/
public class MinWeightMachine {
//宣告相關變數
private static int partweight[][] = new int[110][110];//存放部件重量的陣列
private static int partprice[][] = new int[110][110];//存放部件價格的陣列
private static int n_part; //部件
private static int m_supplier; //供應商
private static int C_totalprice; //總價格
private static int answer; //最後的最小重量
private static int sumprice; //當前部件的總價值
private static int sumWeight; //當前部件的總質量
public static void main(String[] args) {
answer = Integer.MAX_VALUE; //初始化最總結果
C_totalprice = 11; //初始化總價格
sumprice = 0;sumWeight = 0;
n_part = 2;m_supplier = 2;//初始化供應商及部件
partweight[1][1] = 5;partweight[1][2] = 4;partweight[2][1] = 5;partweight[2][2] = 3;
partprice[1][1] = 3;partprice[1][2] = 10;partprice[2][1] = 6;partprice[2][2] = 8;
int i = 1;
minWeight(i);
System.out.println("滿足總價格不超過 " + C_totalprice + " 的最小重量為 " + answer);
}
private static void minWeight(int i)
{
if(i == n_part + 1){
answer =
answer > sumWeight ? sumWeight : answer;
System.out.println("此時總價格:"+sumprice + "\n此時總質量:"+sumWeight);
return ;
}
for(int j = 1; j <= m_supplier; j++){
sumprice = sumprice + partprice[i][j];
sumWeight = sumWeight + partweight[i][j];
if(sumprice > C_totalprice || sumWeight > answer){
continue;
}
minWeight(i + 1); //計算當前值總重量,總價值
sumprice = sumprice - partprice[i][j];
sumWeight = sumWeight - partweight[i][j];
}
}
}