(1)如图 1 所示,按箱子进入顺序依次放入位置,使得箱子按顺序提出的
时候,翻箱数量和操作数量最少?
(2)问题推广:如何将给定进出顺序的 个箱子放入给定的
位置中,
使得取箱最方便?
看着就麻烦的死,钱不够呀
这是一个有趣的问题,我尝试着写了一个算法,供题主参考。
import numpy as np
def get_pos(w, layer, stack, usable):
"""w为箱子取出序号,layer为层号,stack为堆叠方案,usable为每层可用的位置
返回下层取出序号大于w且最接近w的列号;若不存在,则返回下层取出序号小于w且最接近w的列号"""
if layer == 0 or len(usable[layer]) == 1:
return usable[layer].pop() # 最底层或只有一个位置,返回最后一个位置
locs = [(stack[layer-1, loc]-w, loc) for loc in usable[layer]]
locs = sorted(locs, key=lambda x:x[0])
for i in range(1, len(locs)):
if locs[i][0] < 0:
loc = locs[i-1][1]
break
else:
loc = locs[-1][1]
usable[layer].remove(loc)
return loc
def layout(box, r, c):
"""box为各个箱子的取出序号,r为层数,c为每层平铺数
返回箱子的最优堆叠方案"""
n = len(box) # 箱子数量
stack = np.zeros((r, c), dtype=np.uint8) # 堆叠方案,初始为r行c列的全0数组
usable = [[] for i in range(r)] # 每层可用的位置
usable[0] = list(range(c)) # 首层(底层)c个位置可用
for i in box:
row = (n-i)//c # 该箱子最佳匹配层
if usable[row]: # 匹配层层有空位置
loc = get_pos(i, row, stack, usable) # 可用的位置列号
stack[row, loc] = i # 放置箱子
if row < r - 1: # 如果匹配层不是最上层
usable[row+1].append(loc) # 上层增加一个可用位置
elif row > r/2: # 大号,向下优先
k = row - 1 # 向下查找
while k > -1:
if usable[k]: # k层有空位
loc = get_pos(i, k, stack, usable) # 可用的位置列号
stack[k, loc] = i # 放置箱子
usable[k+1].append(loc) # k+1层增加一个可用位置
break
k -= 1
else:
k = row + 1 # 向上查找
while k < r:
if usable[k]: # k层有空位
loc = get_pos(i, k, stack, usable) # 可用的位置列号
stack[k, loc] = i # 放置箱子
if k < r - 1: # 如果k层不是最上层
usable[k+1].append(loc) # k+1增加一个可用位置
break
k += 1
else:
return False # 失败
else: # 小号,向上优先
k = row + 1 # 向上查找
while k < r:
if usable[k]: # k层有空位
loc = get_pos(i, k, stack, usable) # 可用的位置列号
stack[k, loc] = i # 放置箱子
if k < r - 1: # 如果k层不是最上层
usable[k+1].append(loc) # k+1层增加一个可用位置
break
k += 1
else:
k = row - 1 # 向下查找
while k > -1:
if usable[k]: # k层有空位
loc = get_pos(i, k, stack, usable) # 可用的位置列号
stack[k, loc] = i # 放置箱子
usable[k+1].append(loc) # k+1增加一个可用位置
break
k -= 1
else:
return False # 失败
return np.flipud(stack).tolist()
if __name__ == '__main__':
box = [18, 14, 13, 10, 9, 20, 12, 1, 5, 3, 6, 2, 17, 15, 8, 19, 4, 11, 7, 16]
for r, c in [(3,8), (4,6)]: # 测试3行8列、4行6列
print('--------------------------------------------')
print('%d行%d列最佳堆叠方案:'%(r, c))
stack = layout(box, r, c)
if stack:
for line in stack:
for i in line:
if i == 0:
print(' ', end=' ')
elif i < 10:
print(' %d'%i, end=' ')
else:
print(i, end=' ')
print()
else:
print('找不到符合要求的堆叠方案')
测试结果:
--------------------------------------------
3行8列最佳堆叠方案:
4 1 2 6 3
11 7 8 12 5 9 10
16 19 15 17 20 13 14 18
--------------------------------------------
4行6列最佳堆叠方案:
5 2 10
7 4 1 6 13
11 16 8 12 3 14
19 15 17 20 9 18
请按任意键继续. . .
之前有见过这个问题,也试着解过,不过之前的题主只要求思路,我看你这是要代码的,代码都要什么功能?入箱出箱过程,以及翻箱数量和操作数量统计都得实现吗?还是说只完成入箱和结果展示就行,毕竟出箱过程目测口算比较容易,代码实现还挺麻烦的