Алгоритм поиска подмножества, равного сумме с наименьшей стоимостью

Учитывая один (1xN) список положительных весов (не обязательно целые числа, т.е. числа с плавающей запятой) и список соответствующих затрат равной длины (1xN), я хочу найти подмножество списка весов, которое суммируется точно с заданной суммой S и имеет наименьший стоимость (сумма затрат * веса, соответствующие подмножеству в списке весов). Лучше всего было бы написать на Python (если это возможно), так как я не очень хорошо разбираюсь в других языках!

Пример:

w = [2.5, 3.0, 1.0, 5.5] # Weight list
c = [1.0, 1.5, 2.0, 3.0] # Cost list
S = 6.5 # Target sum

Для этого случая у нас есть два возможных подмножества, которые в сумме дают S:

sub1 = [2.5, 3.0, 1.0]
sub2 = [1.0, 5.5]

Затраты на эти подмножества составляют:

cost1 = 2.5*1.0+3.0*1.5+1.0*2.0 = 9.0
cost2 = 1.0*2.0+5.5*3.0 = 18.5

Поскольку подмножество 1 имеет наименьшую стоимость (9,0), мне нужно именно это подмножество.

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

Я искал разные решения, но я мог найти только решения для Python, которые решают проблему равной суммы и одновременно не получают наименьшую стоимость. Вот пример такого решения: Certain-Number">Алгоритм поиска числа в списке, которое в сумме дает определенное число.


person sheg    schedule 07.03.2017    source источник
comment
Являются ли веса хотя бы положительными? В любом случае, это очень простая задача целочисленного линейного программирования 0-1 с единственным ограничением равенства. Таким образом, такие вещи, как алгоритм ветвей и границ, будут работать, хотя могут быть и более простые подходы. Динамическое программирование, безусловно, является естественным путем. Что вы пробовали?   -  person John Coleman    schedule 07.03.2017
comment
Для справки, это известно как проблема суммы подмножества /a> и широко распространено мнение, что эффективного решения этой проблемы не существует. (Конечно, вы не просите эффективного решения, просто решения)   -  person Cruncher    schedule 07.03.2017
comment
Я обновил вопрос. Да, веса имеют положительные действительные значения. Я надеюсь на что-то по крайней мере более эффективное, чем проверка всех возможных комбинаций.   -  person sheg    schedule 07.03.2017
comment
@sheg, если вы посмотрите на страницу Википедии, на которую я дал ссылку, она объясняет наиболее эффективные алгоритмы, которые мы знаем в настоящее время. Вы не можете ожидать, чтобы сделать лучше, чем они. Вам просто нужно немного изменить его, чтобы проверить возможные решения с вашим весом. Должна быть довольно тривиальная модификация   -  person Cruncher    schedule 07.03.2017
comment
@Cruncher Спасибо за предложение! Мне кажется, что предоставленная вами страница Википедии не учитывает стоимостной аспект проблемы. Так что вы имеете в виду, чтобы использовать решение, предложенное в ссылке Википедии, чтобы найти все возможные подмножества, а затем найти подмножество с наименьшей стоимостью?   -  person sheg    schedule 07.03.2017
comment
Где твоя работа? Пришло время продолжить расследование Кранчера. Я отмечу, что даже если ваши данные не являются целыми числами, вы все равно можете открыть некоторые параметры, используя целые числа. OP может быть выражен как точные целые числа, или вы можете использовать эпсилон.   -  person Kenny Ostrom    schedule 07.03.2017
comment
@sheg аспект затрат - очень небольшая часть проблемы. Вполне возможно, что алгоритм даст наименьшую стоимость, поскольку массив в любом случае сортируется по стоимости, но я не очень хорошо знаком со спецификой алгоритма. Вам нужно просто подумать о проблеме и о том, как вы можете изменить ее, чтобы она соответствовала вашей гарантии. Дополнительные затраты не добавляют к проблеме вычислительной сложности. Вам просто нужно быть умным об этом. Добавление затрат, скорее всего, просто затруднит вам поиск решения проблемы в гугле.   -  person Cruncher    schedule 07.03.2017
comment
@Cruncher Хорошо, мне приятно знать, что это не усложняет работу с затратами, поскольку это действительно не моя область, и для меня это также может быть важно для алгоритма. Постараюсь решить проблему, спасибо   -  person sheg    schedule 07.03.2017


Ответы (1)


Наконец, я решил проблему, используя бинарное целочисленное программирование, предложенное Джоном Коулманом. Вот код: https://github.com/sebastianheg/knapsack-problem.

person sheg    schedule 11.03.2017