⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readme.txt

📁 给定一块宽度为W的矩形板
💻 TXT
字号:
                 实验一    零件切割问题
      实验者:李均荣 04120043
一、问题描述:
  给定一块宽度为W的矩形板,矩形板的高度不受限制。现需要从板上分别切割出n个高度为hi,宽度为wi的矩形零件。切割的规则是零件的高度方向与矩形板的高度方向保持一致。问如何切割使得所使用的矩形板的高度h最小?

     

    问题等价于往一个宽为W、高不限的盒子里放木板,使得所用高度最小。

二、基本思路:
    先将木板用快排的方法按高度由高到底排列,然后依次放进盒子里。要放第i块时先比较剩下的宽度,如果木板宽度小于剩下的宽度,就将第i块木板放在第i-1块右边,否则垒在当前最高块的上面。然后对该层剩下的做递归调用,如此进行下去可得一个可行解。
                  最优解    可行解  
16.txt:n=16;W=20;     H=15;   31	
25.txt:n=25;W=40;     H=15;   22
50.txt:n=50;W=40;     H=15;   19
84.txt:n=84;W=225;    H=166;  191	
110.txt:n=110;W=425;  H=52;   62	
156.txt:n=156;W=475;  H=66;   78

关键代码如下:
int DivideBoard(struct graph a[],int i,int leftw,int W,int n)
{
     if(i==n){return 1;}
     else
	 {
       if(a[i].weith<=leftw){
         H=H;
         leftw=leftw-a[i].weith;
         i++;
         DivideBoard(a,i,leftw,W,n);
       }
       else
	   {
         H=H+a[i].height;
         leftw=W-a[i].weith;
         i++;
         DivideBoard(a,i,leftw,W,n);   
	   }        
     }
     
}
分析:
   由于按顺序存放故空间浪费较大,比如若第k块较宽以至于剩余的宽度容不下,那么这块就要放到当前最高块的上方,但实际上可能存在这样的块,其高度比第k块小(排在第k块的后面),宽度也比较小,适合放在第k-1块的右边。这种做法的时间主要花费在快排上,所以时间复杂度为O(nlog n)。


改进:
   在基本思路的基础上增加一步,若第k块较宽以至于不能放在第k-1块的右边,那么就从剩下的零件中找第一块适合放在该位置的零件放进去,然后将第k块放在当前最高块的上面。改进之后得到的可行解如下:
16.txt:n=16;W=20;     H=15;    26	
25.txt:n=25;W=40;     H=15;    22      
50.txt:n=50;W=40;     H=15;    19      
84.txt:n=84;W=225;    H=166;   179	
110.txt:n=110;W=425;  H=52;    61  	
156.txt:n=156;W=475;  H=66;    77	

关键代码如下:
int DivideBoard(struct graph a[],int i,int leftw,int W,int n)
{
     int j,k;
	 struct graph temp;
     if(i==n){return 1;}
     else
	 {
       if(a[i].weith<=leftw){
         H=H;
         leftw=leftw-a[i].weith;
         i++;
         DivideBoard(a,i,leftw,W,n);
       }
       else
	   {
		   j=i+1;
		   while(j<n)
		   {
			   if(a[j].weith<leftw)
			   {
				   H=H;
				   leftw=leftw-a[j].weith;
                   for(k=j+1;k<n;k++)
				   {
					   a[k-1]=a[k];
					   a[k].weith=0;
					   a[k].height=0;
				   }
				   break;
			   }
			   else
			   {
				   j++;
			   }
		   }
          H=H+a[i].height;
		   leftw=W-a[i].weith;
		   i++;
          DivideBoard(a,i+1,leftw,W,n);
	   }        
     }
}
分析:
   这种方法在前一种基础上对16.txt和84.txt文档的测试数据有较明显的改进,但是仍有很大的浪费空间。这种方法只是找到一块适合放在右边的木板放进去,然后就对当前最大高度以上的空间分治递归,因此改进比较小。但由于在寻找第一个适合的块,故时间复杂度增加了,为O(n*n)。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -