记录下代码工作,代码是从0开始写的,解题思路也全部由小队内交流得到。记录下代码。
#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include<algorithm>
#include <string>
# define NUM 110000
# define OrderNUM 604
using namespace std;
int item_id[NUM], IfItemUser[NUM],SumNuItem = 0, user_board = 0, show = 1, Fail = 99999;
string Itemmaterial[NUM], item_order[NUM], order[OrderNUM];
int ItemMatNu[NUM],item_OrderNu[NUM];
unsigned int iwbas[NUM][2];//ItemWitchBoardAndStrip
unsigned int iwsas[NUM][2];//ItemWitchstackAndState
int ItemInf[NUM][2];//0位批次 1位材质
int BetchBeenProd[200];
int IfItemProd[NUM];//产品最终是否生产
int IfSameMatBetItemProd[NUM];//产品最终是否生产
int max_item_num = 1000,SumBetch=0;
int orderIfArrange[OrderNUM],orderWhichBetch[OrderNUM];
float iwxy[NUM][3];//ItemXY坐标 0为绝对长边在下 1为绝对短边在下
float sois[OrderNUM][2];//相同订单中的产品项总数 及 面积 Same_Order_Itim_Sum
float ItemlenandWid[NUM][3], //Len X and Wid Y and Area
StartXY[2] = { 0,0 };// 产品的XY的起始坐标及状态
float max_board_area = 2440 * 1220, Plate_length = 2440, Plate_width = 1220,max_item_area = 250 * 1000000;
int ReadDataFile(string Filename)
{
ifstream inFile(Filename, ios::in);//"dataA1Detal.csv"
if (!inFile)
{
cout << "打开文件失败!" << endl;
exit(1);
}
unsigned int i = 0; //下标从一开始
string line;
string field;
string s;
int pri = 0;
while (getline(inFile, line))//getline(inFile, line)表示按行读取CSV文件中的数据
{
string field;
istringstream sin(line); //将整行字符串line读入到字符串流sin中
getline(sin, field, ','); //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
item_id[i] = atoi(field.c_str());
if(pri)cout << atof(field.c_str()) << " ";//将刚刚读取的字符串转换成int
getline(sin, field, ','); //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
Itemmaterial[i] = field.c_str();
if (pri)cout << Itemmaterial[i] << " ";//将刚刚读取的字符串转换成int
getline(sin, field, ','); //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
item_order[i] = field.c_str();
if (pri)cout << item_order[i] << " "<<endl;//将刚刚读取的字符串转换成int
getline(sin, field, ','); //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
ItemlenandWid[i][0] = atof(field.c_str());
getline(sin, field, ','); //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
ItemlenandWid[i][1] = atof(field.c_str());
getline(sin, field, ','); //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
ItemlenandWid[i][2] = atof(field.c_str());
if (i < OrderNUM) {
getline(sin, field, ','); //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
sois[i][0] = atoi(field.c_str());
if (pri)cout << sois[i][0] << " " << endl;//将刚刚读取的字符串转换成int
getline(sin, field, ','); //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
sois[i][1] = atof(field.c_str());
if (pri)cout << sois[i][1] << " " << endl;//将刚刚读取的字符串转换成int
getline(sin, field, ','); //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
order[i] =field.c_str();
if (pri)cout << order[i] << " " << endl;//将刚刚读取的字符串转换成int
}
// // cout<<item_id[i]<<' '<<ItemlenandWid[i][0]<<' '<<ItemlenandWid[i][1]<<endl;
// // getline(sin, field); //将字符串流sin中的字符读入到field字符串中,以逗号为分隔符
// // cout << field.c_str() << endl;//将刚刚读取的字符串转换成int
i++;
//if (i == OrderNUM)
// break;
}
inFile.close();
cout << "共读取了:" << i << "行" << endl;
for (int j = 0; j < i; j++)
IfItemUser[i] = 0;
return i;
// cout << "读取数据完成" << endl;
}
void SaveDataFile(string Filename)
{
ofstream outFile(Filename, ios::out);
if (!outFile)
{
cout << "打开文件失败!" << endl;
exit(1);
}
outFile << "原片序号" << ",";
outFile << "产品id" << ",";
outFile << "产品x坐标" << ",";
outFile << "产品y坐标" << ",";
outFile << "产品x方向长度" << ",";
outFile << "产品y方向长度" << ",";
outFile << std::endl;
for (int i = 0; i < SumNuItem; i++)
{
outFile << iwbas[i][0] << ",";
outFile << item_id[i] << ",";
outFile << iwxy[i][0] << ",";
outFile << iwxy[i][1] << ",";
if (!iwxy[i][2]) {
outFile << ItemlenandWid[i][0] << ",";
outFile << ItemlenandWid[i][1] << ",";
}
else {
outFile << ItemlenandWid[i][1] << ",";
outFile << ItemlenandWid[i][0] << ",";
}
outFile << std::endl;
if (0) {
cout << iwbas[i][0] << ",";
cout << item_id[i] << ",";
cout << iwxy[i][0] << ",";
cout << iwxy[i][1] << ",";
if (!iwxy[i][2]) {
cout << ItemlenandWid[i][0] << ",";
cout << ItemlenandWid[i][1] << ",";
}
else {
cout << ItemlenandWid[i][1] << ",";
cout << ItemlenandWid[i][0] << ",";
}
cout << endl;
}
}
outFile.close();
cout << "写入数据完成" << endl;
}
int SearchMatchItem(float x_limit, float y_limit, int stat, int add[2], float bexy1[2])
{
//cout << "StartXY " << bexy1[0] << ' ' << bexy1[1] << endl;
if (user_board == 0) exit(1);
int i, a = 0; // x_limit L y_limit W
if (stat == 0) {//0仅搜索长 1长宽混合搜索 严格相等 2 长宽混合搜索 非严格相等
for (i = 0; i < SumNuItem; i++) {
if (IfItemUser[i] == 0) {
if (ItemlenandWid[i][0] < x_limit)
if (ItemlenandWid[i][1] < y_limit) {
IfItemUser[i] = 1;
add[0] = i; add[1] = 0;
//a = add[1];
iwxy[i][0] = bexy1[add[1]];
iwxy[i][1] = bexy1[1 - add[1]];
iwxy[i][2] = add[1];
iwbas[i][0] = user_board;
//cout << item_id[i] << ' ' << 0 << endl;
return i;
}
}
}
return Fail;
}
else if (stat == 1)
{ //1长宽混合搜索 严格相等
for (i = 0; i < SumNuItem; i++) { //first L
// cout<<'L'<<endl;
if (IfItemUser[i] == 0) {
if (ItemlenandWid[i][0] == x_limit)
if (ItemlenandWid[i][1] < y_limit) {
IfItemUser[i] = 1;
add[0] = i; add[1] = 0;
iwxy[i][0] = bexy1[add[1]];
iwxy[i][1] = bexy1[1 - add[1]];
iwxy[i][2] = add[1];
iwbas[i][0] = user_board;
//cout << item_id[i] << ' ' << 1 << endl;
return i;
}
}
}
for (i = 0; i < SumNuItem; i++) { // W
// cout<<'w'<<endl;
if (IfItemUser[i] == 0) {
if (ItemlenandWid[i][1] == x_limit)
if (ItemlenandWid[i][0] < y_limit) {
IfItemUser[i] = 1;
add[0] = i; add[1] = 1; // W
iwxy[i][0] = bexy1[add[1]];
iwxy[i][1] = bexy1[1 - add[1]];
iwxy[i][2] = add[1];
iwbas[i][0] = user_board;
//cout << item_id[i] << ' ' << 1 << endl;
return i;
}
}
}
return Fail;
}
else if (stat == 2) { //2 长宽混合搜索 非严格相等
//cout <<user_board << ' ' << bexy1[0] << ' ' << bexy1[1] << endl;
float minwasteX[10000], minwasteY[10000], minwastex = 0, minwastey = 0;
int minPositionX = 0, minPositionY = 0, ifXfind = 0, ifYfind = 0;
for (i = 0; i < SumNuItem; i++) minwasteX[i] = max_item_area;
for (i = 0; i < SumNuItem; i++) { //first L
if (IfItemUser[i] == 0)
{
if (ItemlenandWid[i][0] <= x_limit) //进行筛选
if (ItemlenandWid[i][1] <= y_limit) {
minwastex = x_limit - ItemlenandWid[i][0];
minwastey = y_limit - ItemlenandWid[i][1];
minwasteX[i] = minwastex * y_limit - minwastey * x_limit + minwastex * minwastey;
ifXfind = 1;
}
}
}
if (ifXfind) {//找到长边优先适合放入的物品 进行保存
minPositionX = min_element(minwasteX, minwasteX + SumNuItem) - minwasteX;
// add[0] = minPositionX; add[1] = 0; // add[1] = 0;无效
}
for (i = 0; i < SumNuItem; i++) minwasteY[i] = max_item_area; //复位最大值
for (i = 0; i < SumNuItem; i++) { // W
if (IfItemUser[i] == 0)
{
if (ItemlenandWid[i][1] == x_limit)
if (ItemlenandWid[i][0] < y_limit) {
minwastex = x_limit - ItemlenandWid[i][1];
minwastey = y_limit - ItemlenandWid[i][0];
minwasteY[i] = minwastex * y_limit - minwastey * x_limit + minwastex * minwastey;//最小的浪费值最小
ifYfind = 1;
}
}
}
if (ifYfind) {//找到长边优先适合放入的物品 进行保存
minPositionY = min_element(minwasteY, minwasteY + SumNuItem) - minwasteY;
// a[6]={1,2,3,4,7,6} minPosition = min_element(a,a+6) - a = 0 下表从 0 开始
}
if (ifXfind || ifYfind) {
//cout << item_id[i] << ' ' << 2 << endl;
if (minwasteY[minPositionY] > minwasteX[minPositionX]) {
IfItemUser[minPositionX] = 1; //保存损失面积小的
add[0] = minPositionX; add[1] = 0;
iwxy[minPositionX][0] = bexy1[add[1]];
iwxy[minPositionX][1] = bexy1[1 - add[1]];
iwxy[minPositionX][2] = add[1];
iwbas[minPositionX][0] = user_board;
bexy1[0] = bexy1[0] + ItemlenandWid[minPositionX][0];
//x_limit = Plate_length - bexy1[0];
//cout << item_id[minPositionX] << ' ' << user_board << ' ' << bexy1[0] << ' ' << bexy1[1] << endl;
}
else {
IfItemUser[minPositionY] = 1;
add[0] = minPositionY; add[1] = 1;
iwxy[minPositionY][0] = bexy1[add[1]];
iwxy[minPositionY][1] = bexy1[1 - add[1]];
iwxy[minPositionY][2] = add[1];
iwbas[minPositionY][0] = user_board;
bexy1[0] = bexy1[0] + ItemlenandWid[minPositionY][0];
//x_limit = Plate_length - bexy1[0];
//cout << item_id[minPositionY] << ' ' << user_board << ' ' << bexy1[1] << ' ' << bexy1[0] << endl;
//cout << item_id[i] << ' ' << 2 << endl;
}
return i;
}
return Fail;
}
return 0;
}
int SizeItemBeenArrange() {
int sum = 0;
for (int i = 0; i < SumNuItem; i++)
sum += IfItemUser[i];
// cout<<sum;
return sum;
}
int Utilization(int nu)//利用率
{
float area = 0;
for (int i = 0; i <= SumNuItem; i++)
area += ItemlenandWid[i][0] * ItemlenandWid[i][1];
cout << (area / (user_board * max_item_area)) << ' ' << user_board << endl;
return 0;
}
int ProcessOfArrage(float XY[2], float bexy[2])
{
//cout << "StartXY " << bexy[0] << ' ' << bexy[1] << endl;
int upgran1 = 0, additemnu[2] = { 0,0 }, ifmatch = 0, state = 0; //additemnu数组 0位代表 个体编号 1位置 0代表长 1代表宽
float x[2] = { 0,0 }, y[2] = { 0,0 }, b = 0;
float plate_length = XY[0], plate_width = XY[1];
if (Fail != SearchMatchItem(plate_length, plate_width, 0, additemnu, bexy))//搜索状态 0仅搜索长 1,2 严格 非严格长宽混合搜索
{
x[0] = plate_length - ItemlenandWid[additemnu[0]][additemnu[1]]; //第一刀 条内长度限定
y[0] = ItemlenandWid[additemnu[0]][1 - additemnu[1]]; //第一刀 条内宽度限定
XY[1] = plate_width - y[0];//剩余条Y长度
ifmatch += 1;
bexy[0] = ItemlenandWid[additemnu[0]][additemnu[1]]; //调整x位置
b = bexy[1] + ItemlenandWid[additemnu[0]][1 - additemnu[1]]; //剩余条起始Y坐标
//cout << "b " << bexy[0] << ' ' <<b<< endl;
}
//Y分割出的条长 宽度
state = 1;
while (Fail != SearchMatchItem(x[0], y[0], state, additemnu, bexy))// 1 严格长宽混合搜索 二阶段 堆内搜索 向上搜索 X轴长度不变 不更新
{
ifmatch += 1;//当等于1时 说明匹配了
if (state != 1)x[0] = x[0] - ItemlenandWid[additemnu[0]][additemnu[1]]; //1 严格长宽混合搜索 向上搜索 X轴长度不变 不更新
y[1] = y[0] - ItemlenandWid[additemnu[0]][1 - additemnu[1]]; //堆内搜索
y[0] = y[1];
// bexy[0] = bexy[0] + ItemlenandWid[additemnu[0]][additemnu[1]];//X轴长度不变 不更新
bexy[1] = bexy[1] + ItemlenandWid[additemnu[0]][1 - additemnu[1]]; //向上搜索 X轴长度不变 更新Y轴
x[0] = 0;
upgran1 = 1;
}
//cout << user_board << ' ' << bexy[0] << ' ' << bexy[1] << endl;
//if (ifmatch)x[0] = 0;
if (x[0] > 0) {
if (upgran1 == 1)
bexy[0] = bexy[0] + ItemlenandWid[additemnu[0]][additemnu[1]];
// bexy[1] = 0;
//cout << user_board << ' ' << bexy[0] << ' ' << bexy[1] << endl;
while (Fail != SearchMatchItem(x[0], y[0], 2, additemnu, bexy)) //2非严格长宽混合搜索 堆内 只能放置一个 运行完完成本条内的搜索
{
x[0] = Plate_length - bexy[0];
ifmatch += 1;
}
}
if (b != 0)
bexy[1] = b;
bexy[0] = 0;
return ifmatch;
}
//int SumItNumberOfBeach(int i)
int IfCanMerge(int Itema,int Itemb)
{
int batch ;
batch = orderWhichBetch[Itema];
float SumArea=0, SumItem = 0;
for (int i = 0; i < OrderNUM; i++)
if (orderWhichBetch[i] == batch)
{
SumItem += sois[i][0];
}
SumItem += sois[Itemb][0];
if (SumItem < max_item_num)
{
for (int i = 0; i < OrderNUM; i++)
if (orderWhichBetch[i] == batch)
{
SumArea += sois[i][1];
}
SumArea += sois[Itemb][1];
if (SumArea < max_item_area)
return 1;
}
return 0;
}
int Inintsolution()//批次编号以批次内第一个订单编号代表同一批次内 编号相同 orderWhichBetch[j]
{
int a;
int i;
for ( i = 0; i < OrderNUM; i++)orderIfArrange[i] = 0;
for ( i = 0; i < OrderNUM; i++)orderWhichBetch[i] = i+1;//默认初始每个订单一个批次 输出的时候考虑加1
for( i=0;i< OrderNUM;i++)
{
if (orderIfArrange[i] == 1) continue;
{
orderIfArrange[i] = 1;//是否安排批次
SumBetch++;
}
for (int j = 0; j < OrderNUM; j++)
{
if (i == j) continue;
if (!orderIfArrange[j]) {
if (IfCanMerge(i, j)) {
orderIfArrange[j] = 1;
orderWhichBetch[j] = orderWhichBetch[i];
}
}
}
}
//for (int i = 0; i < OrderNUM; i++)
// cout << orderWhichBetch[i] << endl;
cout <<"总批次 "<< SumBetch << endl;
return 0;
}
void ItemProjectBetchMaterialStrToNu()
{
for (int i = 0; i < SumNuItem; i++)
;
}
int Typesetting(int a)
{//首先搜寻同批次所有 产品 其次搜索 同材质产品 进行排版 先放面积最大的
// for(int i =0;i<SumNuItem;i++)
int *index;
if(a==0)
for (int z = 0; z < SumNuItem; z++)
{
index = find(BetchBeenProd, BetchBeenProd + SumBetch, orderWhichBetch[z]);
if ((index - BetchBeenProd) == SumBetch)//未找到加入
{
for (int m = 0; m < SumBetch; m++)
{
if (BetchBeenProd[m] == 0)
{
BetchBeenProd[m] = orderWhichBetch[z];
//cout <<"Typesetting "<<SumBetch<<" "<<BetchBeenProd[m] << endl;
return BetchBeenProd[m];
}
}
return 0;
}
}
else if (a == 1)
{
cout << 'a' << endl;
}
//for (int m = 0; m < SumBetch; m++)
// cout << BetchBeenProd[m] << endl;
return 0;
}
int productionm(int aa)
{
string BetchHaveOrder[600];
int a=0;
//并搜寻所有该批次内的板 进行标志位修改, 其次,对该排版内的相同材质的产品进行 标志位修改
//搜寻所有相同材质板进行排版,并修改已拍版标志位, 循环 查找下一材质进行 排版 直至本批次内的产品排版完成
//对下一批次进行排版 最终完成所有排版
//搜寻匹配的
//找到该批次内相同的订单并存放
//cout <<"productionm "<<' ' << ' ' << endl; //return 0;
for (int i = 0; i < SumBetch; i++)//SumNuItem
{
//if (order[orderWhichBetch[i]].compare(order[BetchBeenProd[aa]]) == 0)
// cout << orderWhichBetch[i] << endl;
if (orderWhichBetch[i]==aa)
{
//该批次加入待生产
//a++;
cout << a << ' ' << item_order[orderWhichBetch[i]] << endl;
//cout << ' ' << orderWhichBetch[i] << endl;
}
}
return 0;
}
int main()
{
int a,b=0,gradation = 1, Ifmatch = 0; //additemnu数组 0位代表 个体编号 1位置 0代表长 1代表宽
float XY[2];//条内长度 XY[0]=X,XY[1]=Y分割出的条长 宽度
// XY[0]=Plate_length;XY[1]= Plate_width;
SumNuItem = ReadDataFile("dataBSum.csv");
Inintsolution();//求出初始解
// return 0;
//ItemProjectBetchMaterialStrToNu();
for (int i = 0; i < SumNuItem; i++)IfItemProd[i] = 0; //所有产品均设为未生产
while (1)
{
//已经排版的序列中与未排版的序列进行比对 找出已拍版中未有序列 加入已拍版
//并搜寻所有该排版内的板 进行标志位修改, 其次,对该排版内的相同材质的产品进行 标志位修改
//搜寻所有相同材质板进行排版,并修改已拍版标志位, 循环 查找下一材质进行 排版 直至本批次内的产品排版完成
//对下一批次进行排版 最终完成所有排版
//if (BetchBeenProd[j] == 0) //寻找一个未排版的批次
a = Typesetting(0);//搜索到未生产的批次
//for (int m = 0; m < SumBetch; m++)
//cout << BetchBeenProd[m] << endl;
if (a<= SumBetch)
{ //a为未生产批次 接下来进行生产
//cout << a << endl;
productionm(a);
// return 0;
}
else
{
return 0;
}
}
if(0){
while (SizeItemBeenArrange())
{ //一阶段 分条 已经切条 剩余条内最高由Y限定 float plate_length, float plate_width ,
// cout<<SizeItemBeenArrange()<<' '<<SumNuItem<<endl;
//分配新板材
XY[0] = Plate_length; XY[1] = Plate_width;
StartXY[0] = 0;
StartXY[1] = 0;
user_board++;
Ifmatch = ProcessOfArrage(XY, StartXY); //一条 处理完成 接下来处理剩下的条
//cout << "StartXY" << StartXY[0] << ' ' << StartXY[1] << endl;
// for(int i=0;i<SumNuItem;i++)cout << IfItemUser[i] << ' ' << endl;
while (0 < ProcessOfArrage(XY, StartXY)) //剩余条继续处理 直到无法切割
{
//cout << "StartXY" << StartXY[0] << ' ' << StartXY[1] << endl;
}
}
Utilization(user_board);
}
SaveDataFile("cut_program.csv");
return 0;
}
第一次参加,没选好题,效果一般。附件为代码及论文内容,纪念意义。