Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.03.2011, 11:55   #1
KobolD
Форумчанин
 
Регистрация: 10.06.2010
Сообщений: 239
По умолчанию Перебор комбинаций

Подскажите алгоритм который перебирает всевозможные комбинации элементов одномерного массива, с учетом того что необязательно использовать все элементы массива.

Задача собственно в следующем: Есть ящик в который можно положить инструменты, Молоток, Пила, Отвертка, Дрель и т.д. (пусть будет 10 инструментов). Так вот я могу положить все инструменты, а могу положить только отвертку и молоток или пилу, дрель и отвертку.
Последовательность укладки роли не играет молоток+пила и пила+молоток это одно и тоже.

Язык програмирования роли не играет но желательно на C#. В принципе можно просто словами алгоритм описать.
Чтобы слова не расходились с делом, нужно молчать и ничего не делать.
KobolD вне форума Ответить с цитированием
Старый 14.03.2011, 15:10   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

упорядоченный список пила, отвертка, дрель, ...., молоток, рубанок, НИЧЕГО.
Код:
цикл ящик 1 от пила до НИЧЕГО
  цикл ящик 2 от ящик1 до НИЧЕГО
...
     цикл ящик N  от ящикN-1 до НИЧЕГО  
....  
         цикл ящик 10 от ящик9 до НИЧЕГО  
              если предметы разные то ХОРОШИЙ набор иначе ПЛОХОЙ набор
(при сравнении учитывать что два НИЧЕГО это РАЗНЫЕ предметы)
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 14.03.2011, 15:40   #3
KobolD
Форумчанин
 
Регистрация: 10.06.2010
Сообщений: 239
По умолчанию

Что то я не понял решение, можно коментарии какие-нибудь. Вопервых откуда взялось так много ящиков?
На входе есть массив:
string[] Instruments = { "Пила", "Молоток", "Отвертка", "Дрель", "Лобзик" };
И где то в цикле должен образовываться временный масив
{ "Пила", "Молоток" }, потом { "Пила", "Отвертка"}, ..... { "Пила", "Молоток", "Отвертка"}
Чтобы слова не расходились с делом, нужно молчать и ничего не делать.
KobolD вне форума Ответить с цитированием
Старый 14.03.2011, 15:51   #4
Zer0
Форумчанин
 
Аватар для Zer0
 
Регистрация: 13.12.2007
Сообщений: 788
По умолчанию

я могу помочь, но ближе к вечеру, есть готовый алгоритм генерации всех подмножеств массива (что по сути и нужно), но на Delphi, при желании могу словесно описать

если что пиши -392459949
благодарность - сюда (не забываем писать от кого)
Zer0 вне форума Ответить с цитированием
Старый 14.03.2011, 17:38   #5
Vago
Форумчанин
 
Регистрация: 15.01.2010
Сообщений: 948
По умолчанию

Цитата:
Сообщение от KobolD Посмотреть сообщение
В принципе можно просто словами алгоритм описать.
Хранить все доселе найденные перестановки разрешается?
Vago вне форума Ответить с цитированием
Старый 14.03.2011, 18:48   #6
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

1.
Цитата:
упорядоченный список пила, отвертка, дрель, ...., молоток, рубанок, НИЧЕГО.
добавляем к списку еще один элемент НИЧЕГО (причем он должен быть строго последним)

2.
Цитата:
Код:
цикл ящик 1 от пила до НИЧЕГО
  цикл ящик 2 от ящик1 до НИЧЕГО
...
     цикл ящик N  от ящикN-1 до НИЧЕГО  
....  
         цикл ящик 10 от ящик9 до НИЧЕГО
