石材切割1------简单递归
问题描述
给定一个最大的总切割目标石块,再给定一系列我们需要的样板石块。寻找切割方法使得我们从目标石块上切割出的所需样板石块的面积和最大,即对目标石块的利用率最高。限制切割为一刀切,即一次切割必须把一块石板一分为二,不能只切一段。
算法设计
将所需的样板模块按照面积从大到小进行排序,每次取最大并且可以切割的那块进行切割,在数据量非常大的情况下,单步的最优利用率可能导致全局的最优利用率。首先读入数据,将待切割的石块存入details中。进行递归切割,如果待切割的石块和样板的长度相等,则从宽度上切割,如果宽度相等,则从长度上进行切割。如果长度,宽度都小于,则优先从宽度上切割。
python代码实现
main_sheet = {
'l': 0,
'w': 0,
's': 0
}
main_sheet_square = 0 # 总面积
details = list()
details_square = 0 #小石块面积
#判空
def isempty():
for i in details:
if i['flag'] == 0:
return False
return True
#获取信息
def get_details():
f = open('nice1.txt', 'r')
global details_square, main_sheet_square, details
l = f.readline().split()
main_sheet['l'] = (int)(input("输入石板的长:"))
main_sheet['w'] = (int)(input("输入石板的宽:"))
main_sheet_square = main_sheet['l'] * main_sheet['w']
for line in f:
s = line.split()
detail_length = int(s[0])
detail_width = int(s[1])
detail_square = detail_length*detail_width
if detail_length < detail_width: #保证长比宽大
detail_length, detail_width = detail_width, detail_length
details.append({
'l': detail_length,
'w': detail_width,
's':detail_square,
'flag':0
})
details_square += detail_length * detail_width
details = sorted(details, key=lambda item: (-item['l']*item['w'], -item['l'])) #按面积大小排序
def TooSmall(l,w):
for i in details:
if (i['l']<=l and i['w']<=w and i['flag']==0):
return False
return True
def cut(l,w):
if(isempty()==True):
return True
if(TooSmall(l,w)==True):
return False
for i in range(len(details)):
if details[i]['flag']!=1 and details[i]['l']<=l and details[i]['w']<=w:
break
if(details[i]['l']==l):
details[i]['flag'] = 1
cut(l,w-details[i]['w'])
elif(details[i]['w']==w):
details[i]['flag'] = 1
cut(l-details[i]['l'],w)
elif(details[i]['w']< w and details[i]['l']<l):
cut(l,details[i]['w'])
cut(l,w-details[i]['w'])
area = 0
def display():
global area
for item in details:
if(item['flag']==1):
print(item['l'],"*",item['w'])
print(item['s'])
area += item['s']
else:
print("no")
get_details()
# print(details)
#isempty()
cut(main_sheet['l'],main_sheet['w'])
print(details)
display()
print("利用率",area/main_sheet_square)
nice1数据
549 154
319 254
170 433
166 433
226 313
133 433
124 433
195 254
179 274
151 301
135 313
228 158
206 158
122 254
179 159
273 99
92 254
77 301
273 83
273 72
115 158
228 72
90 172
228 60
90 140
结果
不足
得到的实验结果其实不是最优解,也没有记录切割方法,效率较低,将在后续寻找更好的解法