【问题标题】:Permutations in python, with a twistpython中的排列,有点扭曲
【发布时间】:2010-10-02 20:16:26
【问题描述】:

我有一个对象列表(例如,假设为 5)。我想要一些可能的排列列表。具体来说,鉴于有些对不在一起,有些三元组不做三明治,我如何生成所有其他排列?我意识到我首先生成所有它们并检查它们是否有效,但我认为甚至不考虑不起作用的对和三元组会更快。

先检查再生成会更快,我错了吗?

我该怎么做?

【问题讨论】:

  • 您能否列出一个代码示例来说明您目前的想法?

标签: python


【解决方案1】:

你必须找到一种算法,在一次检查后切断多个不需要的排列,以获得任何东西。显而易见的策略是按顺序构建排列,例如在树中。然后每次切割都会消除整个分支。

编辑:
示例:在集合(A B C D)中,假设B和C,A和D不允许邻居。

(A B C D) / | \ / | \ / | \ / | \ AB AC AD BA BC BD CA CB CD DA DB DC | \ | \X/\X/\/\X/\X/\/\ ABC ABD ACB ACD BAC 坏 BDA BDC CAB CAD CDA CDB DBA DBC DCA DCB X | X | | X X | | X X | | X | X ABDC ACDB BACD BDCA CABD CDBA DBAC DCAB v v v v v v v

每个没有括号的字符串都需要检查。如您所见,X(子树已被切断)保存检查,如果它们在第三行,则保存检查,但如果在第二行,则保存检查。我们在这里保存了 60 次检查中的 24 次,然后降到了 36 次。但是,无论如何,总共只有 24 次排列,所以如果检查限制(而不是构建列表)是瓶颈,我们最好只构建所有排列并在最后检查它们......如果我们这样做时无法优化检查。

现在,如您所见,只需对每个列表的新部分执行检查。这使得检查更加精简;实际上,我们将完整排列所需的检查分成小块。在上面的例子中,我们只需要查看添加的字母是否允许站在最后一个之外,而不是之前的所有字母。

但是,如果我们先构造然后过滤,则一旦遇到“否”,检查可能会被缩短。因此,在检查时,与先构建后过滤算法相比,没有真正的收益;通过更多的函数调用存在更多开销的危险。

我们节省的是构建列表的时间和峰值内存消耗。构建列表通常相当快,但如果对象数量变大,可能需要考虑峰值内存消耗。对于先构建后过滤器,两者都随着对象数量线性增长。对于树版本,它的增长速度较慢,具体取决于约束。从一定数量的对象和规则上,还有实际的支票保存。

一般来说,我认为您需要尝试一下并对这两种算法进行计时。如果您真的只有 5 个对象,请坚持使用简单的 (filter rules (build-permutations set))。如果您的对象数量变大,树算法在某些时候会表现得更好(你知道,大 O)。

嗯。抱歉,我进入了演讲模式;忍受我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    相关资源
    最近更新 更多