回溯法解决板材切割最优化问题(C++)

对一个大矩形板材做切割,切割为小矩形板材,目的是使板材利用率最大,小矩形的规格有四种。

因为不能穷举,故使用了随机量进行切割。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

#define COUNT 3000

string mode1 = "";  // 记录某次切割的方案 
string mode2 = "";  // 记录最优切割的方案 
int total, total1, total2, total3, total4;  // 记录某次的最大面积,和此时各个板的数量 
int max_, max_1, max_2, max_3, max_4;       // 记录当前的最大值面积,和此时各个版的数量 
int random;         // 定义随机变量 
int Slong1 = 373;   // 定义小矩形长宽 
int Swide1 = 201; 
int Slong2 = 477;
int Swide2 = 282;
int Slong3 = 406;
int Swide3 = 229; 
int Slong4 = 311;
int Swide4 = 225;
int Area1 = Slong1 * Swide1;  // 定义小矩形面积 
int Area2 = Slong2 * Swide2;
int Area3 = Slong3 * Swide3;
int Area4 = Slong4 * Swide4;

struct node{
	double p;                          // 本切割模式下的利用率 
	string mode;                       // 切割模式 
 	int max_1, max_2, max_3, max_4;    // 本切割模式下P1 P2 P3 P4的数量 
	// 重载 < 
	const bool operator < (const node &t)const{ 
		return p>t.p;	
	} 
};

setMax;                 // 对每次循环得到的最优值进行记录 
 
