全國大學生數學建模競賽 B題 RGV的動態排程策略
智慧RGV的動態排程策略
摘要
本文為RGV的動態排程問題。根據所給資訊使用了DEV、Excel等軟體建立了基於模擬退火演算法的最短路徑模型來對任務進行求解。在第一問的模型的基礎下,通過加入限制條件和改進演算法來解決題目所提出的問題,本文最後還做了誤差分析和模型分析。
對任務一的情況一:首先CNC的工序是一樣的(安裝同樣的刀具),在分析 RGV的動態排程的時候,將其抽象為類似與求解最短路徑的問題。我們選擇使用模擬退火演算法來解決最短路徑問題。以RGV所在的點為座標原點建立座標軸,得到CNC對應的座標。為了使結果更加具有信服力,我們通過程式設計來隨機產生需要進行上下料操作的CNC座標,然後代入演算法進行求解,得到最短路徑。
對任務一的情況二:需要建立的模型相比情況一的模型不同需考慮加工過程中有兩道工序的情況。通過對於題目中給出的每一道加工工序所需要的時間對比分析,我們利用時間序列分析模型來確定每一道工序所對應的CNC的數量,然後同理與情況一來建立對應的模型,來求得最短路徑。
對任務一的情況三:這種情況是在我們所建立的一道工序和兩道工序的數學模型中,要加入對於CNC的損壞概率的考慮。由於CNC發生故障是具有隨機性的,而CNC一旦發生故障,我們就需要所以通過演算法隨機選取故障時間加入模型中來得到結果。
對任務二:根據題目表1中所給的資料,代入任務一的情況一,情況二,情況三所建立的模型中,加入工作時間8小時的約束,來得到所需要的結果。然後對我們所得到的解進行分析,分析模型的實用性和我們所使用的演算法的有效性。
然後將具體的解放入附件的Excel表中,具體見支撐材料。
最後,給出本文模型的優缺點及其評價。
關鍵詞:模擬退火演算法 最短路徑 目標規劃 時間序列
一、 問題重述
圖1是一個智慧加工系統的示意圖,由8臺計算機數控機床(Computer Number Controller,CNC)、1 輛軌道式自動引導車(Rail Guide Vehicle,
RGV)、1條RGV直線軌道、1條上料傳送帶、1條下料傳送帶等附屬裝置組成。 RGV 是一種無人駕駛、能在固定軌道上自由執行的智慧車。它根據指令能自動控制移動方向和距離,並自帶一個機械手臂、兩隻機械手爪和物料清洗槽,能夠完成上下料及清洗物料等作業任務(參見附件1)。
圖1:智慧加工系統示意圖
針對下面的三種具體情況:
- 一道工序的物料加工作業情況,每臺 CNC 安裝同樣的刀具,物料可以在任一臺CNC上加工完成;
- 兩道工序的物料加工作業情況,每個物料的第一和第二道工序分別由兩臺不同的CNC依次加工完成;
- CNC 在加工過程中可能發生故障(據統計:故障的發生概率約為 1%)的情況,每次故障排除(人工處理,未完成的物料報廢)時間介於10~20 分鐘之間,故障排除後即刻加入作業序列。要求分別考慮一道工序和兩道工序的物料加工作業情況。
請你們團隊完成下列兩項任務:任務1:對一般問題進行研究,給出RGV動態排程模型和相應的求解演算法;任務2:利用表1中系統作業引數的3組資料分別檢驗模型的實用性和演算法的有效性,給出RGV的排程策略和系統的作業效率,並將具體的結果分別填入附件2的EXCEL表中。
表1:智慧加工系統作業引數的3組資料表 時間單位:秒
系統作業引數 |
第1組 |
第2組 |
第3組 |
RGV移動1個單位所需時間 |
20 |
23 |
18 |
RGV移動2個單位所需時間 |
33 |
41 |
32 |
RGV移動3個單位所需時間 |
46 |
59 |
46 |
CNC加工完成一個一道工序的物料所需時間 |
560 |
580 |
545 |
CNC 加工完成一個兩道工序物料的第一道工序所需時間 |
400 |
280 |
455 |
CNC 加工完成一個兩道工序物料的第二道工序所需時間 |
378 |
500 |
182 |
RGV為CNC1#,3#,5#,7#一次上下料所需時間 |
28 |
30 |
27 |
RGV為CNC2#,4#,6#,8#一次上下料所需時間 |
31 |
35 |
32 |
RGV完成一個物料的清洗作業所需時間 |
25 |
30 |
25 |
注:每班次連續作業8小時。
二、問題分析
2.1 問題的總分析
本文要求我們分析RGV的動態排程問題,在題目所給的條件下如何排程
RGV才可以達到執行時間的最優解。我們要分別對題目中所提到的各種情況進行分析,以此建立數學模型。由於題目所給的各種情況都是在第一種的情況下遞進的,所以我們首先對第一種情況進行建模(一道工序的物料加工作業情況,每臺 CNC安裝同樣的刀具,物料可以在任一臺CNC上加工完成)。然後在情況一的基礎上考慮故障概率以及兩道工序的情況,來建立相應的模型。對於任務二,我們使用第一問所建立的數學模型,加入題目中的約束條件,來得到需要的資料。
2.2 具體問題分析
2.2.1 任務一的情況一的分析
任務一要求我們建立對應的RGV的動態排程模型和求解演算法,情況一是在單一工序加工的條件下。通過了解題目中所給出的RGV的執行模式,我們將RGV的執行模式抽象成一個尋找最短路徑的問題,類似於TSP問題。然後根據題目建立座標軸,將RGV所在的位置看作座標原點,將剩餘的CNC的位置用座標出來,為了更貼近現實情況,我們通過程式設計,來隨機產生指定位置的CNC發出需求訊號,然後我們使用模擬退火演算法,模擬RGV執行的過程,通過演算法不斷的優化路徑,得到RGV動態排程的最短路徑。目的在於尋求RGV最短的移動時間,提高RGV的工作效率。座標軸如圖2:
RGV 1 3 5 7
2 4 6 8 圖 2
(因為CNC分佈的原因,RGV可以在同一位置操作兩邊的CNC,所以我們將其看作一個點,只是分佈在兩邊而已)
2.2.2 任務一的情況二的分析
任務一的情況二要求我們考慮的是在有兩道加工工序的情況下的RGV的動態排程模型,從題目中所給的資料我們可以看出兩道加工工序的加工好零件所需要的時間是不同的,通過參考了時間序列分析模型,我們通過對第一道工序和第二道工序的時間比例的計算,以及CNC處於奇偶位置的上下料時間的不同,來確定在8個CNC中第一道工序和第二道工序所對應的CNC位置和所佔的個數,得到了不同的工序所佔的CNC的個數之後,我們同樣使用情況一的方法,將RGV所在的地方看成一條座標軸,通過改進第一問的模型以及演算法來求解。
2.2.3 任務一的情況三的分析
任務一的情況三的要求的是我們在情況一和情況二建立的模型下,再加入一個限制條件,就是要考慮一種更加貼近現實生活的情況,我們需要考慮CNC在執行過程中會因為道具的磨損出現故障的概率,而CNC的修理時間是比較長的(10-20分鐘),所以我們將每次CNC發生故障並修理的過程,看作一次機器的重啟,我們使用了隨機性模擬的方法,將CNC發生故障的情況加入,每次故障之後,都重啟一次演算法,來達到最優解。
2.2.4 任務二的分析
任務二的題目要求就是對任務一對於各種情況所建立的模型的檢驗,檢驗模型的實用性和演算法的有效性。並計算系統的作業效率,我們認為系綜的作業效率就是總時間與系統加工時間的比例,我們將題目要求的限制條件加入我們任務一所建立的模型中,然後對演算法進行改進,對不同的加工序列進行計算,得到題目所需要的資料結果。
三、符號說明
N—— 報廢的工件數
Mi —— 第i臺機器CNC的工件數 , 其中(i=1 ,2 ,3…8)
T —— RGV工作的總的時間
Tn —— RGV的移動時間(n=1,2,3)
Taj——表示RGV的等待時間(j=1,2,3,…,n)
P——RGV的工作效率
四、模型假設
基於題目和附件1的智慧加工系統的組成與作業流程所給資訊量,對本文所建模型作了如下幾點合理假設:
- RGV執行過程中忽略摩擦力等外力的影響。
- 不考慮RGV會發生故障。
- 不考慮在傳送帶上消耗的時間。
- 不考慮RGV機械臂擺動的時間。
- 所有的CNC初始狀態都是空閒狀態。
- RGV移動單位時間是設定的。
- 除故障外,物料加工的過程中是不中斷的。
五、模型建立與求解
5.1 任務一的情況一的模型建立
情況一隻考慮單獨一種工序的加工情況,考慮到一道工序的加工情況下,我們將RGV的移動抽象成一個求RGV移動的最短路徑的問題。,然後對RGV的移動軌跡進行分析。
設RGV所在地點為座標原點,CNC的位置也對應為座標軸上對應的點,如圖
3所示:
RGV 1 3 5 7
2 4 6 8
圖 3
求解RGV的最短路徑問題可以說是一個組合優化的過程,通過組合優化與物理退火的相似性比較,我們選擇了模擬退火演算法來解決該問題。相似性比較見下表2:
組合優化問題 |
金屬物體 |
解 |
粒子狀態 |
最優解 |
能量最低的狀態 |
設定初溫 |
溶解過程 |
Metropolis抽樣過程 |
等溫過程 |
控制引數的下降 |
冷卻 |
目標函式 |
能量 |
表2
通過模擬退火演算法來計算RGV的最短路徑,衡量路徑最短所使用的量是時間,移動時間的目標函式Z1如下:
T1 (移動一個單位距離所需要的時間) Tn T2 (移動兩個單位距離所需要的時間)
T3 (移動三個單位距離所需要的時間)
Z1 = min∑Tn (n=1,2,3)
目標函式建立好之後,因為理論上模擬退火演算法具有概率的全域性優化功能,所以我們選擇了模擬退火演算法(Simulated Annealing, SA),模擬退火演算法是基於Monte-Carlo迭代求解策略的一種隨機尋找演算法,該演算法的出發點是基於物理中固體物質的退火過程與一般組合優化過程之間的相似性。模擬退火演算法從某一較高初溫出發,伴隨溫度引數的不斷下降,結合概率突跳特性在解空間中隨機尋找目標函式的全域性最優解,即在區域性最優解能概率性的跳出並最終趨於全域性最優。
模擬退火演算法的基本步驟如圖4所示:
圖 4
在選好了演算法之後,為了使得所建立得模型更加符合實際中出現的情況,我們通過程式設計來隨機產生髮出訊號的CNC的座標(具體見支撐材料SJ.java),將得到的CNC的座標調入模擬退火演算法進行求解,然後通過模擬退火演算法來解決RGV 怎麼樣排程可以達到最優。
假如我們選取了8個CNC都是空閒的狀態,來對該問題進行求解,求解過程如下。
首先將資料放入RGV.data的檔案中
圖 5
圖 6
然後執行我們的演算法(SA.cpp),可以得到RGV的排程路徑,如下圖7所示:
圖7
0,1,2,3,4,5,6,7分別對應的是1號到8號CNC.
所以我們得出來的最短路徑是依次從1號到8號CNC。
5.2 任務一的情況二的模型建立
情況二要求我們考慮的是比情況一要多一道加工工序的情況,通過分析表中所給的資料,我們可以看出每一道加工工序加工一個零件所需要的時間都是不同的。通過對時間的對照分析,我們參考了時間序列分析模型,決定按照兩道加工工序的時間比例來決定每一道工序所對應的CNC的數量。得到了CNC的分別對應的數量之後,然後將其分配到軌道上固定的位置。最後通過改進演算法來得到想要的結果
5.3 任務一的情況三的模型建立
情況三是在情況一和情況二的基礎上,加入一條限制條件,就是需要我們考慮到CNC刀片會有損壞的情況發生。在CNC刀片損壞之後,我們對這種情況進行了流程分析,見圖8:
5.4 任務二的求解
任務二是對我們在任務一中建立的模型進行檢驗以及驗證所採用和改良的演算法是否有效,我們需要將題目中所給的資料,以及題目所要求的時間限制,都考慮進我們的演算法中來進行計算,然後對得到的解進行分析,分析系統的作業效率以及RGV的調動策略,並將得到的結果放入Eccel表格中。最後計算RGV的工作效率P,目的是希望工作效率最大化,目標函式為Z2。
Z2=maxP=max(T-∑Tn-∑Taj/T);(n=1,2,3;j=1,2,…,n)
P
六、模型的評價
6.1 模型的評價
本文就智慧RGV的動態排程策略,建立了基於模擬退火演算法的最短路徑模型對RGV的動態排程策略進行探究。
模擬退火演算法的優點:計算過程簡單,通用,魯棒性強,適用於並行處理,可用於求解複雜的非線性優化問題,在組合優化方面適用性強。
缺點:收斂速度慢,執行時間長,演算法效能與初始值有關及引數敏感等缺點。
資料量大的時候可能會造成時間的浪費。
最短路徑模型的不足在於模型並不夠智慧,在處理突發情況的時候不夠靈活,可以進一步優化該模型。
該模型建立的時候,對於突發情況的考慮並不周全,只是單獨的考慮當CNC 出現故障的時候的處理方法,還有當RGV出現故障以及傳送帶出現故障的時候的情況並沒有考慮進去。
6.2 模型的改進
可以通過改進模型的演算法,採取更加適合RGV調動策略的演算法,參考國內外著名的文獻資料,可以考慮使用遺傳演算法或者粒子群演算法來改進該模型。
七、參考文獻
[1]姚新,,陳國良,模擬退火演算法及其應用[J],計算機研究與發展,,1990
[2]何霆,劉飛,馬玉林,車間生產排程問題研究[J],機械工程學報,2000
[3]曹承煌,李人厚,樊健,車間排程演算法的研究與開發,控制理論與應用,2002
[4]李海真,許維勝,王中傑,基於 MAS 的排程控制系統研究,計算機輔助上程,2004
[5]張海燕,姜莉莉,一種新型的車間作業計劃及排程監控整合系統的實施,2002
[6]馮玉萍,模擬退火演算法的研究及其應用[D],昆明:昆明理工大學,2005
[7]劉巖,韓承德,王義和等,模擬退火的背景與單調升溫的模擬退火演算法[J],計算計研究與發展,2005
附錄
1、退火演算法
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <stdio.h>
#include <time.h>
#include <math.h>
#define N 30 //城市數量
#define T 3000 //初始溫度 #define EPS 1e-8 //終止溫度
#define DELTA 0.98 //溫度衰減率
#define LIMIT 1000 //概率選擇上限
#define OLOOP 20 //外迴圈次數
#define ILOOP 100 //內迴圈次數
using namespace std;
//定義路線結構體
struct Path
{
int citys[N]; double len;
};
//定義城市點座標
struct Point
{
double x, y;
};
Path bestPath; //記錄最優路徑 Point p[N]; //每個城市的座標 double w[N][N]; //兩兩城市之間路徑長度 int nCase; //測試次數
double dist(Point A, Point B)
{
return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}
void GetDist(Point p[], int n)
{
for(int i = 0; i < n; i++) for(int j = i + 1; j < n; j++) w[i][j] = w[j][i] = dist(p[i], p[j]);
}
void Input(Point p[], int &n)
{
scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%lf %lf", &p[i].x, &p[i].y);
}
void Init(int n)
{
nCase = 0; bestPath.len = 0; for(int i = 0; i < n; i++)
{ bestPath.citys[i] = i; if(i != n - 1) { printf("%d--->", i); bestPath.len += w[i][i + 1];
} else printf("%d\n", i);
} printf("\nInit path length is : %.3lf\n", bestPath.len); printf("-----------------------------------\n\n");
}
void Print(Path t, int n)
{
printf("Path is : "); for(int i = 0; i < n; i++)
{ if(i != n - 1) printf("%d-->", t.citys[i]); else printf("%d\n", t.citys[i]);
}
printf("\nThe path length is : %.3lf\n", t.len); printf("-----------------------------------\n\n");
}
Path GetNext(Path p, int n)
{
Path ans = p; int x = (int)(n * (rand() / (RAND_MAX + 1.0))); int y = (int)(n * (rand() / (RAND_MAX + 1.0))); while(x == y) { x = (int)(n * (rand() / (RAND_MAX + 1.0))); y = (int)(n * (rand() / (RAND_MAX + 1.0)));
} swap(ans.citys[x], ans.citys[y]); ans.len = 0; for(int i = 0; i < n - 1; i++) ans.len += w[ans.citys[i]][ans.citys[i + 1]]; cout << "nCase = " << nCase << endl; Print(ans, n); nCase++; return ans;
}
void SA(int n)
{
double t = T;
srand((unsigned)(time(NULL))); Path curPath = bestPath; Path newPath = bestPath; int P_L = 0; int P_F = 0;
while(1) //外迴圈,主要更新引數 t,模擬退火過程
{
for(int i = 0; i < ILOOP; i++) //內迴圈,尋找在一定溫度下的最優值
{ newPath = GetNext(curPath, n); double dE = newPath.len - curPath.len;
if(dE < 0) //如果找到更優值,直接更新
{
curPath = newPath;
P_L = 0; P_F = 0;
}
else { double rd = rand() / (RAND_MAX + 1.0);
//如果找到比當前更差的解,以一定概率接受該解,並且這個概率會越來越小
if(exp(dE / t) > rd && exp(dE / t) < 1) curPath = newPath;
P_L++; }
if(P_L > LIMIT) { P_F++; break;
} } if(curPath.len < bestPath.len) bestPath = curPath; if(P_F > OLOOP || t < EPS) break; t *= DELTA;
}
}
int main(int argc, const char * argv[]) {
freopen("RGV.data", "r", stdin); int n; Input(p, n);
GetDist(p, n);
Init(n);
SA(n);
Print(bestPath, n); printf("Total test times is : %d\n", nCase); return 0;
}
2、隨機模擬演算法
import java.util.Random;
public class SJ {
public static void main(String[] args) {
int []numbers = {0,0,20,20,33,33,46,46};
Random random = new Random();
int index = random.nextInt(numbers.length);
System.out.println(numbers[index]);
}
}