记录第一次参加2022年“华为杯”第十九届中国研究生数学建模竞赛赛题B题的工作

记录下代码工作,代码是从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;
}

第一次参加,没选好题,效果一般。附件为代码及论文内容,纪念意义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangxiaojie6688

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值