Python 如何巧妙地解决分配优化任务

Python 如何巧妙地解决分配优化任务,python,algorithm,optimization,dynamic-programming,Python,Algorithm,Optimization,Dynamic Programming,我正在编写一个脚本,它将公司的元素与人的元素配对。目标是优化配对,以使所有配对值之和最大化(每个配对的值预先计算并存储在字典ctrPairs) 他们以1:1的比例配对,每个公司只有一个人,每个人只属于一个公司,公司的数量等于人数。我使用自上而下的方法和一个记忆表(memDict)来避免重新计算已经解决的区域 我相信我可以大大提高这里发生的事情的速度,但我不确定如何提高。我担心的区域标有#slow?,如有任何建议,将不胜感激(该脚本适用于列表n~15的输入) 这一行: 剩余公司=公司[1:len(

我正在编写一个脚本,它将
公司的元素
人的元素
配对。目标是优化配对,以使所有配对值之和最大化(每个配对的值预先计算并存储在字典
ctrPairs

他们以1:1的比例配对,每个公司只有一个人,每个人只属于一个公司,公司的数量等于人数。我使用自上而下的方法和一个记忆表(
memDict
)来避免重新计算已经解决的区域

我相信我可以大大提高这里发生的事情的速度,但我不确定如何提高。我担心的区域标有
#slow?
,如有任何建议,将不胜感激(该脚本适用于列表n~15的输入)

这一行:

剩余公司=公司[1:len(公司)]

可替换为以下行:

remainingCompanies = companies[1:]

为了一个非常轻微的速度增加。这是我看到的唯一改进。

如果您想获得元组的副本作为列表,您可以这样做
mylist=list(mytuple)

对于所有对学习理论的使用感到好奇的人来说,这个问题是一个很好的例子。正确的问题不是“python中在列表和元组之间快速跳转的方法”——缓慢的原因是更深层次的

这里您试图解决的问题是:给定两个列表,每个列表包含n个元素和n×n个值(每对的值),如何分配它们以使总“值”最大化(或等效地最小化)。有几种算法可以解决这个问题,例如(),或者您可以使用更通用的最小成本流算法来解决它,甚至可以将其转换为线性规划并使用LP解算器。其中大多数的运行时间为O(n3)

上面的算法所做的是尝试每种可能的配对方法。(回忆录只帮助避免重新计算成对子集的答案,但您仍在查看所有成对的子集。)这种方法至少为Ω(n222n)。对于n=16,n3为4096,n222n为109951162776。当然,每个算法中都有常数因子,但看到它们的区别了吗?:-)(这个问题中的方法仍然比天真的O(n!)好,后者会更糟。)使用O(n^3)算法之一,我预测它应该在时间上运行到n=10000左右,而不是仅仅运行到n=15

“过早优化是万恶之源”,正如Knuth所说,但延迟/过期优化也是如此:在实施之前,首先要仔细考虑一个合适的算法,而不是选择一个坏的算法,然后想知道它的哪些部分是慢的。即使在Python中实现一个好的算法很糟糕,也要比修复上面代码的所有“慢”部分(例如,用C重写)快几个数量级。

我在这里看到两个问题:

  • 效率:您正在为每个公司重新创建相同的
    remainingPeople
    子列表。最好创建所有
    remainingPeople
    和所有
    remainingcompanys
    一次,然后进行所有组合

  • 记忆化:您使用元组而不是列表将它们用作记忆化的
    dict
    键;但元组标识是顺序敏感的。IOW:
    (1,2)!=(2,1)
    您最好使用
    set
    s和
    frozenset
    s来实现这一点:
    frozenset((1,2))==frozenset((2,1))


  • 对不起,我想这让人困惑。我认为它遵循背包型问题的模型,因此想法是提出一个解决方案,让公司的每个元素与人的元素配对,其中所有配对的总和是所有潜在组合的最大可能值(即,没有其他配对安排可以产生更高的总和)@SilentGhost停止设置一个真正描述问题的标题?@Marcin:不要再胡闹了,去回答一些问题。@SilentGhost“胡闹特权”是什么意思?您对我刚才设置的标题有何异议?注意:问题的原始标题是“请求帮助:python中在列表和元组之间跳转的快速方式是什么?”因此,这是答案的第一段。
    remainingCompanies = companies[1:]