裝載問題(回朔法)


一、回朔法

首先來介紹一下回朔法:

(1)基本思想:把問題的解空間轉化成了圖或者樹的結構表示,然后使用深度優先搜索策略進行遍歷,遍歷的過程中記錄和尋找所有可行解或者最優解。

(2)主要步驟:a、求解出所有解所在的解空間;b、構造相應的樹等數據結構來表示解空間;c、使用深度優先搜索在樹中搜索所有最優解(同時結合剪枝函數提高搜索效率);

(3)應用:當問題是求解滿足某某約束條件的最優解或者是所有解的時候,可以使用回朔法,它具有“通用解題法”的美譽;

(4)實現:同時使用遞歸和非遞歸方式實現,其中遞歸方式設計簡單但是效率較低,而非遞歸設計較為復雜但是效率高;

使用到的樹狀結構主要有如下兩類:子集樹排列樹

注意:回溯法與DFS的區別:回溯法不會保留完整的樹結構,但DFS會保留完整的樹結構搜索樹。

二、裝載問題

問題描述:
有一批共n 個集裝箱要裝上艘載重量為c 的輪船,其中集裝箱i 的重量為wi。找出一種最優裝載方案,將輪船盡可能裝滿,即在裝載體積不受限制的情況下,將盡可能重的集裝箱裝上輪船。

代碼如下:

//load.h
#ifndef LOAD_H
#define LOAD_H #include "load.template" #endif

 

//load.template
template <class Type> class Loading { friend Type Maxloading(Type[], Type, int, int[]); private: void Backtrack(int i); int n, //集裝箱數 *x, //當前解 *bestx; //當前最優解 Type *w, //集裝箱重量數組 c, //第一艘輪船的在載重量 cw, //當前載重量 bestw, //當前最優裝載重量 r; //剩余集裝箱重量 }; template <class Type> void Loading<Type> ::Backtrack(int i) { //搜索第i層節點 if (i > n) //到達葉節點 { if (cw > bestw) { for (int j = 1; j <= n; j++) bestx[j] = x[j]; bestw = cw; } return; } //搜索子樹 r -= w[i]; if (cw + w[i] <= c) //搜索左子樹 { x[i] = 1; cw += w[i]; Backtrack(i + 1); cw -= w[i]; } if (cw + r > bestw) //搜索右子樹 { x[i] = 0; Backtrack(i + 1); } r += w[i]; //回溯 } template <class Type> Type Maxloading(Type w[], Type c, int n, int bestx[]) { //返回最優載重量 Loading <Type> X; //初始化X X.x = new int[n + 1]; X.w = w; X.c = c; X.n = n; X.bestx = bestx; X.bestw = 0; X.cw = 0; //初始化r X.r = 0; for (int i = 1; i <= n; i++) { X.r += w[i]; } X.Backtrack(1); delete[] X.x; return X.bestw; }

 

//2018_04_28
//使用回朔法解決裝載問題
//main.cpp
//============================================================================= #include <iostream> #include "load.h" using namespace std; int main(void) { int n = 0; //集裝箱數量; int c = 0; //第一艘船的載重重量 int bestx[4]; //最優解 int *w = new int[n + 1]; //集裝箱重量數組 int m = 0; //最優載重量 cout << "請輸入集裝箱數量: "; cin >> n; cout << endl; cout << "請輸入第一艘船的載重重量: "; cin >> c; cout << endl; cout << "請輸入集裝箱的重量數組 :"; for (int i = 0; i <= n; i++) { cin >> w[i]; } m = Maxloading(w, c, n, bestx); //求解問題 cout << "輸出最優解如下:" << endl; for (int i = 1; i < n; i++) { cout << bestx[i] << " "; } cout << "請輸出最優載重量: " << endl; cout << m; system("pause"); return 0; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM