簡體   English   中英

Python OR-工具 點間距離

[英]Python OR-Tools Distance between points

我正在使用 or-tools 約束求解器來查找房間中物品的工作位置。 我使用 CP 求解器而不是背包求解器,因為我需要添加額外的約束。

我將每個項目表示為 x 間隔和 y 間隔,並添加如下約束:

model.AddNoOverlap2D(x_intervals, y_intervals)

這有助於放置對象,使它們不重疊,但我需要添加另一個約束以確保對象之間有一定距離。 這應該是對象之間的基本 2D 距離,但此公式需要 IntVar 項似乎無法使用的 sqrt 和 pow 函數。

我考慮過使用另一個以每個主要 object 為中心的“間隔對象”,並添加另一個NoOverlap2D約束,但是當距離公式將是更精確的距離且不會浪費時,這將導致整個正方形空間被遮擋房間里的空間。

編輯- 下面的代碼現在用於對項目施加距離限制。

在 Laurent 的建議之后,我嘗試制作許多中間變量來處理這個問題,但我堅持乘以或除以定義形狀位置間隔的 IntVars:

# Now lets make all possible combinations and make a distance between them
combos = list(combinations(range(len(rects_data)), 2))

print(combos) 

currentDistanceId = 0

distanceVariables = []

for listSet in combos:
    leftItem = all_vars[listSet[0]]
    rightItem = all_vars[listSet[1]]

    if leftItem.holderType == HolderType.Person and rightItem.holderType == HolderType.Person:
        print(f"Adding distances between {listSet[0]} and {listSet[1]} because both are people")
        
        currentDistanceId = currentDistanceId + 1

        # Add an intermediate variable to store the sum of x for the center of left object
        leftCenterXSum = model.NewIntVar(0, horizon.x*2, f"leftCenterXSum{currentDistanceId}")
        # Add constraint to it
        model.Add(leftCenterXSum == leftItem.x2 + leftItem.x1)
        # Add an intermediate variable to store the center of x of the left object
        leftCenterX = model.NewIntVar(0, horizon.x, f"leftCenterX{currentDistanceId}")
        # Add a constraint to divide it by 2 to make it te center
        model.AddDivisionEquality(leftCenterX, leftCenterXSum, 2)

        ## Repeat for x and y for left and right objects
        leftCenterYSum = model.NewIntVar(0, horizon.y*2, f"leftCenterYSum{currentDistanceId}")
        model.Add(leftCenterYSum == leftItem.y2 + leftItem.y1)
        leftCenterY = model.NewIntVar(0, horizon.y, f"leftCenterY{currentDistanceId}")
        model.AddDivisionEquality(leftCenterY, leftCenterYSum, 2)

        rightCenterXSum = model.NewIntVar(0, horizon.x*2, f"rightCenterXSum{currentDistanceId}")
        model.Add(rightCenterXSum == rightItem.x2 + rightItem.x1)
        rightCenterX = model.NewIntVar(0, horizon.x, f"rightCenterX{currentDistanceId}")
        model.AddDivisionEquality(rightCenterX, rightCenterXSum, 2)

        rightCenterYSum = model.NewIntVar(0, horizon.y*2, f"rightCenterYSum{currentDistanceId}")
        model.Add(rightCenterYSum == rightItem.y2 + rightItem.y1)
        rightCenterY = model.NewIntVar(0, horizon.y, f"rightCenterY{currentDistanceId}")
        model.AddDivisionEquality(rightCenterY, rightCenterYSum, 2)

        # Create variable for difference of x
        xDiff = model.NewIntVar(-horizon.x, horizon.x, f"xDiff{currentDistanceId}")

        # Create constraint for difference of x
        model.Add(xDiff == rightCenterX - leftCenterX)

        # Create variable for difference of y
        yDiff = model.NewIntVar(-horizon.y, horizon.y, f"yDiff{currentDistanceId}")

        # Create constraint for difference for y
        model.Add(yDiff == rightCenterY - leftCenterY)

        # Create variables for x and y squared
        xDiffSquared = model.NewIntVar(0, horizon.x**2, f"xDiffSquared{currentDistanceId}")
        yDiffSquared = model.NewIntVar(0, horizon.y**2, f"yDiffSquared{currentDistanceId}")

        # Add constraint to multiply them
        model.AddMultiplicationEquality(xDiffSquared, [xDiff, xDiff])
        model.AddMultiplicationEquality(yDiffSquared, [yDiff, yDiff])

        totalDistance = model.NewIntVar(0, horizon.x**2 + horizon.y**2, f"totalDistance{currentDistanceId}")

        model.Add(totalDistance == xDiffSquared + yDiffSquared)

        distanceVariables.append(totalDistance)

        model.Add( totalDistance >= distanceSquared )
    else:
        print(f"Skipping distances between {listSet[0]} and {listSet[1]} because one is furniture")

代替

Sqrt((x1-x2)^2 + (y1-y2)^2) >= d

你為什么不寫

(x1-x2)^2 + (y1-y2)^2 >= d^2

支持哪個。 您將需要編寫(在偽代碼中)

IntVar t_x
Add(t_x == x1 - x2)
IntVar t_sx
AddMultiplicationEquality(t_sx, [t_x, t_x])

IntVar t_y
Add(t_y == y1 - y2)
IntVar t_sy
AddMultiplicationEquality(t_sy, [t_y, t_y])

Add(t_sx + t_sy >= d * d)

暫無
暫無

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

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