десять вложенных циклов (десять ящиков)
для исключения перестановок (пила рубанок) и (рубанок пила) вводим правило в каждый след. ящик можно класть только предметы имеющие больший номер в нашем списке.
(для упрощения конструкций цикла облегчим правило (преметы имеющие такой же или больший номер).

3.
Цитата:
если предметы разные то ХОРОШИЙ набор иначе ПЛОХОЙ набор

(при сравнении учитывать что два НИЧЕГО это РАЗНЫЕ предметы)
"восстанавливаем" исходное правило. Исключаем повторы предметов (пила, пила)


P.S. можно избавиться от проверки повторов

упорядоченный список пила, отвертка, дрель, ...., молоток, рубанок, НИЧЕГО1 НИЧЕГО2, .... , НИЧЕГО10(по числу ящиков).

след(элт) эдемент списка следующий за элт

Код:
цикл ящик 1 от пила до НИЧЕГО1
  цикл ящик 2 от след(ящик1) до НИЧЕГО2
...
     цикл ящик N  от след(ящикN-1) до НИЧЕГОN
....  
         цикл ящик 10 от след(ящик9) до НИЧЕГО10
            БЕРЕМ ГОТОВЫЙ НАБОР(ящик1, ящик2, ... ящик10)
и удаляем оттуда НИЧЕГО1, ... НИЧЕГО10.
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 14.03.2011 в 18:51.
evg_m вне форума Ответить с цитированием
Старый 14.03.2011, 19:06   #7
KobolD
Форумчанин
 
Регистрация: 10.06.2010
Сообщений: 239
По умолчанию

evg_m
Спасибо, теперь я разобрался. Только к сожалению меня такое решение не устраивает, т.к. количество циклов привязано к количеству инструментов, и если его менять то получается надо переписывать программу. Я так понимаю тут рекурсию надо использовать, буду сидеть разбираться.

Цитата:
Сообщение от Vago Посмотреть сообщение
Хранить все доселе найденные перестановки разрешается?
Да, так как из число относительно невелико (я думаю до ста миллионов меня устроит)
Чтобы слова не расходились с делом, нужно молчать и ничего не делать.
KobolD вне форума Ответить с цитированием
Старый 14.03.2011, 19:46   #8
Vago
Форумчанин
 
Регистрация: 15.01.2010
Сообщений: 948
По умолчанию

Это - "некрасивый" вариант (хотя и работающий). С хранением всего, что нагенерировали, и с проверкой "А было-ли уже?"
Код:
#!/usr/bin/python
# -*- coding: cp1251 -*-

x = ['Hammer', 'Saw', 'Screwdriver']
xAll = []
xAll.append( x )


def WasAlreadyGenerated( x ):
   for i in range( 0, len(xAll) ):
      if xAll[i] == x:
         return True

   return False


def Cnm( a ):
   if len( a ) == 1:                  # Уже нечего отбрасывать
      if not WasAlreadyGenerated( a ):    # Такой перестановки ещё не было?..
         xAll.append( a )             # ..Добавляем
   else:
#     Будем пытаться удалять по одному элементу
      for k in range( 0, len(a) ):
#        В силу специфики передачи параметров в Питоне, создаём локальную копию
         _a = []
         for j in range( 0, len(a) ):
            _a.append( a[j] )

         _a.remove( a[k] )	         # Удаляем k-й эл-т
         if not WasAlreadyGenerated( _a ):	 # Такой перестановки ещё не было?..
            xAll.append( _a )            # ..Добавляем

         Cnm( _a )

   return


def main():
   Cnm( x )
   for i in range( 0, len(xAll) ):
      print xAll[i]


main()
110314.jpg

Далi буде...

Последний раз редактировалось Vago; 14.03.2011 в 19:48.
Vago вне форума Ответить с цитированием
Старый 14.03.2011, 22:35   #9
Vago
Форумчанин
 
Регистрация: 15.01.2010
Сообщений: 948
По умолчанию

Без накопления.
Код:
#!/usr/bin/python
# -*- coding: cp1251 -*-

# x = ['Hammer', 'Saw', 'Screwdriver']
x = ['1', '2', '3', '4']

def Cnm( a ):
   kAlowestInX = x.index( a[len(a)-1] )
#  Local copy
   _a = []
   for j in range( 0, len(a) ):
      _a.append( a[j] )

   print a
   if len(a) == 1 and a[len(a)-1] == x[len(x)-1]:	# ВСЁ!
      return

   if a[len(a)-1] == x[len(x)-1]:	   # Достигли предела в "младшем разряде"
      _a.remove( _a[len(_a)-1] )     # Удаляем "крайний правый" элемент...
      _a.remove( _a[len(_a)-1] )     # ...и ещё раз...
      kAlowestInX = x.index( a[len(a)-2] )

   _a.append( x[kAlowestInX+1] )    # Добавляем ещё один эл-т в множество

   Cnm( _a )


def main():
   a = []
   a.append( x[0] )
   Cnm( a )


main()
Изображения
Тип файла: jpg 110314_2.jpg (14.9 Кб, 100 просмотров)

Последний раз редактировалось Vago; 15.03.2011 в 01:16. Причина: Упростил, выбросив флажок... И ещё упростил...
Vago вне форума Ответить с цитированием
Старый 16.03.2011, 13:21   #10
KobolD
Форумчанин
 
Регистрация: 10.06.2010
Сообщений: 239
По умолчанию

Спасибо Vago. Я решил остановиться на варианте перебора по маске.
Код:
        static string[] Instruments = { "1", "2", "3", "4"};
        static void Main(string[] args)
        {
            List<string> CurentState = new List<string>();
            bool[] Maska = new bool[Instruments.Length];
            while (Sdvig(ref Maska))
            {
                for (int i = 0; i < Maska.Length; i++)
                    if (Maska[i])
                        CurentState.Add(Instruments[i]);

                //Вот сдесь можно забирать текущий набор значений из списка CurentState

                for (int i = 0; i < CurentState.Count; i++)
                    Console.Write(CurentState[i].ToString());
                Console.WriteLine();
                CurentState.Clear();
            }
            Console.ReadLine();
        }

       
        static bool Sdvig(ref bool[] Mask)//Процедура выполняет побитовое увеличение на единичку
        {
            bool CF = true;
            for (int i = 0; i < Mask.Length; i++)
            {
                if ((CF) && (Mask[Mask.Length - 1]) && (i == Mask.Length - 1))//достигнут конец перебора (все единицы)
                    return false;
                if (CF)
                {
                    Mask[i] = !Mask[i];
                    if (Mask[i])
                        return true;
                }

            }
            return true;
        }
Чтобы слова не расходились с делом, нужно молчать и ничего не делать.
KobolD вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проверка комбинаций в покере. dixonich Помощь студентам 6 01.02.2011 01:47
Перебор возможных комбинаций в матрице N*N Руслан_911 Помощь студентам 3 25.11.2010 20:35
Вычисление множества комбинаций phobia Помощь студентам 3 17.11.2010 10:56
Перебор возможных комбинаций символов Toxask8 Общие вопросы C/C++ 1 12.12.2009 21:33
Delphi. Проверка комбинаций Zhamie Помощь студентам 7 15.09.2009 11:39