想请问一下这个翻箱咋做呀,写不来代码,可不可以帮助一下,问题如图所示,非常感谢大家😊

(1)如图 1 所示,按箱子进入顺序依次放入位置,使得箱子按顺序提出的
时候,翻箱数量和操作数量最少?
(2)问题推广:如何将给定进出顺序的 个箱子放入给定的
位置中,
使得取箱最方便?

img

img

看着就麻烦的死,钱不够呀

这是一个有趣的问题,我尝试着写了一个算法,供题主参考。

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

请按任意键继续. . .

之前有见过这个问题,也试着解过,不过之前的题主只要求思路,我看你这是要代码的,代码都要什么功能?入箱出箱过程,以及翻箱数量和操作数量统计都得实现吗?还是说只完成入箱和结果展示就行,毕竟出箱过程目测口算比较容易,代码实现还挺麻烦的