簡體   English   中英

如何輕松解決分配優化任務

[英]How to tractably solve the assignment optimisation task

我工作的一個腳本,需要從內容companies和對他們與的元素people 目標是優化配對,使得所有配對值的總和最大化(每個配對的值被預先計算並存儲在字典ctrPairs )。

他們都以1:1的比例配對,每個公司只有一個人,每個人只屬於一家公司,公司數量等於人數。 我使用自上而下的方法和memDict表( memDict )來避免重新計算已經解決的區域。

我相信我可以大大提高這里發生的速度,但我不確定如何。 我擔心的地方標有#slow? ,任何建議將不勝感激(該腳本適用於列表n <15的輸入,但是對於n> ~15,它會變得非常慢)

def getMaxCTR(companies, people):
    if(memDict.has_key((companies,people))):
        return memDict[(companies,people)] #here's where we return the memoized version if it exists
    if(not len(companies) or not len(people)):
        return 0

    maxCTR = None
    remainingCompanies = companies[1:len(companies)] #slow?

    for p in people:
        remainingPeople = list(people) #slow?
        remainingPeople.remove(p) #slow?
        ctr = ctrPairs[(companies[0],p)] + getMaxCTR(remainingCompanies,tuple(remainingPeople)) #recurse
        if(ctr > maxCTR):
            maxCTR = ctr
    memDict[(companies,people)] = maxCTR
    return maxCTR

對於那些對使用學習理論感到疑惑的人來說,這個問題很好。 正確的問題不是“在python中列表和元組之間反彈的快速方法” - 緩慢的原因是更深層次的。

你在這里想要解決的是被稱為賦值問題 :給定兩個n元素列表和n×n值(每對的值),如何分配它們以使總“值”最大化(或者等價地,最小化)。 有幾種算法,例如匈牙利算法Python實現 ),或者您可以使用更通用的最低成本流算法來解決它,甚至將其轉換為線性程序並使用LP求解器。 其中大多數的運行時間為O(n 3 )。

您的算法上面所做的是嘗試每種可能的配對方式。 (記憶僅有助於避免重新計算子集對的答案,但您仍然在查看所有子集對。)此方法至少為Ω(n 2 2 2n )。 對於n = 16,n 3為4096,n 2 2 2n為1099511627776.當然,每種算法都有常數因子,但看到差異? :-)(問題中的方法仍然比天真的O(n!)更好,這會更糟糕。)使用其中一個O(n ^ 3)算法,我預測它應該及時運行起來n = 10000左右,而不是n = 15。

正如Knuth所說,“過早優化是所有邪惡的根源”,但延遲/過期優化也是如此:在實施之前,你應首先仔細考慮一個合適的算法,而不是選擇一個壞算法,然后想知道它的哪些部分很慢。 :-)即使在Python中實現一個好的算法,也比修復所有“慢”快幾個數量級。 上面代碼的一部分(例如,通過在C中重寫)。

我在這里看到兩個問題:

  1. 效率:你正在為每個公司重新創建相同的remainingPeople子列表。 最好是創建所有remainingPeople人和所有remainingCompanies ,然后再進行所有組合。

  2. memoization:你使用元組而不是列表來將它們用作用於記憶的dict鍵; 但是元組標識對順序敏感。 IOW: (1,2) != (2,1)你最好使用set s和frozenset s: frozenset((1,2)) == frozenset((2,1))

這一行:

remainingCompanies =公司[1:len(companies)]

可以替換為這一行:

remainingCompanies = companies[1:]

對於非常輕微的速度增加。 這是我看到的唯一改進。

如果你想獲得一個元組的副本作為列表你可以做mylist = list(mytuple)

暫無
暫無

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

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