Пролог комбинаторика

Есть ли способ сгенерировать все возможности, такие как 9 букв, которые будут разделены на 3 команды, например:

  • 1-я команда: 2 буквы
  • 2-я команда: 3 буквы
  • 3-я команда: 4 буквы
  • ?

Пример:

find([a, b, c, d, e, f, g, h, i], T1, T2, T3).
T1 = [a, b]
T2 = [c, d, e]
T3 = [f, g, h, i]

Следующее поколение должно быть следующей комбинацией, пока не останется больше комбинаций.

1 ответ

Решение

Есть ли способ? Конечно:

-Выберите 2 участника из первоначального списка, поместите их в T1,
-Выберите 3 члена в остальных и поместите их в T2,
Остальное T3:

teams(L, T1, T2, T3) :-
    pick2(L, T1, L1),
    pick3(L1, T2, T3).

pick2(L, [M1, M2], Rest) :-
    member(M1, L),   
    delete(L, M1, L1),
    member(M2, L1),
    delete(L1, M2, Rest).

pick3(L, [M1, M2, M3], Rest) :-
    pick2(L, [M1, M2], L1),
    member(M3, L1),
    delete(L1, M3, Rest).

Запрос

:- teams([a,b,c,d,e,f,g,h,i], T1, T2, T3).

производит запрошенный вывод. Обратите внимание, что в приведенном выше коде предполагается, что ввод введен в правильном формате (т. Е. Список содержит правильное количество элементов).

Обновление: вы можете использовать select/3 Предикат в прологе SWI вместо member/delete комбинации:

teams(L, T1, T2, T3) :-
    pick2(L, T1, L1),
    pick3(L1, T2, T3).

pick2(L, [M1, M2], Rest) :-
    select(M1, L, L1),
    select(M2, L1, Rest).

pick3(L, [M1, M2, M3], Rest) :-
    pick2(L, [M1, M2], L1),
    select(M3, L1, Rest).
Другие вопросы по тегам