我在咨询机构工作,大部分时间都在客户所在地。因此,我很少见到我的同事。为了更好地了解彼此,我们将安排一个晚宴。将有许多小桌子,所以人们可以聊天。为了在聚会期间尽可能多地与不同的人交谈,每个人都必须按照一定的时间间隔来换桌子,比如每小时一次。
如何编写创建表切换计划的程序?只是给你一些数字;在这种情况下,将有大约40人,每张桌子最多可以有8个人。但是,算法必须是通用的
答案 0 :(得分:11)
或者你可以通过给每个人一张卡片来解决问题,他们可以写下他们用餐的所有人的名字......并且在活动结束时,向人们提供一些奖品。他们卡片中的大多数名字
答案 1 :(得分:6)
为什么不模仿现实世界?
class Person {
void doPeriodically() {
do {
newTable = random (numberOfTables);
} while (tableBusy(newTable))
switchTable (newTable)
}
}
哦,请注意,有一个类似的算法可以找到一个交配伙伴,并且传言这对99%没有花费所有空闲时间回答编程问题的人都有效...
答案 2 :(得分:5)
这听起来像是遗传算法的应用:
您可以在健身中添加您喜欢的任何其他因素,例如男/女比例等,而不会大幅改变基本方法。
答案 3 :(得分:4)
答案 4 :(得分:3)
您可能需要查看combinatorial design theory。
答案 5 :(得分:2)
直觉上我认为你不能比perfect shuffle做得更好,但这超出了我对咖啡前的认知来证明它。
答案 6 :(得分:2)
这个非常好笑! :d
我尝试了不同的方法,但adi92(card + prize)建议的逻辑是比我尝试过的任何其他方法更好的逻辑。
它的工作原理如下:
在每个回合中,坐席的人的顺序是随机的(这可以避免可能的无限循环),这是python中工作算法的“演示”:
import random
class Person(object):
def __init__(self, name):
self.name = name
self.known_people = dict()
def meets(self, a_guy, propagation = True):
"self meets a_guy, and a_guy meets self"
if a_guy not in self.known_people:
self.known_people[a_guy] = 1
else:
self.known_people[a_guy] += 1
if propagation: a_guy.meets(self, False)
def points(self, table):
"Calculates how many new guys self will meet at table"
return len([p for p in table if p not in self.known_people])
def chooses(self, tables, n_seats):
"Calculate what is the best table to sit at, and return it"
points = 0
free_seats = 0
ret = random.choice([t for t in tables if len(t)<n_seats])
for table in tables:
tmp_p = self.points(table)
tmp_s = n_seats - len(table)
if tmp_s == 0: continue
if tmp_p > points or (tmp_p == points and tmp_s > free_seats):
ret = table
points = tmp_p
free_seats = tmp_s
return ret
def __str__(self):
return self.name
def __repr__(self):
return self.name
def Switcher(n_seats, people):
"""calculate how many tables and what switches you need
assuming each table has n_seats seats"""
n_people = len(people)
n_tables = n_people/n_seats
switches = []
while not all(len(g.known_people) == n_people-1 for g in people):
tables = [[] for t in xrange(n_tables)]
random.shuffle(people) # need to change "starter"
for the_guy in people:
table = the_guy.chooses(tables, n_seats)
tables.remove(table)
for guy in table:
the_guy.meets(guy)
table += [the_guy]
tables += [table]
switches += [tables]
return switches
lst_people = [Person('Hallis'),
Person('adi92'),
Person('ilya n.'),
Person('m_oLogin'),
Person('Andrea'),
Person('1800 INFORMATION'),
Person('starblue'),
Person('regularfry')]
s = Switcher(4, lst_people)
print "You need %d tables and %d turns" % (len(s[0]), len(s))
turn = 1
for tables in s:
print 'Turn #%d' % turn
turn += 1
tbl = 1
for table in tables:
print ' Table #%d - '%tbl, table
tbl += 1
print '\n'
这将输出如下内容:
You need 2 tables and 3 turns
Turn #1
Table #1 - [1800 INFORMATION, Hallis, m_oLogin, Andrea]
Table #2 - [adi92, starblue, ilya n., regularfry]
Turn #2
Table #1 - [regularfry, starblue, Hallis, m_oLogin]
Table #2 - [adi92, 1800 INFORMATION, Andrea, ilya n.]
Turn #3
Table #1 - [m_oLogin, Hallis, adi92, ilya n.]
Table #2 - [Andrea, regularfry, starblue, 1800 INFORMATION]
由于随机性,它并不总是带有最小数量的开关,特别是对于较大的人群。然后你应该运行它几次并以较少的转弯得到结果(所以你不要强调聚会上的所有人:P),并且编码很容易:P
PS: 是的,你可以节省奖金:P
答案 7 :(得分:1)
您还可以查看稳定的匹配问题。该问题的解决方案涉及使用max-flow算法。 http://en.wikipedia.org/wiki/Stable_marriage_problem
答案 8 :(得分:0)
我不打扰遗传算法。相反,我会做以下事情,这是对重复完美洗牌的一点点改进。
虽然(有两个人没有见过面):
重复上述步骤一段时间,直到轮数似乎收敛。
答案 9 :(得分:0)
WRT @ Neodymium的评论,这是相关网站上的page:
它讨论了遗传算法。