首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >策划一个和平的聚会

策划一个和平的聚会
EN

Stack Overflow用户
提问于 2014-09-09 12:50:26
回答 2查看 720关注 0票数 1

有很多人--有些人恨对方,有些人爱对方,有些人不认识对方.如果(A恨B,A坐在B旁边)或(A爱B和A不坐在B旁边),那将是一场战争。我正在准备我朋友的生日聚会,所以我不想让派对变成战场,我有这样的清单:

a1讨厌a2

a1喜欢a3

a3喜欢a2

..。

有没有一个有效的算法来安排我朋友的座位,这样我们就不会有战争了?

我目前正在使用nave蛮力解,生成所有排列,以找到可行的安排。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-09 13:20:14

您应该将此作为一个图形问题来处理。我以为你想把客人围成一圈。

V做你的客人。让E是所有顶点对的集合,(A, B),这样AB就不互相憎恨了。在这个图中找到一个哈密顿循环已经解决了这样一个问题,那就是憎恨对方的人不能坐在一起,因为这些边不存在。

现在你需要强制要求彼此相爱的人坐在一起。对于每一对顶点(A, B),如AB彼此相爱,则添加具有边(A, A')(B, B')(A', B')的顶点A'B'A'B'都有度2,所以哈密顿循环必须包含(A', B')

现在,只要找到哈密顿循环,你就有了座位布局。不幸的是,这个问题是NP完全的,但至少它是很好的研究。

票数 3
EN

Stack Overflow用户

发布于 2014-09-09 13:01:08

如果您关心的不仅仅是相邻的位置(例如,如果人们不能面对面地坐着),那么我会亲自使用遗传算法

你知道什么是好比赛,但很难做到。

伪码警报

假设你有一个人的数据模型

代码语言:javascript
复制
person
  +loves : person[]
  +hates : person[]
  +id : string //typically name, or a b c in your example

你有一个函数来计算两个人的适应度

代码语言:javascript
复制
okToSitNextToEachOther(person1 : person, person2 : person) 
   return (person1.loves.contains(person1) ? 1 : 0) + 
          (person1.hates.contains(person2) ? -2 : 0); // hate more important than love
          //do the same for person2 if hate/love is directional

创建表格安排的数据模型。然后,建立一个函数来评估该安排的适合性。

代码语言:javascript
复制
table
  -x : int //length of a table side, set in constructor
  +seatRow1 : person[x]
  +seatRow2 : person[x]
  +calculateMatch() : float //you could return int of error count or a percentage
  +mutate() : void // randomly swap people who violates your rule around

创建一个随机填充x表的管理器(足够用于填充的表)。让经理能够对匹配最少的表的数据进行变异。(变异意味着交换周围的人)。

代码语言:javascript
复制
PartyManager
  -people : person[] //pass in constructor
  -tables : table[]
  +calculateMatch() : float //iterate over all tables and return sum of match
  +mutate() : void //iterate over all tables and mutate those who does not suit match requirement
  +clone() : PartyManager //clone this 

现在,创建许多经理,并将他们都列在一个列表中。循环,直到其中一个经理有一个“足够好”的安排。到那时为止。给每个经理打电话。删除最不成功的,并为您删除的每一个创建一个新的,并使用最成功的种子,然后对这些种子进行变异。

代码语言:javascript
复制
PartyManager match = null
while (true) {
   PartyManager bestManager = managers.max( m => m.calculateMatch() ) //find the best match
   for each partyManager in managers
       if partyManager.calculateMatch() < TOO_BAD
           clone = bestManager.clone()
           clone.mutate()
           managers.add(clone)
           managers.remove(partyManager)
       else if partyManager.calculateMatch() < GOOD_ENOUGH
           partyManager.mutate()
       else
           match = partyManager // we fount a match
           break

如果您需要的话,我可以填写更多的信息,但是看看我链接到的wiki。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25745120

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档