//接前一篇
1、RGV::RGV()
RGV类构造函数,定义RGV类对象时实现成员变量的初始化。具体成员变量初始化情况:RGV初始位置Position=0,初始最优解(RGV当前操作CNC台的编号)now_cnc=1,RGV初始状态rgv_flag空闲,加工总耗时为0,加工熟料总数为0。
2、void RGV::Init(CNC *p)
RGV第一轮作业情况特殊,仅需考虑RGV“移动”和“上料”动作。
3、int RGV::posCalculate(int pos1, int pos2)
该函数返回RGV从位置1pos1移动到位置2pos2需要的时间。主要由函数RGV::move调用。
4、void RGV::move(CNC *p)
该函数抽象RGV类的“运动”作业。①先用“贪心算法”找到RGV下一移动目标的最优解next_cnc;②比较当前对象now_cnc和最优对象next_cnc,如果当前对象不是最优对象,则移动向最优对象;③判断是否需要等待,如果最优CNC工作台当前忙碌(CNC工作剩余时间count不为0),则等待。
5、void RGV::load(CNC *p)
该函数抽象RGV类的“上下料”作业。①判断当前CNC工作台编号的奇偶性,选择奇数号上下料时间CNC1还是偶数号上下料时间CNC2;②完成“上下料”作业的同时,将此时RGV中的“加工物序列总数RGV::n”和“CNC加工完成一个一道工序的物料所需时间CNC_WORKTIME”赋给当前CNC工作台的“加工物序号CNC::n”和“加工剩余时间CNC::count”。
6、void RGV::clean(CNC* p)
该函数抽象RGV类的“清洗”作业。将“完成清洗时间CLEAN”同步到“总时间”和所有CNC“加工剩余时间CNC::count”。
7、void RGV::wait(CNC* p)
该函数抽象RGV类的“等待”作业。将“完成清洗时间CLEAN”同步到“总时间”和所有CNC“加工剩余时间CNC::count”。
8、CNC::CNC( int num, int pos)
CNC类构造函数,要求在初始化CNC类对象时必须进行显性初始化。显性初始化方便用户使用程序时进行查错,且初始化后对象的属性不会在程序运行时发生改变,提高了程序的稳定性。具体成员变量初始化情况:CNC初始编号number=0;CNC初始位置position=0;CNC剩余加工时间count;CNC::n当前加工无序列号。
9、void CNC::countdown(int temp)
该函数的作用是同步CNC类与RGV类的时间变化。输入形参temp为调用该函数时变化的时间值。
②第二种情况(无故障):
/*-----------------------------------------CNC.h---------------------------------------*/
#pragma once
class CNC
{
private:
int number; //CNC编号
int position; //CNC位置
int knife; //CNC刀具型号,1第一道工序,2第二道工序
int count; //CNC剩余工作时间
int n; //加工物序列号
public:
CNC(int num, int pos, int kni);
void countdown(int temp);
friend class RGV;
};
/*-----------------------------------------CNC.cpp---------------------------------------*/
#include "stdafx.h"
#include "CNC.h"
CNC::CNC(int num, int pos, int kni)
{
number = (num > 0) ? num : ERROR;
position = (pos >= 0) ? pos : ERROR;
knife = (kni == 1 || kni == 2) ? kni : ERROR;
count = 0;
n = 0;
}
void CNC::countdown(int temp)
{
if (count > temp) {
count -= temp;
}
else {
count = 0;
}
}
/*-----------------------------------------RGV.h---------------------------------------*/
#pragma once
#include "CNC.h"
using namespace std;
class RGV
{
private:
int position; //rgv当前位置
int now_cnc; //rgv当前CNC对象
int rgv_flag; //rgv_flag,RGV当前状态,1空闲,2持有半成品
int rgv_n; //RGV当前半成品号
public:
int time; //总用时
int sum; //加工熟料总数
RGV();
int find(CNC* p); //寻找最优解
void Init(CNC *p); //第一轮初始化
int posCalculate(int pos1, int pos2); //计算RGV移动时间
void move(CNC *p); //RGV移动
void load(CNC *p); //RGV上下料
void wait(CNC *p);//RGV等待
};
/*-----------------------------------------RGV.cpp---------------------------------------*/
#include "stdafx.h"
#include "RGV.h"
#define STEP1 20
#define STEP2 33
#define STEP3 46
#define CNC_WORKTIME1 400
#define CNC_WORKTIME2 378
#define CNC1 28
#define CNC0 31
#define CLEAN 25
#define CNC_NUMBER 8
#define TIME 28800
using namespace std;
int n = 0;//加工物序号
RGV::RGV()
{
position = 0;
now_cnc = 1;
rgv_flag = 1;
rgv_n = 0;
time = 0;
sum = 0;
}
void RGV::Init(CNC *p)
{
CNC*ptr = p;
for (int i = 0; i < CNC_NUMBER; i++, ptr++, now_cnc++)
{
if (ptr->knife == 1) {
int temp = posCalculate(position, (p + now_cnc - 1)->position);
if (temp) {
time += temp;
CNC*ptr1 = p;
for (int i = 0; i < CNC_NUMBER; i++, ptr1++) //同步RGV和CNC的时间
{
ptr1->countdown(temp);
}
}
load(p);
position = (p + now_cnc - 1)->position;
//cout << "position" << position << '\t' << "now_cnc" << now_cnc << endl; //test
rgv_flag = 1;
}
else continue;
}
}
int RGV::posCalculate(int pos1, int pos2)//RGV移动时间计算
{
switch (abs(pos1 - pos2))
{
case 3: return STEP3;
case 2: return STEP2;
case 1: return STEP1;
case 0: return 0;
default: return ERROR;
}
}
int RGV::find(CNC *p)
{
CNC* ptr = p;
int next_cnc = 1;//最优解
int min_time1 = 1000;
int now_time1 = 0;
if (rgv_flag == 1) {//空闲
for (int i = 0; i < CNC_NUMBER; i++, ptr++) {//注意!!空闲既可选择刀具1,也可选择刀具2
int postime = posCalculate(position, ptr->position);
now_time1 = (ptr->count > postime) ? ptr->count : postime;
if (min_time1 > now_time1) {
min_time1 = now_time1;
next_cnc = ptr->number;
}
else continue;
}
}
else {//半成品
for (int i = 0; i < CNC_NUMBER; i++, ptr++) {
if (ptr->knife == 2) {
int postime = posCalculate(position, ptr->position);
now_time1 = (ptr->count > postime) ? ptr->count : postime;
if (min_time1 > now_time1) {
min_time1 = now_time1;
next_cnc = ptr->number;
}
}
else continue;
}
}
return next_cnc;
}
void RGV::move(CNC *p)//RGV移动
{
int next_cnc = find(p);
if (next_cnc != now_cnc) {//当前对象不是最优对象,移动
int temp = posCalculate(position, (p + next_cnc - 1)->position);
if (temp) {
time += temp;
CNC*ptr1 = p;
for (int i = 0; i < CNC_NUMBER; i++, ptr1++) //所有CNC剩余时间 - rgv移动时间
{
ptr1->countdown(temp);
}
}
position = (p + next_cnc - 1)->position;
now_cnc = next_cnc;
//cout << "position" << position << '\t' << "now_cnc" << now_cnc << endl; //test
}
wait(p);
}
void RGV::load(CNC *p)
{
CNC* ptr = p + now_cnc - 1; //此处数组下标和CNC编号要注意!
int count_temp = 0;
if (ptr->knife == 1) {
cout << time << '\t' << rgv_flag << '\t' << ptr->n << '\t' << '\t' << ++n << '\t' << '\t' << now_cnc << endl;
count_temp = CNC_WORKTIME1;
rgv_flag = 2;
rgv_n = ptr->n;//半成品序列号
ptr->n = n;
}
else {
cout << time << '\t' << rgv_flag << '\t' << ptr->n << '\t' << '\t' << rgv_n << '\t' << '\t' << now_cnc << endl;
count_temp = CNC_WORKTIME2 + CLEAN;
rgv_flag = 1;
if ((TIME - time) > CNC0 && (TIME - time) > CNC1) {
sum = ptr->n;
}else
sum = (ptr->n - 1);
ptr->n = rgv_n;
}
ptr->count = count_temp;
int temp = 0;
if ((ptr->number % 2) == 1) {
temp = CNC1;
}
else {
temp = CNC0;
}
time += temp;
CNC*ptr1 = p;
for (int i = 0; i < CNC_NUMBER; i++, ptr1++) //所有CNC剩余时间 - rgv移动时间
{
ptr1->countdown(temp);
}
}
void RGV::wait(CNC *p)//RGV等待
{
CNC* ptr = p + now_cnc - 1;
if (ptr->count) {
int temp = ptr->count;
time += temp;
CNC*ptr1 = p;
for (int i = 0; i < CNC_NUMBER; i++, ptr1++) //所有CNC剩余时间 - rgv移动时间
{
ptr1->countdown(temp);
}
}
else return;
}
/*-----------------------------------------main.cpp---------------------------------------*/
#include "stdafx.h"
#include "RGV.h"
#include "CNC.h"
#define CNC_NUMBER 8
#define TIME 28800
using namespace std;
int main()
{
RGV rgv;
CNC cnc[CNC_NUMBER] = {
CNC(1,0,1), CNC(2,0,2), CNC(3,1,1), CNC(4,1,2),
CNC(5,2,1), CNC(6,2,2), CNC(7,3,1), CNC(8,3,2) };
CNC *pCNC = cnc;
cout << "时间" << '\t' <<"工序"<< '\t' << "下料开始" << '\t' << "上料开始" << '\t' << "CNC#" << endl;
rgv.Init(pCNC);
while (rgv.time <= TIME)
{
rgv.move(pCNC);
rgv.load(pCNC);
}
cout << "生成熟料总数:" << rgv.sum << endl;
system("pause");
return 0;
}