哪种算法可以合理地减少多个列表? ("谁杀了谁"亲)

时间:2014-11-12 17:33:13

标签: python algorithm logic

我不知道我所说的问题是否有名字,如果是这样的话,我想知道它是为了做更多的研究。

为了解释我的问题,更容易想象它。

我会给出一个代表,但其他许多人都有可能。

  
      
  • 在一个小镇上,警方发现了大量尸体。
  •   
  • 对于发现的每一具尸体,居民中都有一些嫌犯   城市。
  •   
  • 凶手不能杀死一个以上的人。
  •   
  • 有一个解决方案。   

    找出谁杀了谁
  •   

在我写这篇文章时,我意识到这个问题可能有很多变种,所以知道它是什么类型的问题真的很有用。


我将使用测试游戏 因此,对于每一具尸体,我们在居民中都有一套嫌疑人。

C1 -> [S1, S3]
C2 -> [S1, S3, S4]
C3 -> [S2]
C4 -> [S2, S3]

通过逻辑演绎,可以很容易地确定谁杀了谁。

  1. C3只有一名嫌犯,所以,S2是凶手。
  2. S2是C3的凶手,所以他不能成为C4的凶手。这意味着S2杀死了C4。
  3. S1是C1的最新潜在嫌疑人,因此他是凶手。
  4. 最后,S4是C2的凶手。
  5. 这为我们提供了解决方案:

    C1 -> S1
    C2 -> S4
    C3 -> S2
    C4 -> S3
    

    解决此问题的算法的简单实现将是:

    found = []
    
    for corpse in corpses:
        corpse.suspects = [s for s in corpse.suspsects if s not in found]
        if len(corpse.suspects) == 1:
            found.append(suspects[0])
            continue # Restart the loop to remove the new killer found 
                     # from previous corpses suspects
    

    问题在于,由于有大量的身体和嫌疑人,它变得非常昂贵,循环需要很长时间。当然,可以进行小的改进(例如,一旦嫌疑人发现,就将尸体从列表中删除),但算法在我看来仍然不是最佳的。

    这个问题有更好的算法吗? 我再说一遍,这是一个特定的名称吗?它绝对可以帮到我很多。

1 个答案:

答案 0 :(得分:6)

这是maximum bipartite matching的示例。所讨论的二分图由两组人(尸体和嫌疑人)以及将每个尸体与可能杀死他的嫌疑人联系在一起的边缘来定义。最大匹配将为每个尸体选择一个边缘(如果可能),而不是为每个嫌疑人选择多个边缘。