集装箱货运是国际货物运输的主要方式之一,在进行码头运货时,会先将不同类型的物品都装入集装箱,然后再统一运送。
集装箱通常有统一的规格。本关挑战是需要你设计算法,要求将码头已有的多种类型的货物使用给定规格的集装箱进行组合装箱,并使得集装箱的载重和空间利用率尽可能的高。
假设货运码头仅有一种规格的集装箱,其体积是56
立方米,最多能放入重量为128
千克的物品。该码头支持运输的物品有7
种类型,各种类型物品的具体规格尺寸等信息如下:
类型 | 体积(立方米) | 重量(千克) |
---|---|---|
type1 | 2 | 2 |
type2 | 2 | 8 |
type3 | 4 | 16 |
type4 | 8 | 32 |
type5 | 16 | 16 |
type6 | 16 | 32 |
type7 | 16 | 64 |
现在,该码头有多个不同类型的物品(具体物品的类型和数量由程序输入给定)需要全部装入多个该规格的集装箱进行运输。集装箱可以选择多个,没有数量限制,但是在选择物品装箱时要考虑装箱物品的总重量和总体积不能够超过单个箱子的重量和体积。
请你设计一种方法,将给定数量的多个不同种类的物品放入集装箱中,使得集装箱的利用率最高。利用率计算方式是体积和重量利用率各占一半,具体计算公式如下:
其中,
VRes_i
表示第 i
个物品的体积资源WRes_i
表示第 i
个物品的重量资源VBox_j
表示放置的第 j
个箱子的体积总资源WBox_j
表示放置的第 j
个箱子的重量总资源。编程要求
请补充完善右侧代码区域中的put_things(box_info,input_lines)
函数,实现物品装箱计算,并将最终装箱组合结果存入result
数组。 其中,
box_info
为集装箱的信息数值,具体格式如下:
[体积,重量]
例如:
[56, 128]
input_lines
为要放置的物品,物品种类以及数量数值为元组类型,具体格式如下:
[(‘type1’,数量), (‘type2’,数量), (‘type3’,数量)…(‘type7’,数量)]
例如:
[('type1',1), ('type2',2), ('type3',2), ('type4',1), ('type5',2), ('type6',2), ('type7',2)]
result
为物品装箱组合结果数组,数组的长度即集装箱个数,每一个数组元素为某个集装箱中放置的物品和物品个数。具体格式如下:
['物品1 物品1的个数 物品2 物品2的个数', '物品3 物品3的个数 物品5 物品5的个数']
例如,
result = ['type4 1 type2 2 type3 2 type5 2 type1 1', 'type7 1 type6 2', 'type7 1']
评测说明
测试样例为:
测试输入:
box_info = [56, 128]
input_lines = [('type1',255), ('type2',213), ('type3',248), ('type4',232), ('type5',76), ('type6',281), ('type7',30)]
测试输出格式如下:
return = ['物品1 物品1的个数 物品2 物品2的个数', '物品3 物品3的个数 物品5 物品5的个数'...]
计分规则:
本次挑战总分500
分,最终得分根据集装箱利用率进行换算。具体换算方法如下:
score = Usage * 500
#官方参考答案
def put_things(box_info, input_lines):
result = []
'''**********BEGIN***********'''
result = start(input_lines,56,128)
'''***********END************'''
return result
class Backpack():
'''描述箱子信息:总weight、总volume、可用weight、可用volume、已存放的物品列表'''
def __init__(self, weight, volume):
self.total_weight = weight
self.total_volume = volume
self.free_weight = weight
self.free_volume = volume
self.types = []
def put_type(self, type):
if self.free_volume >= type.volume and self.free_weight >= type.weight:
self.free_volume -= type.volume
self.free_weight -= type.weight
self.types.append(type)
return True
return False
class Type():
'''描述物品类型:物品名字、体积、重量'''
def __init__(self, type_name, type_volume, type_weight):
# type: (object, object, object) -> object
self.name = type_name
self.weight = type_weight
self.volume = type_volume
def put_types_to_backpacks(map_num_types, map_type_volume_weight, backpack_volume, backpack_weight):
'''firstfit放置'''
thing_types = []
thing_type = []
backpacks = []
#将输入的物品数据展开
for map_puts_types in map_num_types:
map_type_puts_num = int(map_num_types[map_puts_types])
while map_type_puts_num != 0:
map_type_puts_num -= 1
thing_type.append(map_puts_types)
# print("thing_type", thing_type)
#将thing_type类化
for thing in thing_type:
thing_types.append(map_type_volume_weight[thing])
# print("thin_types", thing_types)
#第一个箱子
first_bp = Backpack(backpack_weight, backpack_volume)
backpacks.append(first_bp)
#开始放置
for type in thing_types:
flag = True
for i in range(0, len(backpacks)):
if backpacks[i].put_type(type):
flag = False
break
if flag == True:
bp = Backpack(backpack_weight, backpack_volume)
bp.put_type(type)
backpacks.append(bp)
return backpacks
def start(res, volume_size, weight_size):
things_put_data = {}
for res_elemet in res:
type = res_elemet[0]
type_number = res_elemet[1]
things_put_data[type] = type_number
# 各种物品参数
map_type_volume_weight = {}
map_type_volume_weight["type1"] = Type("type1", 2, 2)
map_type_volume_weight["type2"] = Type("type2", 2, 8)
map_type_volume_weight["type3"] = Type("type3", 4, 16)
map_type_volume_weight["type4"] = Type("type4", 8, 32)
map_type_volume_weight["type5"] = Type("type5", 16, 16)
map_type_volume_weight["type6"] = Type("type6", 16, 32)
map_type_volume_weight["type7"] = Type("type7", 16, 64)
# print(map_type_volume_weight.values())
# 箱子资源相关信息
backpack_volume = volume_size
backpack_weight = weight_size
# 调用放置算法
backpacks = put_types_to_backpacks(things_put_data, map_type_volume_weight, backpack_volume, backpack_weight)
result_array = []
#将箱子中的物品放置结果存至result
for element in backpacks:
flag = 1
result_string = ""
type_dic = {}
for type in element.types:
# print(type.name)
type_name = type.name
# if type_dic.has_key(type_name):
if type_dic.__contains__(type_name):
type_dic[type_name] += 1
else:
type_dic[type_name] = 1
for t_dic in type_dic:
if flag == 1:
result_string += t_dic + " " + str(type_dic[t_dic])
flag = 0
else:
result_string += " " + t_dic + " " + str(type_dic[t_dic])
result_array.append(result_string)
return result_array
put_things([56, 128],[('type1',255), ('type2',213), ('type3',248), ('type4',232), ('type5',76), ('type6',281), ('type7',30)])
emmmm,好难哦,学习了一下0-1背包问题,完全背包问题,答案只用了两百多个箱子,而我用了500多个,于是系统没法评分了。。。真是sad