2018高教社杯B题 RGV动态调度 c++模拟
2020-01-12 18:52
316 查看
##2018高教社杯B题 RGV动态调度 c++模拟
本人软件工程专业,怀着提高数学能力的初衷参加数学建模竞赛,万万没想到居然在这道题里提高了编程能力。。甚至之前没学懂的指针都搞懂了,连调试程序也得心应手了:)
虽然答辩时被怼这不是程序设计大赛而是数学建模竞赛,但感觉收获颇多,代码也颇有价值,可用在论文最后动态模拟RGV工作流程。
注:程序中只用了数组、指针、动态生成随机数等最基本C++技术,可放心食用
代码如下:
- 一道工序
#include "stdafx.h" #include <math.h> #include <iostream> #include <ctime> #include <random> #define random(a,b) (rand()%(b-a)+a) int m = 545;//CNC上单个产品加工时间 int erro = 0; int Time = 0, H = 0, W = 0, U = 0, Q = 0; //Time为系统从开始到某时刻的时间;H为系统运动消耗时间;W为系统等待时间;U为系统上下料时间;Q为系统清洗熟料时间 int h = 0, w = 0, u = 0, u1 = 27, u2 = 32, q = 25, h1 = 18, h2 = 32, h3 = 46;//u1为奇数CNC上下料时间,u2为偶数CNC上下料时间 int place1 = 1, place2 = 2, place3 = 3, place4 = 4;//设定RGV轨道上四个位置节点 int n = 0;//产出熟料数量 class CNC { public: int T = 0; int status1 = 1; int status2 = 0; int Cp = place1; int products = 0; }; class RGV { public: int RpNow = place1;//RGV当前所处位置 int RpNext = place4;//RGV下一个遍历的位置 }; void TimeCost(CNC *k); void Pick1(CNC *k, int u); void Pick2(CNC *k, int u); void Wait(CNC k[8]); void route(CNC k[8], RGV *s); int main() { srand(unsigned(time(0))); RGV rgv;//一台RGV CNC cnc[8];//一共8台CNC机器且都可被RGV使用 cnc[1].Cp = place1, cnc[2].Cp = place2; cnc[3].Cp = place2, cnc[4].Cp = place3; cnc[5].Cp = place3, cnc[6].Cp = place4; cnc[7].Cp = place4, cnc[0].Cp = place1; //RGV工作流程: while (Time <= 8 * 3600) { //更新CNC的请求状态 TimeCost(cnc); //系统进入等待时间 if ((cnc[0].status1 == 0 && cnc[0].status2 == 0) && (cnc[1].status1 == 0 && cnc[1].status2 == 0) && (cnc[2].status1 == 0 && cnc[2].status2 == 0) && (cnc[3].status1 == 0 && cnc[3].status2 == 0) && (cnc[4].status1 == 0 && cnc[4].status2 == 0) && (cnc[5].status1 == 0 && cnc[5].status2 == 0) && (cnc[6].status1 == 0 && cnc[6].status2 == 0) && (cnc[7].status1 == 0 && cnc[7].status2 == 0)) { Wait(cnc); } //选择下一个去的位置 else { route(cnc, &rgv); } } //计算产出的总产品量 printf("总共生产了%d个熟料\n", n); printf("出了%d次错", erro); getchar(); return 0; } //判断某台CNC是否在加工产 void TimeCost(CNC k[8]) { for (int r = 0;r < 8;r++) { if (abs((Time - k[r].T)) >= m) { k[r].status1 = 0; k[r].status2 = 1; } } } void Pick1(CNC *k, int u) { k->status1 = 0; k->status2 = 0; U += u;//增加单位上下料时间 Time += u; if (random(0, 100) == 10) { k->T = Time + random(10 * 60, 20 * 60) + random(0, m); erro++; } else { k->T = Time;//记录CNC开始工作时刻 } //printf("%d\n", (k->T)-50); } void Pick2(CNC *k, int u) { k->status1 = 0; k->status2 = 0; k->products++; U += u;//增加单位上下料时间 Time += u; if (random(0,100)==10) { k->T = Time + random(10 * 60, 20 * 60) + random(0, m); erro++; } else { k->T = Time;//记录CNC开始工作时刻 Q += q;//增加单位清洗时间 Time += q; n++; } printf("%d\n", Time - 50); } void Wait(CNC k[8]) { int temp = 10000000; for (int n = 0;n<8;n++) { if (temp >= k .T) { temp = k .T; } } Time += (m - (Time - temp));//增加最小等待时间 } void route(CNC k[8], RGV *s) { int c = 5; int d = 0; for (int i = 0;i < 8;i++) { if (k[i].status1 == 1 || k[i].status2 == 1) { if (abs(k[i].Cp - s->RpNow)< c) { s->RpNext = k[i].Cp; c = abs(s->RpNext - s->RpNow); d = i; } /* else { if (k[i].status2 == 1) //pick2优先 { s->RpNext = k[i].Cp; c = abs(s->RpNext - s->RpNow); d = i; } else { s->RpNext = k[i].Cp; c = abs(s->RpNext - s->RpNow); d = i - 1; } } */ } } //区别移动距离 if (c = 0) h = 0; else if (c = 1) h = h1; else if (c = 2) h = h2; else if (h = 3) h = h3; H = h; Time += h; if (k[d].status2 == 1) //判断CNC为奇还是偶 { if (d % 2 == 0) u = u2; else if (d % 2 != 0) u = u1; Pick2(&k[d], u); } else if (k[d].status1 == 1) { if (d % 2 == 0) u = u2; else if (d % 2 != 0) u = u1; Pick1(&k[d], u); } s->RpNow = s->RpNext;//更新RGV位置 }
- 一道工序且CNC有几率产生故障
#include "stdafx.h" #include <math.h> #include <iostream> #include <ctime> #include <random> #define random(x) rand()%(x) int m = 545;//CNC上单个产品加工时间 int Time = 0, H = 0, W = 0, U = 0, Q = 0; //Time为系统从开始到某时刻的时间;H为系统运动消耗时间;W为系统等待时间;U为系统上下料时间;Q为系统清洗熟料时间 int h = 0, w = 0, u = 0, u1 = 27, u2 = 32, q = 25, h1 = 18, h2 = 32, h3 = 46;//u1为奇数CNC上下料时间,u2为偶数CNC上下料时间 int place1 = 1, place2 = 2, place3 = 3, place4 = 4;//设定RGV轨道上四个位置节点 int n = 0;//产出熟料数量 class CNC { public: int T = 0; int status1 = 1; int status2 = 0; int Cp = place1; int products = 0; }; class RGV { public: int RpNow = place1;//RGV当前所处位置 int RpNext = place4;//RGV下一个遍历的位置 }; void TimeCost(CNC *k); void Pick1(CNC *k, int u); void Pick2(CNC *k, int u); void Wait(CNC k[8]); void route(CNC k[8], RGV *s); int main() { srand(unsigned(time(0))); RGV rgv;//一台RGV CNC cnc[8];//一共8台CNC机器且都可被RGV使用 cnc[1].Cp = place1, cnc[2].Cp = place2; cnc[3].Cp = place2, cnc[4].Cp = place3; cnc[5].Cp = place3, cnc[6].Cp = place4; cnc[7].Cp = place4, cnc[0].Cp = place1; //RGV工作流程: while (Time <= 8 * 3600) { //更新CNC的请求状态 TimeCost(cnc); //系统进入等待时间 if ((cnc[0].status1 == 0 && cnc[0].status2 == 0) && (cnc[1].status1 == 0 && cnc[1].status2 == 0) && (cnc[2].status1 == 0 && cnc[2].status2 == 0) && (cnc[3].status1 == 0 && cnc[3].status2 == 0) && (cnc[4].status1 == 0 && cnc[4].status2 == 0) && (cnc[5].status1 == 0 && cnc[5].status2 == 0) && (cnc[6].status1 == 0 && cnc[6].status2 == 0) && (cnc[7].status1 == 0 && cnc[7].status2 == 0)) { Wait(cnc); } //选择下一个去的位置 else { route(cnc, &rgv); } } //计算产出的总产品量 printf("总共生产了%d个熟料", n); getchar(); return 0; } //判断某台CNC是否在加工产 void TimeCost(CNC k[8]) { for (int r = 0;r < 8;r++) { if (abs((Time - k[r].T)) >= m) { k[r].status1 = 0; k[r].status2 = 1; } } } void Pick1(CNC *k, int u) { k->status1 = 0; k->status2 = 0; U += u;//增加单位上下料时间 Time += u; k->T = Time;//记录CNC开始工作时刻 //printf("%d\n", (k->T)-50); } void Pick2(CNC *k, int u) { int cc = random(101); k->status1 = 0; k->status2 = 0; k->products++; U += u;//增加单位上下料时间 Time += u; if (cc == 10) { k->T = Time + random(10 * 60, 20 * 60) + random(0, m); } else{ k->T = Time;//记录CNC开始工作时刻 Q += q;//增加单位清洗时间 Time += q; n++; } printf("%d\n", Time-50); } void Wait(CNC k[8]) { int temp = 10000000; for (int n = 0;n<8;n++) { if (temp >= k .T) { temp = k .T; } } Time += (m - (Time - temp));//增加最小等待时间 } void route(CNC k[8], RGV *s) { int c = 5; int d = 0; for (int i = 0;i < 8;i++) { if (k[i].status1 == 1 || k[i].status2 == 1) { if (abs(k[i].Cp - s->RpNow)< c) { s->RpNext = k[i].Cp; c = abs(s->RpNext - s->RpNow); d = i; } /* else { if (k[i].status2 == 1) //pick2优先 { s->RpNext = k[i].Cp; c = abs(s->RpNext - s->RpNow); d = i; } else { s->RpNext = k[i].Cp; c = abs(s->RpNext - s->RpNow); d = i - 1; } } */ } } //区别移动距离 if (c = 0) h = 0; else if (c = 1) h = h1; else if (c = 2) h = h2; else if (h = 3) h = h3; H = h; Time += h; if (k[d].status2 == 1) //判断CNC为奇还是偶 { if (d % 2 == 0) u = u2; else if (d % 2 != 0) u = u1; Pick2(&k[d], u); } else if (k[d].status1 == 1) { if (d % 2 == 0) u = u2; else if (d % 2 != 0) u = u1; Pick1(&k[d], u); } s->RpNow = s->RpNext;//更新RGV位置 }
- 两道工序
// mat.cpp: 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <math.h> #include <ctime> #define random(a,b) (rand()%(b-a)+a) #define knife1 4 //knife1和2决定了两种CNC的数量 #define knife2 4 int m = 560,m1=280,m2=500;//CNC上单个产品加工时间 int Time = 0, H = 0, W = 0, U = 0, Q = 0; //Time为系统从开始到某时刻的时间;H为系统运动消耗时间;W为系统等待时间;U为系统上下料时间;Q为系统清洗熟料时间 int h = 0, w = 0,u=30, u1 = 28,u2=31, q = 30,h1=23,h2=41,h3=59;//u1为奇数CNC上下料时间,u2为偶数CNC上下料时间 int place1 = 1, place2 = 2, place3 = 3, place4 = 4;//设定RGV轨道上四个位置节点 int n = 0;//产出熟料数量 //构造两种CNC,一种装刀具1,一种装刀具2 class CNC1 { public: int T=0; int status1=1; int status2 = 0; int Cp = place1; int products = 0; }; class CNC2 { public: int T = 10000000; int status3 = 1;//////////////////////////////////////////////////////////////// int status4 = 0; int Cp = place1; int products = 0; }; class RGV { public : int RpNow = place1;//RGV当前所处位置 int RpNext = place4;//RGV下一个遍历的位置 int hand = 0; }; void TimeCost(CNC1 *k1,CNC2 *k2); void Pick1(CNC1 *k,int u); void Pick2(CNC1 *k,RGV *s,int u); void Pick3(CNC2 *k,RGV *s,int u); void Pick4(CNC2 *k,RGV *s,int u); void Wait(CNC1 k1[knife1], CNC2 k2[knife2]); //void route(CNC1 k1[knife1], CNC2 k2[knife2], RGV *s); int None(CNC1 s1[knife1], CNC2 s2[knife2]); int K2n( CNC2 s2[knife2],RGV k); int K1n(CNC1 s1[knife1], RGV k); int p1(CNC1 k[knife1]); int p2(CNC1 k[knife1]); int p3(CNC2 k[knife1]); void step1(CNC1 k1[knife1], RGV *s); void step2(CNC1 k1[knife1], RGV *s); void step3(CNC2 k1[knife1], RGV *s); int main() { RGV rgv;//一台RGV CNC1 cnc1[knife1]; CNC2 cnc2[knife2]; if (knife1 == 3) { cnc1[0].Cp = place2, cnc1[1].Cp = place2, cnc1[2].Cp = place3; cnc2[0].Cp = place1, cnc2[1].Cp = place1, cnc2[2].Cp = place3, cnc2[3].Cp = place4 , cnc2[4].Cp = place4; } else if(knife1 == 4) { cnc1[0].Cp = place1, cnc1[1].Cp = place2, cnc1[2].Cp = place3, cnc1[3].Cp = place4; cnc2[0].Cp = place1, cnc2[1].Cp = place2, cnc2[2].Cp = place3, cnc2[3].Cp = place4; } else if(knife1==5) { cnc2[0].Cp = place2, cnc2[1].Cp = place2, cnc2[2].Cp = place3; cnc1[0].Cp = place1, cnc1[1].Cp = place1, cnc1[2].Cp = place3, cnc1[3].Cp = place4, cnc1[4].Cp = place4; } else if(knife1==6) { cnc2[0].Cp = place2, cnc2[1].Cp = place3; cnc1[0].Cp = place1, cnc1[1].Cp = place1, cnc1[2].Cp = place3, cnc1[3].Cp = place4, cnc1[4].Cp = place4 , cnc1[5].Cp = place2; } //RGV工作流程: while (Time <= 8 * 3600) { //更新CNC的请求状态 TimeCost(cnc1, cnc2); //系统进入等待时间 if (None(cnc1, cnc2)==0||K2n(cnc2,rgv)==0||K1n(cnc1,rgv)==0) { Wait(cnc1,cnc2); } //选择下一个去的位置 else { while (p1(cnc1)) { step1(cnc1, &rgv); } if (rgv.hand == 0&&p2(cnc1)==1) { step2(cnc1, &rgv); } else if (rgv.hand == 1&&p3(cnc2)==1) { step3(cnc2, &rgv); } } } //计算产出的总产品量 printf("总共生产了%d个熟料", n); getchar(); return 0; } //判断某台CNC是否加工完成产品 void TimeCost(CNC1 k1[knife1],CNC2 k2[knife2]) { for (int r1 = 0;r1 < knife1;r1++) { if ((Time - k1[r1].T) >= m1) { k1[r1].status1 = 0; k1[r1].status2 = 1; } } for (int r2 = 0;r2 < knife2;r2++) { if ((Time - k2[r2].T) >= m2) { k2[r2].status3 = 0; k2[r2].status4 = 1; } } } void Pick1(CNC1 *k, int u) { k->status1 = 0; k->status2 = 0; U += u;//增加单位上下料时间 Time += u; k->T = Time;//记录CNC开始工作时刻 //printf("%d;\n", (k->T)-53); } void Pick2(CNC1 *k, RGV *s, int u) { k->status1 = 0; k->status2 = 0; s->hand = 1;//表示机械臂上已有一个半熟料 U += u;//增加单位上下料时间 Time += u; k->T = Time;//记录CNC开始工作时刻 //printf("%d;%d\n",Time-53,(k->T)-u-53); } void Pick3(CNC2 *k, RGV *s , int u) { k->status3 = 0; k->status4 = 0; s->hand = 0;//表示机械臂上已经没有半熟料 U += u;//增加单位上下料时间 Time += u; k->T = Time;//记录CNC开始工作时刻 printf("%d;\n", (k->T)-u-53); } void Pick4(CNC2 *k,RGV *s, int u) { k->status3 = 0; k->status4 = 0; s->hand = 0; U += u;//增加单位上下料时间 Time += u; k->T = Time;//记录CNC开始工作时刻 Q += q; Time += q; n++; printf("%d;%d\n", Time - 53, (k->T) - u - 53); } void Wait(CNC1 k1[knife1],CNC2 k2[knife2]){ //取最小的pick2和最小的pick4,作比较取最小的那个最为等待时间 int temp1 = 10000000; int temp2 = 10000000; for (int n=0;n<knife1;n++) { if (temp1 >= k1 .T) { temp1 = k1 .T; } } for (int n2 = 0;n2<knife2;n2++) { if (temp2 >= k2[n2].T) { temp2 = k2[n2].T; } } if (temp1 > temp2) { Time += (m2 - (Time - temp2))+1;//增加最小等待时间 } else Time += (m1 - (Time - temp1))+1;//增加最小等待时间 } /* void route(CNC1 k1[knife1],CNC2 k2[knife2],RGV *s) { int c = 5; int c1 = 5; int c2 = 5; int d1 = 0; int d2 = 0; //找一个最近的CNC1,d1即为它的编号 for (int i = 0;i < knife1;i++) { if (k1[i].status1 == 1 || k1[i].status2 == 1) { if (abs(k1[i].Cp - s->RpNow)< c1) { s->RpNext = k1[i].Cp; c1 = abs(s->RpNext - s->RpNow); d1 = i; } } } //找一个最近的CNC2,d2即为它的编号 for (int j = 0;j < knife2;j++) { if (k2[j].status3 == 1 || k2[j].status4 == 1) { if (abs(k2[j].Cp - s->RpNow)< c2) { s->RpNext = k2[j].Cp; c2 = abs(s->RpNext - s->RpNow); d2 = j; } } } //区别移动距离 if (c = 0) h = 0; else if (c = 1) h = h1; else if (c = 2) h = h2; else if (c = 3) h = h3; H += h; Time += h; if (k1[d1].status2 == 1) { if (d1 % 2 == 0) //由于CNC编号与位置无关,无法判断CNC为奇还是偶 u = u2; else if (d1 % 2 != 0) u = u1; Pick2(&k1[d1],s,u); printf("编号为%d的CNC在时刻%ds完成熟料的下料以及生料的上料(pick2操作)\n", d1, Time); } else if(k1[d1].status1 == 1) { /* if (d1 % 2 == 0) u = u2; else if (d1 % 2 != 0) u = u1; Pick1(&k1[d1],u); printf("编号为%d的CNC在时刻%ds由待机状态放上生料开始工作(pick1操作)\n", d1, Time); } s->RpNow = s->RpNext;//更新RGV位置 } */ int None(CNC1 s1[knife1], CNC2 s2[knife2]) //如果没有任何指令返回0,否则返回1 { int a = 0, b = 0; for (int i = 0;i < knife1;i++) { if (s1[i].status1 != 0 || s1[i].status2 != 0) { a = 1; break; } } for (int j = 0;j < knife2;j++) { if (s2[j].status3 != 0 || s2[j].status4 != 0) { b = 1; break; } } if (a + b == 0) return 0; else return 1; } int K2n( CNC2 s2[knife2],RGV k)//如果刀2无信号且机械臂上有一个半熟料则返回0 { int a = 0; for (int j = 0;j < knife2;j++) { if (s2[j].status3 != 0 || s2[j].status4 != 0 || k.hand != 1) { a = 1; break; } } return a; } int K1n(CNC1 s1[knife1], RGV k) { int a = 0; for (int i = 0;i < knife1;i++) { if (s1[i].status1 != 0 || s1[i].status2 != 0||k.hand!=0) { a = 1; break; } } return a; } int p1(CNC1 k[knife1])//检验是否还有可执行的status1 { int a=0; for (int n = 0;n < knife1;n++) { if (k .status1 == 0) a += 0; else a += 1; } if (a == 0) return 0; else return 1; } int p2(CNC1 k[knife1])//检验是否有可执行pick2的CNC1 { int a = 0; for (int n = 0;n < knife1;n++) { if (k .status2 == 0) a += 0; else a += 1; } if (a == 0) return 0; else return 1; } int p3(CNC2 k[knife1])//检验是否有可执行pick3/pick4的CNC2 { int a = 0; for (int n = 0;n < knife1;n++) { if (k .status3 == 0&&k .status4==0) a += 0; else a += 1; } if (a == 0) return 0; else return 1; } void step1(CNC1 k1[knife1], RGV *s) //step1:找到最进的status1=1的CNC1 { int c1 = 5; int d1 = 0; for (int i = 0;i < knife1;i++) { if (k1[i].status1 == 1) { if (abs(k1[i].Cp - s->RpNow)< c1) { s->RpNext = k1[i].Cp; c1 = abs(s->RpNext - s->RpNow); d1 = i; } } } //移动过去 if (c1 = 0) h = 0; else if (c1 = 1) h = h1; else if (c1 = 2) h = h2; else if (c1 = 3) h = h3; H += h; Time += h; //完成pick1 Pick1(&k1[d1], u); //printf("编号为%d的CNC1在%d时刻完成pick1\n",d1,Time); s->RpNow = s->RpNext;//更新RGV位置 } void step2(CNC1 k1[knife1],RGV *s) //step2:找到最进的能执行pick2的CNC1 { int c1 = 5; int d1 = 0; for (int i = 0;i < knife1;i++) { if (k1[i].status2 == 1 ) { if (abs(k1[i].Cp - s->RpNow)< c1) { s->RpNext = k1[i].Cp; c1 = abs(s->RpNext - s->RpNow); d1 = i; } } } //移动过去 if (c1 = 0) h = 0; else if (c1 = 1) h = h1; else if (c1 = 2) h = h2; else if (c1 = 3) h = h3; H += h; Time += h; //完成pick2 Pick2(&k1[d1],s, u); //printf("编号为%d的CNC1在%d时刻完成pick2\n", d1, Time); s->RpNow = s->RpNext;//更新RGV位置 } void step3(CNC2 k1[knife1], RGV *s) { int c1 = 5; int d1 = 0; for (int i = 0;i < knife1;i++) //找一个最近的能执行pick3或pick4的CNC2 { if (k1[i].status3 == 1||k1[i].status4==1) { if (abs(k1[i].Cp - s->RpNow)< c1) { s->RpNext = k1[i].Cp; c1 = abs(s->RpNext - s->RpNow); d1 = i; } } } //移动过去 if (c1 = 0) h = 0; else if (c1 = 1) h = h1; else if (c1 = 2) h = h2; else if (c1 = 3) h = h3; H += h; Time += h; //完成pick3或pick4 if (k1[d1].status3 == 1) { Pick3(&k1[d1], s, u); //printf("编号为%d的CNC2在%d时刻完成pick3\n", d1, Time); } else if (k1[d1].status4 == 1) { Pick4(&k1[d1], s, u); //printf("编号为%d的CNC2在%d时刻完成pick4\n", d1, Time); } s->RpNow = s->RpNext;//更新RGV位置 }
- 点赞 1
- 收藏
- 分享
- 文章举报
相关文章推荐
- 使用动态优先权的进程调度算法的模拟
- 使用动态优先权的进程调度算法的模拟
- 使用C++模拟动态密码验证
- 流水线调度最优问题(装配线调度问题)动态规划 O(n)时间(线性时间)C++实现
- 操作系统——使用动态优先权的进程调度算法的模拟
- 动态规划-流水调度的C++实现
- 模拟磁盘调度 (C++) 先来先服务、最短寻道时间优先、电梯算法
- 流水线调度最优问题(装配线调度问题)动态规划 O(n)时间(线性时间)C++实现
- C++动态数组简单模拟二叉堆
- c++ 模拟进程调度 (链表实现)
- c++模拟动态语言中string类的实现
- C++动态创建及工厂模式的模拟
- 进程调度算法模拟,用动态优先数及时间片轮转法实现进程调度_Java语言模拟实现
- 模拟c++容器vector写的动态数组
- c++模拟操作系统进程调度算法(优先数,时间片轮转)
- 操作系统 单处理器进程调度模拟实验(c++)
- 用C++模拟操作系统进程调度的几种算法
- 用C++和JAVA实现进程调度模拟
- C++模拟实现Objective-C动态类型(附源码)
- c++ 模拟银行家调度算法 避免进程死锁