Какой алгоритм может решить проблему моего свадебного стола?

У меня есть x гостей для моей свадьбы и у стола с z местами. Гость A может сидеть на том же столе, что и гость B, а гость C не может сидеть в той же таблице, что и гость D,....

Учитывая набор данных о всех связях между всеми гостями, существует ли известный алгоритм, который может решить эту проблему?

Я уверен, что в этой проблеме есть абстрактный родитель, известный как "проблема x" или что-то, или, может быть, это состав проблемы a и проблемы b, который можно решить, объединив алгоритм y и z

Оценивается любая точка в правильном направлении.

Ответ 1

Если вам требуется точное решение, сформулируйте его как целочисленную программу 0-1 и используйте GLPK для ее решения.

Пусть x_ij равно 1, если человеку я присваивается таблица j и 0 в противном случае. Рассмотрим следующее ограничение:

(i) sum_ {j = 1... y} x_ij = 1 для я = 1... x

(ii) sum_ {i = 1... x} x_ij <= z для j = 1... y

(iii) x_ij + x_kj <= 1 для j = 1... y

(iv) x_ij является двоичным

Ограничения (i) убедитесь, что все назначены. Ограничения (ii) предотвращают перегрузку таблицы. Ограничения (iii) определены для каждой пары лиц (i, k), которые не могут сидеть вместе.

Подключите его в GLPK, CPLEX или GUROBI, и вы находитесь в бизнесе при условии, что проблема не слишком велика. Как говорили другие, NP-твердость означает, что все может стать уродливым.

Ответ 2

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

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

Надеюсь, это поможет!

Ответ 3

Это проблема NP-hard, поэтому вы не найдете общего решения. Фактически, даже поиск z гостей, которые могут сидеть вместе за одним столом, NP-hard.

Однако, если у вас слишком много конфликтов с гостями, возможно, будет работать эвристика. Например:

Pick an unseated guest G with a maximal number of incident edges (conflicts)
  If G has a conflict with someone seated at each table, then fail
  Else assign G at random to an available table
Repeat until all guests are seated

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

Pick an unseated guest G such that the size of G.availableTables is minimal
  If G.availableTables is empty, then fail
  Assign G at random to a table T from G.availableTables
  For each guest G2 who is in conflict with G
    remove T from the set G2.availableTables
Repeat until all guests are seated.

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

На практике, если эвристика, подобная этой, не работает после попытки нескольких сотен рандомизированных попыток, то, вероятно, это будет трудная проблема для решения.