簡體   English   中英

在 Julia 網格系統性能問題中查找重疊區域

[英]Finding overlapping areas in Julia grid system performance question

我目前正在嘗試計算網格中特定類型的一組位置。 手頭的問題與 2D 打包優化問題有關。

打包物品時,我需要在網格中為該物品選擇一個位置(i,j) 由於項目大小,還可以覆蓋網格中的其他幾個位置。 因此,我需要一個集合Qijc ,這是放置項目 c 可能覆蓋位置(i,j)的正方形集合。 例如,如果項目 c 的大小為 2x2,則Qijc包含{(i,j),(i-1,j-1),(i-1,j),(i,j-1)} 如果項目 c 位於這些位置中的任何一個.. 位置(i,j)也被覆蓋。

我有當前的工作代碼。 但是,它會蠻力計算並且在達到 150x400 的網格大小時非常慢。 我一直在嘗試優化代碼,我相信我遺漏了一些簡單的東西。 任何建議,將不勝感激。

目前,我將信息存儲在字典中以建立“一對多”關系。 該問題的另一個警告是我只存儲項目 c 的位置,如果該位置在網絡中可用於項目 c,則它將涵蓋位置(i,j)

在給定的示例中,如果項目c = 3 ,並且我們正在查看位置(4,3)將覆蓋的位置是(4,2)(4,3) ,但是位置(5,3)也會但是,通常不存儲封面(4,3) ,因為項目 c 無法到達此位置。 ( 我希望這是有道理的)

我相信我有幾個冗余循環,並且可以以更快的方式完成,但是,我很難把頭繞在它周圍。

function validpositions(UnusuableSpace::Matrix{Int64}, nCargoes::Int64, SquaresL::Vector{Int64}, SquaresW::Vector{Int64})
    # This function should return all position that are valid in the layout for
    # cargo c in C. This should be returned as a tuple e.g. pos = [(1,1),(4,3),..,(18,1)].
    N = []
    for c in 1:nCargoesM
        pos = Vector{Tuple{Int64,Int64}}()

        for i in SquaresL[c]:size(UnusuableSpace)[1] # skip some of the rows. If the cargo has dimensions > 1.
            for j in 1:size(UnusuableSpace)[2]
                # Check if position includes a pillar / object
                if UnusuableSpace[i,j] != 1
                    # Check if these is space for the cargo in the position.
                    if (i-SquaresL[c]) >= 0 && (j+SquaresW[c]-1) <= size(UnusuableSpace)[2]
                        # Check if position i,j covers an are with pillars in due to cargo
                        # dimensions.
                        if sum(UnusuableSpace[i-SquaresL[c]+1:i,j:j+SquaresW[c]-1]) == 0
                            push!(pos,(i,j))
                        end
                    end
                end
            end

        end
        push!(N,pos)
    end
    # return all valid positions of the cargo c.
    return N
end # end valid position function





nCargoesM = 3
SquaresL = [1,2,3]
SquaresW = [1,2,2]


UnusableSpace = [
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 1 1 0 1 0 0 0
0 0 1 1 1 0 1 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]

N = validpositions(UnusableSpace, nCargoesM, SquaresL, SquaresW)


function coveringSet(UnusableSpace::Matrix{Int64}, nCargoes::Int64, SquaresL::Vector{Int64}, SquaresW::Vector{Int64}, N)
    Qijc = Dict{}()
    for c in 1:nCargoesM
        for i in 1:size(UnusableSpace)[1]
            for j in 1:size(UnusableSpace)[2]
                tmpset = []
                for (k, l) in N[c]
                    # Get the points/nodes of the areas to check
                    vec1 = [i, j]
                    vec2 = [k-SquaresL[c]+1:k, l:l+SquaresW[c]-1]

                    tmp = [[x, y] for x in vec1[1], y in vec1[2]]
                    tpm = [[x, y] for x in vec2[1], y in vec2[2]]

                    # Check for overlapping
                    if sum([tmp in tpm for tmp = tmp]) > 0
                        push!(tmpset, [k, l])
                    end
                end
                push!(Qijc, [i, j, c] => tmpset)
            end
        end
    end
    return Qijc
end



Qijc = coveringSet(UnusableSpace, nCargoesM, SquaresL, SquaresW, N)


一段時間后,我實際上自己解決了這個問題。 您可以預先計算字典中的所有鍵並執行循環。 檢查貨物的位置,是否是允許的位置。

function coveringSet_new_threaded(UnusableSpace, nCargoesM::Int64, SquaresL::Vector{Int64}, SquaresW::Vector{Int64})
    # Create dictionary
    Qijc4 = Dict{}()

    for c in 1:nCargoesM
        for i in 1:size(UnusableSpace)[1]
            for j in 1:size(UnusableSpace)[2]
                push!(Qijc4, [i, j, c] => [])
            end
        end
    end

    # Finding the combinations of cargo size
    combinationsCargo = Vector{Tuple{Int64,Int64}}()
    for i in 1:length(SquaresL)
        push!(combinationsCargo, (SquaresL[i], SquaresW[i]))
    end

    # The unique combinations available
    CargoTypes = unique(combinationsCargo)


    Threads.@threads for c in 1:length(CargoTypes)
        typeindx = findall(x -> x == CargoTypes[c], combinationsCargo)
        # Index to control where to find information regarding squaresL and squaresW
        sizeidx = typeindx[1]

        #Threads.@threads for c in 1:nCargoesM
        for i in 1:size(UnusableSpace)[1]
            for j in 1:size(UnusableSpace)[2]
                tmpset = []

                # Generate the range of positions to check. (h,m) check if it also covers (i,j)
                # due to cargo size.
                for h in i:i+SquaresW[sizeidx]-1
                    for m in j-SquaresL[sizeidx]+1:j
                        # Check that the position is actually within the layout of the ship
                        if (h > 0 && m > 0 && h <= size(UnusableSpace)[1] && h <= size(UnusableSpace)[2])
                            # Check that the position is not unusable.
                            if UnusableSpace[h, m] != 1
                                # Check that the position given cargo size is withon the layout of the ship.
                                if (h - SquaresW[sizeidx]) >= 0 && (m + SquaresL[sizeidx] - 1) <= size(UnusableSpace)[2]
                                    # Check that the cargo, when in position (h,m) does not collide with any unusable space.
                                    if sum(UnusableSpace[h-SquaresW[sizeidx]+1:h, m:m+SquaresL[sizeidx]-1]) == 0
                                        # Only then is it a position for cargo c that covers (i,j).
                                        push!(tmpset, [h, m])
                                    end
                                end
                            end
                        end
                    end
                end
                # Push in set for that position. It may be empty.
                for k in typeindx
                    Qijc4[[i, j, k]] = tmpset
                end
            end
        end
    end

    return Qijc4
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM