コメントには既に言及していますが、この問題はセールスマン問題の解決に相当します。私はそれについて詳述したいと思います:
すべての人は頂点に相当し、エッジはお互いに座ることができる人を表す頂点の間にあります。今、可能な座席配置を見つけることは、グラフ内のハミルトニアン経路を見つけることと同じです。
この問題はNPCです。最も純粋な解決策は、すべての可能な並べ替えを試みて、実行時間がになることです。 O(n!)
よりも優れた性能を発揮し、ウェブ上で自由に入手できる、よく知られたアプローチがたくさんあります。このコードが適切にテストされていませんが、私はあなたがそれの要点を得ることができることを望む:
#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
免責事項:私はPythonで、ここで、O(n^2*2^n)
で実行され、コードにはかなりまっすぐ進むである、Held-Karpに言及したいと思います。
出典
2016-02-11 23:08:19
ead
"ハミルトニアンパス"を参照 –
誰もが常に友人か敵か、無関心にできますか?あなたの例は、無関心である可能性があることを示唆しています。友人の隣に座っていなければなりませんか、敵でない人が座っていられますか? –
あなたはあまりにも多くの人がいない場合は、すべての可能な着順を試すアルゴリズムを書くことをお勧めします。そして、すべての条件を満たしている最初のもので止めてください。 – RomCoo