Напишите функцию для циклического перебора подмножеств, добавляя / удаляя элементы - PullRequest
4 голосов
/ 23 августа 2011

Проблема: Начните с набора S размера 2n + 1 и подмножества A из S размера n. У вас есть функции addElement(A,x) и removeElement(A,x), которые могут добавлять или удалять элементы A. Напишите функцию, которая перебирает все подмножества S размера n или n + 1, используя только эти две операции над A.

Я выяснил, что есть (2n + 1 выберите n) + (2n + 1 выберите n + 1) = 2 * (2n + 1 выберите n) подмножества, которые мне нужно найти. Итак, вот структура моей функции:

for (int k=0; k<2*binomial(2n+1,n); ++k) {
    if (k mod 2) {
        // somehow choose x from S-A
        A = addElement(A,x);
        printSet(A,n+1);
    } else
        // somehow choose x from A
        A = removeElement(A,x);
        printSet(A,n);
    }
}

Функция binomial(2n+1,n) просто дает биномиальный коэффициент, а функция printSet печатает элементы A, чтобы я мог видеть, ударил ли я все множества.

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

Для n = 1, я нашел решение, которое работает:

for (int k=0; k<6; ++k) {
    if (k mod 2) {
        x = S[A[0] mod 3];
        A = addElement(A,x);
        printSet(A,2);
    } else
        x = A[0];
        A = removeElement(A,x);
        printSet(A,1);
    }
}

и вывод для S = [1,2,3] и A=[1]:

[1,2]
[2]
[2,3]
[3]
[3,1]
[1]

Но даже заставить это работать для n = 2 я не могу сделать. Может кто-нибудь помочь мне с этим?

Ответы [ 2 ]

5 голосов
/ 23 августа 2011

Это не столько решение, сколько еще один способ думать о проблеме.

Сделайте следующий график:

  • Вершины - это подмножества S размеров n или n+1.
  • Между v и w существует грань, если два набора отличаются на один элемент.

Например, для n = 1 вы получите следующий цикл:

 {1} --- {1,3} --- {3}
  |                 |
  |                 |
{1,2} --- {2} --- {2,3}

Ваша задача - найти гамильтонов цикл :

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

Другими словами, эта проблема сложная.

Существует несколько теорем, дающих достаточные условия для существования гамильтонова цикла в графе (например, если все вершины имеют степень, по крайней мере, N/2, где N - количество вершин), но ни одной из них я не знаю сразу подразумевает, что этот граф имеет гамильтонов цикл.

Вы можете попробовать один из бесчисленных алгоритмов, чтобы определить, существует ли гамильтонов цикл. Например, из статьи в википедии о проблеме гамильтонова пути :

Тривиальный эвристический алгоритм определения местоположения гамильтоновых путей состоит в построить путь abc ... и расширять его до тех пор, пока он больше не станет возможным; когда путь abc ... xyz больше не может быть расширен, потому что все соседи z уже лежат на пути, один возвращается на шаг назад, удаляя ребро yz и расширяя путь другим соседом из у; если нет выбора, то получается гамильтонова траектория сделайте шаг назад, удалив край xy и расширив путь другой сосед х и тд. Этот алгоритм, безусловно, будет найти гамильтонов путь (если он есть), но он работает в экспоненциальном времени.

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


Хорошие новости : Хотя проблема с гамильтоновым циклом в целом сложна, этот график очень хорош: он двудольный и (n+1) -регулярный. Это означает, что может быть хорошее решение для этого конкретного графика.

Плохие новости : После небольшого поиска выясняется, что эта проблема известна как гипотеза средних уровней и, похоже, возникла примерно в 1980 году. Я могу сказать, что проблема все еще остается открытой, но она была проверена на компьютере для n <= 17 (и я нашел препринт от 12/2009, требующий проверки n=18). Эти две страницы имеют дополнительную информацию о проблеме и ссылки:

0 голосов
/ 23 августа 2011

Подобные вещи описаны в Knuth Vol 4A (который, несмотря на прекрасные романы Чарльза Стросса о стирке, теперь доступен в открытом доступе). Я думаю, что ваш запрос удовлетворен разделом монотонного двоичного кода Грея, описанного в разделе 7.2.1.1. Существует электронная препринт в формате PDF на http://www.kcats.org/csci/464/doc/knuth/fascicles/fasc2a.pdf

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...