智能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]);
}
}