【问题标题】:Algorithm to find "good" neighbours - graph coloring?寻找“好”邻居的算法 - 图形着色?
【发布时间】:2016-02-11 17:32:30
【问题描述】:

我有一群人,每个人都有一个朋友列表和一个敌人列表。我想把它们排成一排(没有桌子上的圆圈),这样最好没有敌人,只有朋友挨着。

输入示例:https://gist.github.com/solars/53a132e34688cc5f396c

我认为我需要使用图形着色来解决此问题,但我不确定如何 - 我认为我必须省略朋友(或敌人)列表以使其更容易并映射到图形。

有谁知道如何解决这些问题并告诉我我是否走在正确的道路上?

代码示例或在线示例也不错,我不介意编程语言,我通常使用 Ruby、Java、Python、Javascript

非常感谢您的帮助!

【问题讨论】:

  • 查找“汉密尔顿路径”
  • 每个人都会永远是朋友还是敌人,还是你可以无动于衷?你的例子表明可以无动于衷。您必须坐在朋友旁边,还是可以坐在不是敌人的人旁边?
  • 如果您没有太多人,我建议您编写一个算法来尝试所有可能的坐席顺序。并在第一个满足所有条件的地方停下来。
  • 组有多大?还有……你在维斯特洛开展派对服务吗?
  • 感谢你们的帮助,我认为这是正确的方法。 @JeremyWest 你是对的,如果没有条目,它就像一个jocker,所以没关系,如果建模为一个hamiltonian图,这基本上和一个朋友一样。

标签: python algorithm graph graph-algorithm


【解决方案1】:

在cmets中已经提到,这个问题相当于旅行商问题。我想详细说明一下:

每个人都相当于一个顶点,边在顶点之间,代表可以坐在一起的人。现在,找到一个可能的座位安排就相当于在图中找到一条哈密顿路径。

所以这个问题是NPC。最天真的解决方案是尝试所有可能的排列,从而导致O(n!) 运行时间。有许多众所周知的方法比O(n!) 性能更好,并且可以在网络上免费获得。我想提一下Held-Karp,它在O(n^2*2^n) 中运行,代码非常简单,这里是python:

#graph[i] contains all possible neighbors of the i-th person
def held_karp(graph):
    n = len(graph)#number of persons

    #remember the set of already seated persons (as bitmask) and the last person in the line
    #thus a configuration consists of the set of seated persons and the last person in the line
    #start with every possible person:
    possible=set([(2**i, i) for i in xrange(n)])

    #remember the predecessor configuration for every possible configuration:
    preds=dict([((2**i, i), (0,-1)) for i in xrange(n)])

    #there are maximal n persons in the line - every iterations adds a person
    for _ in xrange(n-1):
        next_possible=set()
        #iterate through all possible configurations
        for seated, last in possible:
            for neighbor in graph[last]:
                bit_mask=2**neighbor
                if (bit_mask&seated)==0: #this possible neighbor is not yet seated!
                    next_config=(seated|bit_mask, neighbor)#add neighbor to the bit mask of seated
                    next_possible.add(next_config)
                    preds[next_config]=(seated, last)
        possible=next_possible

    #now reconstruct the line
    if not possible:
      return []#it is not possible for all to be seated

    line=[]
    config=possible.pop() #any configuration in possible has n person seated and is good enough!
    while config[1]!=-1:
        line.insert(0, config[1])
        config=preds[config]#go a step back

    return line

免责声明:此代码未经过适当测试,但我希望您能了解它的要点。

【讨论】:

  • 非常感谢!如上所述,我认为这是正确的道路。我将检查是否有任何现有的库在 ruby​​ 中提供 TSP 算法,我还将查看您发布的算法/代码。然后,我会为所有朋友或未指定的事物提供优势——隐含地排除敌人。我认为这应该有效
猜你喜欢
  • 2011-06-24
  • 2011-03-12
  • 1970-01-01
  • 2015-07-16
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
相关资源
最近更新 更多