Все комбинации 6 из 36 и общий алгоритм
Немалое число программ, которые я создаю на заказ для своих клиентов, требуют усиленной работы мозга; использования хитрых алгоритмов. Иногда алгоритмы приходится создавать самому и при этом обращаться за помощью к коллегам. Вот, например, сейчас я работаю над одним интересным заказом: по сути дела это программа, представляющая собой глобальную систему фильтров, которая по заданным пользователем параметрам отфильтрует конечный результат, основанный на принципах комбинаторики сочетаний. По сути всё основывается на 3 принципах: включить, исключить, ограничить.
Заказчица не разрешила выкладывать программу в открытый доступ, но милостиво позволила опубликовать ряд заметок по принципам (алгоритмам) и схемам, которые я использовал при написании данной программы. В этой заметке мы научимся создавать комбинации, которые будем затем отсортировывать нашими фильтрами.
Итак, первая задача заключается в том, чтобы получить исходный набор комбинаций. Нам требуется создать систему, которая будет генерировать комбинации до 40 из 80 Для примера возьмем 6 из 36. Вот код, который получает все такие комбинации в массив.
int count = 0; for (int i1 = 1; i1 <= 31; i1++) { for (int i2 = i1 + 1; i2 <= 32; i2++) { for (int i3 = i2 + 1; i3 <= 33; i3++) { for (int i4 = i3 + 1; i4 <= 34; i4++) { for (int i5 = i4 + 1; i5 <= 36; i5++) { for (int i6 = i5 + 1; i6 <= 36; i6++) { massALL[count] = i1 + " " + i2 + " " + i3 + " " + i4 + " " + i5 + " " + i6; } } } } } }Обращаю внимание, что нам неважен порядок выпадения номеров (как в лотерее). По сути вы, наверно и сами догадались, что это получается как бы генератор лотереи; по крайне мере выглядит очень похоже. Код выше прекрасно работает, но нам то надо самим вводить общее количество чисел всего и в комбинации. Поэтому код выше надо заменить на рекурсивную функцию. Вот такую:
void GetMass(int for1, int for2, int level = 1, int prev = 1, string str = "") { string item = string.Empty; for (int i = prev; i < ((for2 + 1) - (for1 - level)); i++) { if (level > for1) break; else if (level == for1) { count++; massALL[count] = str + " " + i.ToString(); } else GetMass(for1, for2, level + 1, i + 1, str + (str.Length > 0 ? " " : "") + i.ToString()); } }Огромное спасибо за помощь в написании рекурсии Евгению (HectorPrima). Используем в частности вот так
for (int i = 0; i < massALL.Length; i++) { massALL[i] = ""; } chiselInComb = (int)numericUpDown1.Value; chiselAll = (int)numericUpDown2.Value; GetMass(chiselInComb, chiselAll); MessageBox.Show("Всего комбинаций " + count.ToString());Результат:
Как видите, у нас получается почти два миллиона комбинаций. Причем программа считает довольно быстро – массив заполняется буквально за пару секунд. В следующих заметках мы добавим фильтры и там уже программе придется туговато – время работы будет достигать одной минуты. Но в дальнейшем мы оптимизируем и этот процесс.
Если вам требуется создать программу на заказ, помочь с языками программирования, разобраться в чем-то, то вы всегда можете обратиться за консультацией ко мне. На почту up777up@yandex.ru, в скайп up777up2 или вконтакте - https://vk.com/idup7. Я с удовольствием и за небольшую плату помогу вам с программами на таких языках как C++, C#, Java, PHP.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.