void T4(int Blong, int Bwide)
{
	random = rand()%4 + 1;
	
	if(random == 1){  // 切1 
		// 切割方式1:大矩形横向切割,小矩形纵向放置 
		if(Blong>=Swide1 && Bwide>=Slong1){
			int n = Blong/Swide1;  // 本次切割的数量 
			total = total + Area1*n;
			total1 = total1 + n;
			mode1 = mode1 + "$1";
			T4(Blong, Bwide-Slong1);
			total = total - Area1*n;
			total1 = total1 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式2:大矩形横向切割,小矩形横向放置 
		if(Blong>=Slong1 && Bwide>=Swide1){
			int n = Blong/Slong1;  // 本次切割的数量 
			total = total + Area1*n;
			total1 = total1 + n;
			mode1 = mode1 + "$2";
			T4(Blong, Bwide-Swide1);
			total = total - Area1*n;
			total1 = total1 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式3:大矩形纵向切割,小矩形纵向放置 
		if(Blong>=Swide1 && Bwide>=Slong1){
			int n = Bwide/Slong1;  // 本次切割的数量
			total = total + Area1*n;
			total1 = total1 + n;
			mode1 = mode1 + "$3";
			T4(Blong-Swide1, Bwide);
			total = total - Area1*n;
			total1 = total1 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式4:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Slong1 && Bwide>=Swide1){
			int n = Bwide/Swide1;  // 本次切割的数量
			total = total + Area1*n;
			total1 = total1 + n;
			mode1 = mode1 + "$4";
			T4(Blong-Slong1, Bwide);
			total = total - Area1*n;
			total1 = total1 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录 
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
	}
	else if(random == 2){  // 切2
		// 切割方式1:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Swide2 && Bwide>=Slong2){
			int n = Blong/Swide2;  // 本次切割的数量 
			total = total + Area2*n;
			total2 = total2 + n;
			mode1 = mode1 + "*1";
			T4(Blong, Bwide-Slong2);
			total = total - Area2*n;
			total2 = total2 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式2:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Slong2 && Bwide>=Swide2){
			int n = Blong/Slong2;  // 本次切割的数量 
			total = total + Area2*n;
			total2 = total2 + n;
			mode1 = mode1 + "*2";
			T4(Blong, Bwide-Swide2);
			total = total - Area2*n;
			total2 = total2 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式3:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Swide2 && Bwide>=Slong2){
			int n = Bwide/Slong2;  // 本次切割的数量
			total = total + Area2*n;
			total2 = total2 + n;
			mode1 = mode1 + "*3";
			T4(Blong-Swide2, Bwide);
			total = total - Area2*n;
			total2 = total2 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式4:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Slong2 && Bwide>=Swide2){
			int n = Bwide/Swide2;  // 本次切割的数量
			total = total + Area2*n;
			total2 = total2 + n;
			mode1 = mode1 + "*4";
			T4(Blong-Slong2, Bwide);
			total = total - Area2*n;
			total2 = total2 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录 
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
	} 
	else if(random==3){  // 切3 
		// 切割方式1:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Swide3 && Bwide>=Slong3){
			int n = Blong/Swide3;  // 本次切割的数量 
			total = total + Area3*n;
			total3 = total3 + n;
			mode1 = mode1 + "_1";
			T4(Blong, Bwide-Slong3);
			total = total - Area3*n;
			total3 = total3 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式2:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Slong3 && Bwide>=Swide3){
			int n = Blong/Slong3;  // 本次切割的数量 
			total = total + Area3*n;
			total3 = total3 + n;
			mode1 = mode1 + "_2";
			T4(Blong, Bwide-Swide3);
			total = total - Area3*n;
			total3 = total3 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式3:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Swide3 && Bwide>=Slong3){
			int n = Bwide/Slong3;  // 本次切割的数量
			total = total + Area3*n;
			total3 = total3 + n;
			mode1 = mode1 + "_3";
			T4(Blong-Swide3, Bwide);
			total = total - Area3*n;
			total3 = total3 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式4:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Slong3 && Bwide>=Swide3){
			int n = Bwide/Swide3;  // 本次切割的数量
			total = total + Area3*n;
			total3 = total3 + n;
			mode1 = mode1 + "_4";
			T4(Blong-Slong3, Bwide);
			total = total - Area3*n;
			total3 = total3 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录 
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
	} 
	else {  // 切4 
		// 切割方式1:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Swide4 && Bwide>=Slong4){
			int n = Blong/Swide4;  // 本次切割的数量 
			total = total + Area4*n;
			total4 = total4 + n;
			mode1 = mode1 + "#1";
			T4(Blong, Bwide-Slong4);
			total = total - Area4*n;
			total4 = total4 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式2:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Slong4 && Bwide>=Swide4){
			int n = Blong/Slong4;  // 本次切割的数量 
			total = total + Area4*n;
			total4 = total4 + n;
			mode1 = mode1 + "#2";
			T4(Blong, Bwide-Swide4);
			total = total - Area4*n;
			total4 = total4 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式3:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Swide4 && Bwide>=Slong4){
			int n = Bwide/Slong4;  // 本次切割的数量
			total = total + Area4*n;
			total4 = total4 + n;
			mode1 = mode1 + "#3";
			T4(Blong-Swide4, Bwide);
			total = total - Area4*n;
			total4 = total4 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
		// 切割方式4:大矩形纵向切割,小矩形横向放置 
		if(Blong>=Slong4 && Bwide>=Swide4){
			int n = Bwide/Swide4;  // 本次切割的数量
			total = total + Area4*n;
			total4 = total4 + n;
			mode1 = mode1 + "*4";
			T4(Blong-Slong4, Bwide);
			total = total - Area4*n;
			total4 = total4 - n;
			mode1 = mode1.substr(0, mode1.length()-2); 
		}
		else if(max_ < total){  // 到了终点了,如果好,记录 
			max_ = total;
			max_1 = total1;
			max_2 = total2;
			max_3 = total3;
			max_4 = total4;
			mode2 = mode1;
		}
	}
}

int main()
{
	freopen("test4_1234.txt", "w", stdout);
	
	cout<<"每3行为1组,每组第1行为利用率,第2行为切割模式,第3行为各个板子的切割数量"<::iterator it;
    for(it = Max.begin(); it != Max.end(); it++){
        cout<p<mode<max_1<max_2<max_3<max_4<

 

你可能感兴趣的:(回溯法解决板材切割最优化问题(C++))