You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遍历3D数组添加容器ID时出现重复值问题求助

Ship[4] 3D数组重复值问题排查与修复

问题背景

需要将容器ID写入ship[4]三维数组的指定(i,j,k)位置,实现相关函数后,测试发现ship[4]中出现大量重复值,需定位并解决该问题。

实现代码

核心函数

def addContainerOnShip(ship,container):
    place = findPlace(ship,container)
    if place == False:
        return False
    ship[3].append(container)
    id = getIdContainer(container)
    deck = place[0][0]
    row = place[0][1]
    position1 = place[0][2]
    if len(place) == 2:
        position2 = place[1][2]
        ship[4][deck][row][position1] = id
        ship[4][deck][row][position2] = id
    elif len(place) == 1:
        ship[4][deck][row][position1] = id
    else: 
        return False
    return True

def findPlace(ship, container): #rowsene øker ikke. 
    for i in range(getHeightShip(ship)-1):
        deck = ship[4][i]
        if getLengthContainer(container) == 20:
            for j in range(getWidthShip(ship)):
                row = deck[j]
                for k in range(getLengthShip(ship)-1):
                    position = row[k]
                    if position == 0 and isContainerBelow(ship, [i, j, k]): 
                       return [[i, j, k]] #doble lister fordi den kjører på to elementer
                    k+=1
        elif getLengthContainer(container) == 40:
            for j in range(getWidthShip(ship)):
                row = deck[j]
                for k in range(getLengthShip(ship)-2):
                    position1 = row[k]
                    position2 = row[k+1]
                    if (position1 == 0 and position2 == 0 and isContainerBelow(ship, [i,j,k]) and isContainerBelow(ship, [i,j,k+1])):
                        return [[i, j, k],[i, j, k+1]]
                    k+=1
        else:
            return False  

def isContainerBelow(ship, position):
    deck = position[0]
    row = position[1]
    place = position[2]
    positionBelow = ship[4][deck-1][row][place]
    if deck == 0:
        return True
    elif positionBelow == 0: #there is nothing under here 
        return False
    else: 
        return True

测试代码与输出

测试代码

randomContainers(containers) #随机生成10个容器
skip1 = NewShip(6,5,4)
makeDeck(skip1)
con = NewContainer(1111,40,3)
sortContainersWeight(containers)
for el in containers:
    print(el)
    print(addContainerOnShip(skip1,el))
    print(findPlace(skip1,con))

print(skip1[4])

输出结果

[307813, 20, 2, 0, 2]
True
[[0, 0, 1], [0, 0, 2]]
[3779799, 20, 2, 2, 4]
True
[[0, 0, 2], [0, 0, 3]]
[9725995, 20, 2, 6, 8]
True
[[0, 0, 3], [0, 0, 4]]
[7275339, 40, 4, 6, 10]
True
[[1, 0, 0], [1, 0, 1]]
[4210939, 40, 4, 8, 12]
True
[[1, 0, 2], [1, 0, 3]]
[2058645, 40, 4, 11, 15]
True
[[1, 1, 0], [1, 1, 1]]
[4558888, 20, 2, 13, 15]
True
[[1, 1, 0], [1, 1, 1]]
[9093612, 40, 4, 16, 20]
True
[[1, 1, 2], [1, 1, 3]]
[2733982, 20, 2, 19, 21]
True
[[1, 1, 3], [1, 1, 4]]
[6156045, 20, 2, 22, 24]
True
[[1, 2, 0], [1, 2, 1]]
[[[307813, 3779799, 9725995, 7275339, 7275339], [307813, 3779799, 9725995, 7275339, 7275339], [307813, 3779799, 9725995, 7275339, 7275339], [307813, 3779799, 9725995, 7275339, 7275339], [307813, 3779799, 9725995, 7275339, 7275339], [307813, 3779799, 9725995, 7275339, 7275339]], [[4210939, 4210939, 2058645, 2058645, 4558888], [9093612, 9093612, 2733982, 6156045, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]], [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]], [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]

问题定位

  1. 数组初始化引用重复:输出显示ship[4]第一个甲板的所有行内容完全一致,原因是makeDeck初始化时所有行复用了同一个列表对象,修改任意一行都会同步影响其他行。
  2. findPlace循环逻辑错误:遍历位置时手动执行k +=1,叠加for循环的自动递增,导致k每次增加2,跳过大量位置,同时可能错误重复选择区域。
  3. 甲板遍历范围错误:for i in range(getHeightShip(ship)-1)会跳过最后一个甲板,导致容器无法被放置到上层甲板。

修复方案

1. 修复makeDeck的数组初始化

确保每个行都是独立列表,避免引用复用:

def makeDeck(ship):
    height = getHeightShip(ship)
    width = getWidthShip(ship)
    length = getLengthShip(ship)
    ship[4] = []
    for _ in range(height):
        deck = []
        for _ in range(width):
            # 为每行创建独立的初始列表
            deck.append([0]*length)
        ship[4].append(deck)

2. 修复findPlace的循环逻辑

移除手动k +=1,修正遍历范围:

def findPlace(ship, container):
    # 遍历所有甲板,从底层开始
    for i in range(getHeightShip(ship)):
        deck = ship[4][i]
        if getLengthContainer(container) == 20:
            for j in range(getWidthShip(ship)):
                row = deck[j]
                # 遍历所有合法位置
                for k in range(getLengthShip(ship)):
                    position = row[k]
                    if position == 0 and isContainerBelow(ship, [i, j, k]): 
                        return [[i, j, k]]
        elif getLengthContainer(container) == 40:
            for j in range(getWidthShip(ship)):
                row = deck[j]
                # 遍历到倒数第二个位置即可
                for k in range(getLengthShip(ship)-1):
                    position1 = row[k]
                    position2 = row[k+1]
                    if (position1 == 0 and position2 == 0 
                        and isContainerBelow(ship, [i,j,k]) 
                        and isContainerBelow(ship, [i,j,k+1])):
                        return [[i, j, k],[i, j, k+1]]
        else:
            return False  

3. 完善isContainerBelow的边界处理

避免deck=0时访问非法索引,逻辑更严谨:

def isContainerBelow(ship, position):
    deck = position[0]
    row = position[1]
    place = position[2]
    if deck == 0:
        return True
    # 确保下层甲板索引合法
    if deck-1 < 0 or deck-1 >= len(ship[4]):
        return False
    positionBelow = ship[4][deck-1][row][place]
    return positionBelow != 0

验证修复

重新运行测试代码,ship[4]的各行列应仅在对应位置出现容器ID,不再出现全行列重复的情况。

内容的提问来源于stack exchange,提问作者marfin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:05:20