物资配送路径问题(一)
???????? 這篇文章是一個研究生數模的作業,研究了一下感覺挺有意思的,所以準備拿來好好研究一下,借此寫幾篇博文,記載。
?----20140605
???????? 首先,這里第一篇我會基于該題目本身來進行基本的設計和研究。參考過一兩篇所謂答案,感覺看上去不知所云,希望我能用最簡單的語言成功描述這個問題。下面是這個題目:
???????? 某物流中心擁有一支貨運車隊,每臺貨運車輛的載重量(噸)相同、平均速度(千米/小時)相同,該物流中心用這樣的車為若干個客戶配送物資,物流中心與客戶以及客戶與客戶之間的公路里程(千米)為已知。每天,各客戶所需物資的重量(噸)均已知,并且每個客戶所需物資的重量都小于一臺貨運車輛的載重量,所有送貨車輛都從物流中心出發,最后回到物流中心。物流中心每天的配送方案應當包括:當天出動多少臺車?行駛路徑如何?由此形成的當天總運行里程是多少?一個合格的配送方案要求送貨車輛必須在一定的時間范圍內到達客戶處,早到達將產生等待損失,遲到達將予以一定的懲罰;而一個好的配送方案還應該給出使配送費用最小或總運行里程最短的車輛調度方案。
〔算例〕載重量為 8 噸、平均速度為 50千米/小時 的送貨車輛從物流中心(0)出發,為編號是 1,2,…,8 的8個客戶配送物資。某日,第個客戶所需物資的重量為噸(),在第個客戶處卸貨時間為小時,第個客戶要求送貨車輛到達的時間范圍 ?由表1給出。物流中心與各客戶以及各客戶間的公路里程(單位:千米)由表2給出。問當日如何安排送貨車輛(包括出動車輛的臺數以及每一臺車輛的具體行駛路徑)才能使總運行里程最短。
表1 ??物資配送任務及其要求
| 客戶 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| (噸) | 2 | 1.5 | 4.5 | 3 | 1.5 | 4 | 2.5 | 3 |
| (小時) | 1 | 2 | 1 | 3 | 2 | 2.5 | 3 | 0.8 |
| [1, 4] | [4, 6] | [1, 2] | [4, 7] | [3, 5.5] | [2, 5] | [5, 8] | [1.5, 4] |
表2?? 點對之間的公路里程(千米)
| ? ? | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 0 | 0 | 40 | 60 | 75 | 90 | 200 | 100 | 160 | 80 |
| 1 | 40 | 0 | 65 | 40 | 100 | 50 | 75 | 110 | 100 |
| 2 | 60 | 65 | 0 | 75 | 100 | 100 | 75 | 75 | 75 |
| 3 | 75 | 40 | 75 | 0 | 100 | 50 | 90 | 90 | 150 |
| 4 | 90 | 100 | 100 | 100 | 0 | 100 | 75 | 75 | 100 |
| 5 | 200 | 50 | 100 | 50 | 100 | 0 | 70 | 90 | 75 |
| 6 | 100 | 75 | 75 | 90 | 75 | 70 | 0 | 70 | 100 |
| 7 | 160 | 110 | 75 | 90 | 75 | 90 | 70 | 0 | 100 |
| 8 | 80 | 100 | 75 | 150 | 100 | 75 | 100 | 100 | 0 |
??????? 很顯然這是一個基于最短路徑的問題。
??????? 在第一步,顯然應該獲得關于所有節點之間的最短路徑矩陣。最初我根據網上的若干文章選擇使用了Dijkstra算法以獲得關于物流中心,也就是0節點的最短路徑數組。當然針對算例也能得到不錯的配送方案,但是對于比較復雜的路線肯定無法滿足需要,因此我還是重選了Floyd算法來處理這個問題(另一個原因是因為這個算法更好寫)。這里我把兩個算法寫成的java函數放到下面
//Floyd算法,返回一個類,這個類包含兩個二維數組 public Result floyd(int[][] g) {int n = g.length;int[][] dis = new int[n][n];//距離矩陣int[][] path = new int[n][n];//path矩陣for (int q = 0; q < n; q++) {for (int w = 0; w < n; w++) {dis[q][w] = g[q][w];path[q][w] = -1;}}//數組初始化完成for (int k = 0; k < n; k++) {for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (dis[i][j] > dis[i][k] + dis[k][j]) {dis[i][j] = dis[i][k] + dis[k][j];path[i][j] = k;}}}}Result rs = new Result();rs.dis = dis;rs.path = path;return rs;} //每次只會計算start這一行,結果包含兩個二維數組和一個數組 public Result dijsktra(int[][] weight, int start) {// 接受一個有向圖的權重矩陣,和一個起點編號start(從0編號,頂點存在數組中)// 返回一個int[] 數組,表示從start到它的最短路徑長度int n = weight.length; // 頂點個數int[] shortPath = new int[n]; // 存放從start到其他各點的最短路徑int[] visited = new int[n]; // 標記當前該頂點的最短路徑是否已經求出,1表示已求出int[] pathM = new int[n];for (int i = 0; i < pathM.length; i++) {pathM[i]= -1;}Result rs = new Result();// 初始化,第一個頂點求出shortPath[start] = 0;visited[start] = 1;for (int count = 1; count <= n - 1; count++) // 要加入n-1個頂點{int k = -1; // 選出一個距離初始頂點start最近的未標記頂點int dmin = 1000;for (int i = 0; i < n; i++) {if (visited[i] == 0 && weight[start][i] < dmin) {dmin = weight[start][i];k = i;}}// 將新選出的頂點標記為已求出最短路徑,且到start的最短路徑就是dminshortPath[k] = dmin;visited[k] = 1;// 以k為中間點想,修正從start到未訪問各點的距離for (int i = 0; i < n; i++) {if (visited[i] == 0&& weight[start][k] + weight[k][i] < weight[start][i]) {weight[start][i] = weight[start][k] + weight[k][i];pathM[i] = k;}}}rs.pathM = pathM;//path矩陣rs.dist = shortPath;//改行的dist數組rs.resultM = weight;//修改過start行的距離矩陣return rs;}??????? 得到基礎的兩個矩陣之后。第一步就算是結束了。
??????? 但是接下來選擇多少運送車輛和每輛車的運送路徑就成了關鍵的問題。
??????? 1.根據車輛載重構造可能的運送線路集合;
??????? 2.根據最短線路規則制定行車線路;
??????? 3.根據時間規則,構造可能的節點順序。
??????? 想到這里,問題似乎就陷入了死胡同,首先,三個條件的交叉點不一定存在。第二,沒有一個條件可以作為評分標準。第三,用程序寫這個就更不好寫了。
??????? 既然一次性搞定有問題,那么就一步步來把。
???????
總結
以上是生活随笔為你收集整理的物资配送路径问题(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android之仿IOS悬浮窗
- 下一篇: 右值引用及其作用