2018数模国赛B题(2)完整实现代码

//接前一篇

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;
}

 

你可能感兴趣的:(C++,数模)