1 问题描述
在给定长宽的石板上切割出n个wi*li的石砖,需满足长度方向不变及一刀切约束,求解最大利用率。
2 算法设计
2.1 变(常)量名约定
变(常)量名
说明
MAXSTONE
石砖最大数目
MAXTRY
尝试切割次数
num
实际石砖数目
stone
需要的石砖结构体
acc_area
每一次尝试的面积累计
record
每一次尝试切割的石块记录
use_ratio
每一次尝试的利用率
best
最好情况的尝试编号
2.2 函数说明
函数
说明
void Read (void)
从某txt文件中读取石砖长宽数据
void Sort (void)
对石砖数据进行面积降序排列
int TooSmall (int l,int w)
判断石板是否过小(过小返回1)
int Empty (void)
判断石砖是否全部切割(完毕返回1)
void CutStone (int l,int w,int k)
递归切割石板(k为尝试编号)
int Compare (void)
比较多次切割方法,返回最优切割法序号
void Display (int best)
输出该切割法的切割情况
2.3 递归算法概述
将所需的石砖按照面积从大到小排列,每次取最大的那块进行切割。切割前确认石板是否过小或所需石砖已切割完毕。若石砖长(宽)与石板相同,则按宽(长)来一刀切,若石砖长宽均小于石板长宽,通过随机数来决定从哪个方向来一刀切。通过多次尝试比较,来确认最好的切割方式利用率。
1. void CutStone(int l,int w,int k)
2. {
3. if(Empty() == 1) return; //石砖全部切割完成
4. if(TooSmall(l,w) == 1) return; //石板过小,舍弃
5. int i;
6. for(i=0; i
7. if(stone[i].flag==0 && stone[i].length <= l && stone[i].width <= w) break;
8. if(stone[i].length == l) //若石砖长度与石板相同,则按宽方向一刀切
9. {
10. stone[i].flag = 1; //flag=1表示该块石砖已切割
11. acc_area[k] += stone[i].length*stone[i].width; //累计面积
12. record[k][i] = 1; //记录切割石砖情况
13. CutStone(l,w-stone[i].width,k); //递归切割剩余石板
14. }
15. else if(stone[i].width == w) //若石砖宽度与石板相同,则按长方向