Все комбинации 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 - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, си шарп, алгоритмы, комбинаторика




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Урок 12. Оператор switch в Java
Буферизация файлов в Windows
Урок 24. Получение информации DateTime C#