1. 程式人生 > >回溯法演算法思想解決最小機器重量設計問題

回溯法演算法思想解決最小機器重量設計問題

開門見山

簡單理解回溯法

最小機器重量問題處理

一、回溯法

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];
	    }
	    
	}

}

4.執行結果