#python #algorithm
#python #алгоритм
Вопрос:
Учитывая, что в файле данных указаны идентификатор магазина, стоимость, товары, какой алгоритм мне следует использовать, чтобы получить все запрошенные запасные части из одного магазина с минимальным выигрышем. Если не удается найти ни одного магазина, следует напечатать «None». Кроме того, нет ничего плохого в покупке дополнительных запасных частей за минимальный приз.
Shop ID, Cost($), Items List
1, 4.00, E
1, 8.00, F
2, 5.00, E
2, 6.50, F
5, 4.00, A
5, 8.00, D
6, 5.00, D
6, 6.00, A, B, C ; Here in 6$ three items can be obtained
7, 2.20, B
7, 3.00, B,C
7, 2.00, B
7, 2.50, C
a) Spare Parts : A,D
Output:
Shop ID-6
Cost - 11.0$
b) Spare Parts : E,F
Output:
Shop ID-2
Cost - 11.5$
Мой подход (который не работает):
a) Сначала получите общие идентификаторы магазинов для заданных входных данных
shop_id_list=[]
for items in input_list:
shop_id_list = getCommonShopIds(items.strip(), shop_id_list )
all_items.append( items )
б) Для каждого all_items
получите минимальную стоимость этого элемента во всех shop_id_list
(0, если элементы уже включены в последнюю итерацию)
res = [0 for x in range(len(shop_id_list)) ]
for items in all_items:
all_cost = getMinShopCost( shop_id_list, items )
res= map(operator.add, all_cost, res ) # Add those list
c) Найдите минимальный индекс элемента в res (скажем, i
) и выведите соответствующий shop_id_list[i]
и res[i]
Моя логика не работает для таких случаев, как:
Ввод: B C
Он выводит 7 4.5 $
Ожидаемый показатель должен составлять 7 3,00 $
Является ли это какой-либо стандартной задачей или вариацией какой-либо задачи теории графов и т.д.?
Я не могу найти какой-либо оптимизированный подход, буду признателен за любую помощь.
PS: Python помечен только потому, что в вопросе есть фрагмент кода python, меня просто интересует подход. Кроме того, это не проблема с онлайн-конкурсом, о котором я не знаю.
Комментарии:
1. Здесь есть 2 шага. Сначала вам нужно найти, какие места могут удовлетворять ограничению. Назовите этот набор S. Если S пустое, то вы возвращаете none. Если значение S не пустое, то вы рассчитываете стоимость их получения из каждого места в S. Вы возвращаете место, стоимость которого самая низкая из мест в S. Проблема намного сложнее, если вы можете получить запчасти более чем из одного места.
2. Сколько примерно существует различных деталей?
3. @j_random_hacker Это не указано / неизвестно, данные должны вводиться из файла csv
4. Я спрашиваю, потому что есть простой алгоритм DP, который экспоненциально зависит от количества различных продуктов, поэтому будет идеально, если это меньше ~ 20, но совершенно бесполезно, если это > 30.
5. Также: как может быть, что вы даже приблизительно не знаете, сколько разных деталей может быть? Есть ли кто-нибудь, кого вы можете спросить об этом? В противном случае это звучит так, как будто это проблема онлайн-конкурса…
Ответ №1:
Здесь есть 2 шага.
Первый шаг: сначала вам нужно найти, какие места могут удовлетворить ограничению наличия всех необходимых деталей на складе. Вызовите набор мест, который соответствует этому ограничению set S. Если S пустое, то вы возвращаете none. Если значение S не пустое и имеется более одного местоположения, то вы переходите ко второму шагу.
Второй шаг: вам нужно рассчитать стоимость получения запчастей из каждого места в S. Вычисление стоимости для отдельного места является проблемой удовлетворения ограничений. http://en.wikipedia.org/wiki/Constraint_satisfaction_problem. Есть несколько способов, которыми вы могли бы решить эту проблему. Один из способов — использовать подход, основанный на смешанном целочисленном LP, со следующей формулировкой:
Let X be the item groups bought
let y_1, .. y_n be the items you require
min F(X) = sum cost(X)
subject to:
y_i in X, for i in {1,..,n}
По сути, у вас есть некоторые бинарные ограничения. Скорее всего, есть лучшие способы сформулировать это, но, надеюсь, это даст вам общее представление.
Возможно, вы могли бы решить эту проблему с помощью какого-нибудь LP-решателя, такого как симплексный метод.
Если вы используете Python, взгляните на эти библиотеки решателей: http://www.scipy.org
https://software.sandia.gov//trac/coopr
https://code.google.com/p/pulp-or
После расчета затрат вы возвращаете место с наименьшей стоимостью из мест в S
Комментарии:
1. 1 Спасибо за подход, я пытаюсь понять, мне может потребоваться некоторое время
2. @P0W, рад, что это помогает. Я занимался подобными вещами довольно много лет. Я думаю, что попытка решить этот вопрос могла бы стать отличным постом в блоге, поэтому я сделаю это, если у меня будет время.
Ответ №2:
Если проблема небольшая, то подойдет простое отслеживание назад :-
- Сделать для каждого магазина
- выберите предложение, которое еще не выбрано и содержит по крайней мере подмножество непроданных товаров.
- сделайте предложение выбранным и отметьте все охватываемые им товары как выбранные.
- рекурсивный выбор до тех пор, пока не будут исчерпаны все позиции или не останется приемлемого предложения.
- запишите минимальную стоимость всех возможных покупок.
Кроме того, вы также можете предотвратить рекурсию, если стоимость уже превышает текущую минимальную стоимость.
Если количество предложений невелико, используйте также метод грубой силы :-
- выберите подмножество предложений и отметьте все позиции, которые оно охватывает.
- сгенерируйте из него n-разрядное число.
- Поместите в хэш-карту n => минимальную стоимость.
Это очень эффективно, если у вас несколько заказов, так как тогда вам просто нужно выполнить поиск в хэш-карте, введя n-разрядный номер заказа.
Вы также можете попробовать метод ветвления и привязки с оценкой в виде суммы элементов, взятых по отдельности