Генерация сочетаний (Обычное приложение)




Генератор сочетаний 1С

Сочетаниями из n элементов по k называются соединения, которые можно образовать из n элементов, собирая в каждое соединение k элементов; при этом соединения отличаются друг от друга только самими элементами (различие порядка их расположения во внимание не принимается).

Например, из 3 элементов (a,b,c) по 2 можно образовать следующие сочетания: ab, ac, bc.

Число всех возможных сочетаний, которые можно образовать из n элементов по k, обозначается символом Cnk и вычисляется по формуле:

За основу математических алгоритмов был взяты статьи с http://algolist.manual.ru/maths/combinat/

Так же хочется поблагодарить пользователя noblekey за его алгоритм генерации случайных чисел. Код был взят с публикации //infostart.ru/public/57305/

Алгоритм генерации сочетаний обширно использовался мною на олимпиадах по 1С.

Возможно, есть более быстрые решения. Обработка поддерживает максимально число из 20 цифр, но можно добавить в табличную часть «Числа» реквизиты вида «Цифра_21″,»Цифра_22» и больше, и после чего будет поддерживаться числа, длиной больше 20 цифр.

12 Comments

  1. rayastar

    По необходимости могу выложить работу на управляемых формах

    Reply
  2. WKBAPKA

    а есть что нибудь для необычных приложений?

    Reply
  3. rayastar

    (2) WKBAPKA, есть «что нибудь» для управляемого приложения)

    Reply
  4. mikuho

    Долго переделывали алгоритм?

    Reply
  5. rayastar

    (4) mikuho, алгоритм переделывал с паскаля. но собирал его из двух исходников. в целом, ушло около 6 часов на написание(pascal) и перенос на 1С. Много возникало нюансов по поводу генерации случайных чисел. Не обошлось без помощи коллег)

    Reply
  6. DrAku1a

    Алгоритм?

    В самом простом для понимания виде:

    F = N-k+1;
    Для сч1=1 По F Цикл
    Для сч2 = сч1+1 По F+1 Цикл
    Для сч3 = сч2+1 По F+2 Цикл
    …
    // и таких циклов k штук
    
    Комбинация = (сч1, сч2, сч3, …, счk);
    
    …
    КонецЦикла;
    КонецЦикла;
    КонецЦикла;

    Показать

    Вот из жизни: подходишь к двери, на ней кодовый замок (нужно нажать три кнопки из десяти и дверка откроется, визуально код определить не возможно — на кнопках нет потёртостей). Нужно перебрать все возможные варианты.

    Алгоритм перебора:

    1. Зажимаешь пальцами одной руки 1 и 2, перебираешь свободной клавиши 3,4,5,6,7,8,9,0,

    2. Далее зажимаешь 1 и 3, перебираешь 4,5,6,7,8,9,0 (2 не надо, т.к. 123 равнозначно 132)

    … и так до 1 и 8, нажимаешь 9.

    3. Зажимаешь 2 и 3, перебираешь 4,5,6,7,8,9,0 (1 не надо, т.к. с ним уже все комбинации перебрали)

    4. Зажимаешь 2 и 4, перебираешь 5,6,7,8,9,0

    и так до 8-9-0

    или тоже самое в коде:

    Для сч1=1 По 8 Цикл
    Для сч2 = сч1+1 По 9 Цикл
    Для сч3 = сч2+1 По 10 Цикл
    ПроверитьКомбинацию(сч1, сч2, ?(сч3=10, 0, сч3));
    КонецЦикла;
    КонецЦикла;
    КонецЦикла;

    Для общего случая, когда N и k заранее неизвестны — подойдет использование рекурсии.

    Reply
  7. rayastar

    (6) DrAku1a, Согласен, есть простое понимание. А есть универсальное, в котором не нужно учитывать количество циклом и писать 20 «Для Каждого Цикл». Главное свойство любого алгоритма — оптимальность и универсальность.

    Reply
  8. anig99

    не совсем понимаю зачем это, но плюс

    Reply
  9. rayastar

    (8) anig99, В прикладных задачах найти применение трудно. Я писал конфигурацию по Лото(сбор, анализ данных, планирование ставок и тому подобное) Если интересно — могу выложить на всеобщее обозрение. Вот как раз там я использовал данный алгоритм

    Reply
  10. mikuho

    (9) а что за конфигурация, можно по подробней? я кажется пишу нечто подобное

    Reply
  11. rayastar

    (10) mikuho, анализ данных лото. делал летом этого года, около 5-6 месяцев)

    Reply
  12. rayastar

    Могу выложить на всеобщее обозрение

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *