Метод перебора упаковки в корзину

Мне нужно написать программу, которая решает проблему упаковки в контейнеры, но я уже сделал первые подходящие и жадные алгоритмы, но мой лектор говорит, что в некоторых случаях она не найдет минимального решения проблемы. Поэтому я решил попробовать брутфорс, но я понятия не имею, как он должен проверять все возможные решения. Так что да ... может кто-нибудь объяснить мне или дать псевдокод или что-то в этом роде. Я был бы очень признателен.


person Domas Mar    schedule 18.04.2013    source источник
comment
Вот код, написанный на Паскале. Все данные считываются из файла data.txt.   -  person Domas Mar    schedule 18.04.2013
comment
Связано.   -  person Bernhard Barker    schedule 18.04.2013


Ответы (3)


Обратите внимание, что bin-packing — это NP-сложная проблема, в основном означающая, что для ее решения потребуется слишком много времени. использовать грубую силу даже для относительно небольших входных данных, поэтому грубая сила для NP-сложных задач почти никогда не бывает хорошей идеей. Ссылка выше показывает некоторые альтернативы (или приближения). Но я продолжу...

Рекурсия упрощает перебор. Как только вы поймете основной рекурсивный алгоритм, продолжайте читать...

Основная идея: (для 3 предметов, 2 корзины, при условии, что все подходит, если он просто не пропускает эту ветку)

Put the first item in the first bin.
  Put the second item in the first bin.
    Put the third item in the first bin.
      Woo-hoo! We have a solution!
    Remove the third item from the first bin and put it into the second bin.
      Woo-hoo! We have a solution!
    Remove the third item from the second bin.
  Remove the second item from the first bin and put it into the second bin.
    Put the third item in the first bin.
      Woo-hoo! We have a solution!
    Remove the third item from the first bin and put it into the second bin.
      Woo-hoo! We have a solution!
    Remove the third item from the second bin.
  Remove the second item from the second bin.
Remove the first item from the first bin and put it into the second bin.
  Put the second item in the first bin.
    Put the third item in the first bin.
      Woo-hoo! We have a solution!
    Remove the third item from the first bin and put it into the second bin.
      Woo-hoo! We have a solution!
    Remove the third item from the second bin.
  Remove the second item from the first bin and put it into the second bin.
    Put the third item in the first bin.
      Woo-hoo! We have a solution!
    Remove the third item from the first bin and put it into the second bin.
      Woo-hoo! We have a solution!
    Remove the third item from the second bin.
  Remove the second item from the second bin.
Remove the first item from the second bin.

(Смотрите, сколько там уже ступенек? И это только на 3 предмета и 2 корзины)

Псевдокод:

recurse(int itemID)
  if pastLastItem(itemID)
    if betterThanBestSolution
      bestSolution = currentAssignment
    return
  for each bin i:
    putIntoBin(itemID, i)
    recurse(itemID+1)
    removeFromBin(itemID, i)
person Bernhard Barker    schedule 18.04.2013
comment
попробуйте 1025 элементов... stackoverflow :) (да, в любом случае это займет целую вечность, так что это не имеет большого значения) - person Geoffrey De Smet; 18.04.2013
comment
@GeoffreyDeSmet Легко немного увеличить размер стека с помощью параметров командной строки для Java (размер по умолчанию довольно мал), не могу вспомнить точную команду. - person Bernhard Barker; 18.04.2013
comment
Спасибо за ваш комментарий :) - person Domas Mar; 19.04.2013
comment
Здравствуйте, сегодня мне удалось наконец-то закончить свою программу с вашей помощью! Большое спасибо :) Я немного оптимизировал свой брутфорс, и теперь он работает довольно быстро. - person Domas Mar; 20.04.2013

Брутфорс просто пробует каждую комбинацию.

введите здесь описание изображения

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

00000000

Затем напишите один цикл, увеличивающий его в восьмеричной системе счисления:

00000001
00000002
00000003
...
00000007 // 7 + 1 = 10
00000010
00000011
00000012
...
77777776
77777777

Это пробует все комбинации без необходимости жестко кодировать 8 внутренних циклов. Замените 8 на n, и тот же код по-прежнему будет работать.

person Geoffrey De Smet    schedule 18.04.2013
comment
На всякий случай полезно указать, что такое восьмеричные числа. - person Bernhard Barker; 18.04.2013

Вы, очевидно, можете добиться большего, чем просто грубая сила. Сначала вы вычисляете минимальное количество бункеров. Если у вас есть ячейки размером 100 и элементы с общим размером 1234, то они не поместятся в 12 ячеек, но могут поместиться в 13.

С 13 ячейками у вас будет неиспользуемое пространство 66 (1300 - 1234). Поскольку 5 x 13 = 65, должен быть хотя бы один неиспользуемый бин размером 6. Таким образом, если у вас есть какие-либо предметы размером 6 или меньше, вы можете не учитывать их в расчетах, потому что вы все равно можете вместить их в конце (конечно, вам нужно свериться с фактическими номерами, которые у вас есть, но в любом случае мелкие предметы могут быть удален из поиска).

Если два предмета точно заполняют корзину, вам не нужно рассматривать какое-либо решение, если они не подходят друг другу.

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

person gnasher729    schedule 31.03.2014