2009-06-09 2 views
10

Я работаю в консалтинговой организации и большую часть времени занимаюсь в местах расположения клиентов. Из-за этого я редко встречаю своих коллег. Чтобы лучше узнать друг друга, мы собираемся устроить званый обед. Там будет много маленьких столов, чтобы люди могли общаться в чате. Чтобы разговаривать с как можно большим количеством разных людей во время вечеринки, каждый должен переключать столы с некоторым интервалом, скажем, каждый час.Быстрый алгоритм знакомства

Как написать программу, которая создает расписание переключения таблиц? Просто чтобы дать вам несколько цифр; в этом случае их будет около 40 человек, и за каждым столом может быть не более 8 человек. Но, алгоритм должен быть универсальным, конечно

+0

Должно ли быть одинаковое количество мужчин и женщин на стол? – Unknown

+0

Нет, я думаю, что проблема достаточно сложная, как есть. – Hallis

+9

Почему бы вам просто не создать группу Facebook, чтобы поддерживать связь друг с другом? –

ответ

4

Это звучит как приложение для генетического алгоритма:

  1. Выберите случайная перестановка 40 гостей - это одно сидение
  2. Повторите случайную перестановку N раз (n сколько раз вы должны переключаться между сидениями в ночное время)
  3. Объедините перестановки вместе - это хромосома для одного организм
  4. Повторяйте, как много организмов вы хотите размножать в одном поколении
  5. Оценка пригодности - это количество людей, которых каждый человек должен видеть за одну ночь (или, наоборот, - инверсию числа людей, которых они не делали см.)
  6. Породите, мутируйте и вводите новые организмы, используя обычный метод, и повторяйте, пока не получите удовлетворительный ответ

Вы можете добавить любые другие факторы, которые вам нравятся в фитнесе, такие как соотношение мужчин и женщин и т. Д., Без существенного изменения базового метода.

+0

Если я ошибаюсь, просьба указать, почему вместо молчаливой вещи проголосовать, спасибо –

+2

Вы не должны без разбора бросать генетические алгоритмы при любой проблеме оптимизации, которая возникает, в частности, не при небольших и регулярных проблемах, подобных этому. – starblue

+2

Здесь есть много хороших предложений, но я закончил реализацию этого как генетический алгоритм. Главным образом потому, что раньше я не делал никаких GA, и мне было весело. Вы можете скачать мой код отсюда: http://hallvardkorsgaard.spaces.live.com/blog/cns!6A4336898CA0055D!407.entry – Hallis

11

Heres идея
первая работа с точки зрения первого лица .. назовем его X
X должен отвечать всем другим людям в комнате, так что мы следует разделить оставшихся людей на n групп (где n = # _of_people/capacity_per_table) и заставить его сидеть с одной из этих групп на итерацию
Теперь, когда X был позабочен, мы рассмотрим следующего человека Y
WLOG Y быть человеком, которому X должен был сидеть в первой итерации. Поэтому мы уже знаем таблицу Y для этой временной шкалы. Затем мы должны разделить оставшихся людей на группы, чтобы каждая группа сидела с Y для каждого co nsecutive итерации .. и для каждой итерации группы X и группа Y не имеют ни одно лицо, в общем
.. Я думаю, если вы продолжаете делать что-то вроде этого, вы получите оптимальное решение (если таковой существует)

В качестве альтернативы вы может толковать источник проблемы, предоставляя каждому человеку карточку, где они могли бы записывать имена всех людей, с которыми они пообедали ... и в конце мероприятия представляют какой-то приз человеку с наибольшим количеством имен на их карточке

+6

+1 к альтернативному предложению – tanascius

+2

Как и ваша идея о картах! Генетическое программирование в действии. :) –

+1

Напоминает мне http://en.wikipedia.org/wiki/Dance_card – mouviciel

2

Интуитивно я не думаю, что вы можете сделать лучше, чем perfect shuffle, но это не соответствует моему пред-кофейному познанию, чтобы это доказать.

4
+1

Я являюсь автором PerfectTablePlan. PerfectTablePlan может обрабатывать этот сценарий, но для этого нужно немного ручного вмешательства: http://www.perfecttableplan.com/html/PerfectTablePlan_Windows_Help_402/index.html?arrange_multiple_seatings_for_an_event.htm Это на моих «список желаний», чтобы расширить PerfectTablePlan в лучше обрабатывайте несколько мест. –

+1

@ Энди Брайс: Отличная программа! –

+0

@ Энди Брис - Хе-хе, я просто сделал комментарий в шутку. – user79755

6

Почему бы не имитировать реальный мир?

class Person { 
    void doPeriodically() { 
     do { 
      newTable = random (numberOfTables); 
     } while (tableBusy(newTable)) 
     switchTable (newTable) 
    } 
} 

Да, и обратите внимание, что подобный алгоритм поиска брачного партнера и по слухам, чтобы быть эффективным для тех, кто 99% людей, которые не проводят все свое свободное время отвечая на вопросы программирования ...

+0

Я рад видеть, что мой алгоритм скоростного датирования имеет некоторый успех на этом форуме ... –

0

Я бы не стал беспокоиться о генетических алгоритмах. Вместо этого я бы сделал следующее, что было небольшим уточнением при повторных совершенных перетасовках.

Хотя (есть два человека, которые не встречались):

  1. Рассмотрим граф, где каждый узел является гостем и ребро (A, B) существует, если А и В не сидел в то же Таблица. Найти все этого графика. Если есть какие-либо связанные компоненты размером < таблицы, планируйте эти подключенные компоненты за таблицами. Обратите внимание, что даже это на самом деле является примером жесткой проблемы, известной как упаковка бинов, но с первого раза уменьшающаяся, вероятно, будет прекрасной, что может быть достигнуто путем сортировки подключенных компонентов в порядке наибольшей и наименьшей, а затем поместить их каждый из них в повернитесь на первую таблицу, где они подходят.
  2. Выполните произвольную перестановку остальных элементов. (Другими словами, расположите оставшихся людей случайным образом, что сначала будет всем.)
  3. Счетчик приращений, указывающий количество раундов.

Повторяйте приведенное выше какое-либо время, пока количество раундов, похоже, не сходится.

0

WRT @ комментарий неодимовых, вот это page на сайте, который имеет отношение:

Он обсуждает генетические алгоритмы.

2

Это было очень смешно! : D

Я пробовал использовать другой метод, но логика, предложенная adi92 (card + prize), является той, которая работает лучше, чем любая другая, которую я пробовал.

Это работает так:

  1. парень приходит и проверяет все таблицы
  2. для каждой таблицы со свободными местами он подсчитывает, сколько людей он должен встретиться еще, а затем выбрать один с более неизвестным люди
  3. , если две таблиц имеют равное количество неизвестных людей, то парень будет выбрать один с более свободными местами, так что есть больше вероятности встретить новые человек

при каждом повороте порядок людей, принимающих мест является случайным (это позволит избежать возможных бесконечных циклов), то это является «демо» рабочего алгоритма в питоне:

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

Смежные вопросы