Кто знает правильные алгоритмы?
Правила форума
Пожалуйста, ознакомьтесь с правилами данного форума
Пожалуйста, ознакомьтесь с правилами данного форума
- sz
- Маньяк
- Сообщения: 1266
- Зарегистрирован: 17 фев 2003, 19:34
Кто знает правильные алгоритмы?
Для задачи оптимизации покупок.
Ну, например, есть односвязный список товаров:
struct Goodie
{
float price;
float quality;
Goodie* next;
};
И нужно написать функцию, которая в пределах бюджета соберет максимальный quality. Ну, скажем:
Goodie* CreateBusket( Goodie* list, float budget );
Возвращает, разумеется, односвязный список. Исходный список можно (да, в общем-то, и нужно) разрушать после прохождения.
Время исполнения очень критично, но к счастью, списки довольно маленькие - порядка десятков.
Наверняка ведь напридумывано уже до фига алгоритмов, швырните в меня ключевыми словами. Куда копать?
Ну, например, есть односвязный список товаров:
struct Goodie
{
float price;
float quality;
Goodie* next;
};
И нужно написать функцию, которая в пределах бюджета соберет максимальный quality. Ну, скажем:
Goodie* CreateBusket( Goodie* list, float budget );
Возвращает, разумеется, односвязный список. Исходный список можно (да, в общем-то, и нужно) разрушать после прохождения.
Время исполнения очень критично, но к счастью, списки довольно маленькие - порядка десятков.
Наверняка ведь напридумывано уже до фига алгоритмов, швырните в меня ключевыми словами. Куда копать?
- Дима
- Маньяк
- Сообщения: 1455
- Зарегистрирован: 15 авг 2006, 10:21
- Откуда: Минск->Vancouver->Victoria
- sz
- Маньяк
- Сообщения: 1266
- Зарегистрирован: 17 фев 2003, 19:34
- ajkj3em
- Маньяк
- Сообщения: 2063
- Зарегистрирован: 12 ноя 2006, 06:53
- Дима
- Маньяк
- Сообщения: 1455
- Зарегистрирован: 15 авг 2006, 10:21
- Откуда: Минск->Vancouver->Victoria
И точно, не изменяет. Вот популярная статья по этому поводу. http://www.kgtu.runnet.ru/WD/TUTOR/lp/lp03.html
Правда, в твоем случае неравенство одно - ограничение на бюджет. Целевая функция - суммарное качество.
Очевидно, что твой случай - вырожден, и оптимальное решение - взять продукт, у которого соотношение цена-качество лучще всего
Если же появляются другие ограничения, то без ЛП не обойтись.
Правда, в твоем случае неравенство одно - ограничение на бюджет. Целевая функция - суммарное качество.
Очевидно, что твой случай - вырожден, и оптимальное решение - взять продукт, у которого соотношение цена-качество лучще всего

- Дима
- Маньяк
- Сообщения: 1455
- Зарегистрирован: 15 авг 2006, 10:21
- Откуда: Минск->Vancouver->Victoria
Подозреваю еще, что в твоем случае речь идет только о целочисленных решениях. Тогда ты попал
Вот полезная ссылочка. http://www.sampo.ru/~alexeyf/lp_faq.html

-
- Частый Гость
- Сообщения: 41
- Зарегистрирован: 08 май 2006, 17:20
Эта задача называется 0-1 knapsack problem. Если price была бы в целых числах, можно было бы решить за время O(n*b), n - количество товаров в списке, b - бюджет (например в центах), и с дополнительным местом размером O(b). В общем случае, b - диапазон значений бюджета - например для float - все представимые значения от 0 до budget, что делает решение непрактичным.
Если нужен код для целочисленной версии, могу написать пример.
Если нужен код для целочисленной версии, могу написать пример.
-
- Маньяк
- Сообщения: 2803
- Зарегистрирован: 29 май 2003, 22:29
- Откуда: Магадан - Миссиссага
фукция(ции) качество/товар там не задана. Целевая функция будет вовсе не линейной. Возможность представления фунции цели в виде суммы - не признак линейности. Каждое из "слагаемых" может быть нелинейной, вообще разрывной функцией.ajkj2em писал(а):йепДима писал(а):Раздел называется Линейное программирование.
- sz
- Маньяк
- Сообщения: 1266
- Зарегистрирован: 17 фев 2003, 19:34
Я, похоже, плохо объяснил условие.
Суть в том, что товаров можно взять много, причем не важно, сколько. Важно, чтобы суммарное качество было максимальным при цене укладывающейся в бюджет.
На самом деле, я сейчас сделал очень приблизительное решение (для проверки концепции), которое просто выбирает лучший товар вписывающийся в бюджет и кладет в корзину, потом повторяет операцию для остатка бюджета и так далее, пока таковые находятся.
Ну, на самом деле, просто отбрасываю все не помещающиеся в бюджет, а остатки сортирую по качеству. И беру сверху до тех пор, пока в бюджете есть место.
Как ни странно, работает прилично. Хотя оптимального решения и не дает. Хотелось бы находить оптимальное. Да и выполняться побыстрее не мешало бы..
Суть в том, что товаров можно взять много, причем не важно, сколько. Важно, чтобы суммарное качество было максимальным при цене укладывающейся в бюджет.
На самом деле, я сейчас сделал очень приблизительное решение (для проверки концепции), которое просто выбирает лучший товар вписывающийся в бюджет и кладет в корзину, потом повторяет операцию для остатка бюджета и так далее, пока таковые находятся.
Ну, на самом деле, просто отбрасываю все не помещающиеся в бюджет, а остатки сортирую по качеству. И беру сверху до тех пор, пока в бюджете есть место.
Как ни странно, работает прилично. Хотя оптимального решения и не дает. Хотелось бы находить оптимальное. Да и выполняться побыстрее не мешало бы..
-
- Частый Гость
- Сообщения: 41
- Зарегистрирован: 08 май 2006, 17:20
Товаров можно взять много - это значит можно из данного списка взять несколько или каждого товара из списка можно больше чем один взять (например 10 товаров типа а, 20 типа б и т.д.)?Старина Зотин писал(а):Я, похоже, плохо объяснил условие.
Суть в том, что товаров можно взять много, причем не важно, сколько. Важно, чтобы суммарное качество было максимальным при цене укладывающейся в бюджет.
Вот пример на котором это решение дает ответ далекий от оптимального:Старина Зотин писал(а): На самом деле, я сейчас сделал очень приблизительное решение (для проверки концепции), которое просто выбирает лучший товар вписывающийся в бюджет и кладет в корзину, потом повторяет операцию для остатка бюджета и так далее, пока таковые находятся.
Ну, на самом деле, просто отбрасываю все не помещающиеся в бюджет, а остатки сортирую по качеству. И беру сверху до тех пор, пока в бюджете есть место.
Как ни странно, работает прилично. Хотя оптимального решения и не дает. Хотелось бы находить оптимальное. Да и выполняться побыстрее не мешало бы..
товар 1 - цена 6, качество 51
товар 2 - цена 5, качество 50
товар 3 - цена 5, качество 50
бюджет 10
Ваш алгоритм дает 51 вместо 100.
А быстрого оптимального решения к сожалению нет - если конечно кто нибудь не докажет что P=NP

Последний раз редактировалось anton2 21 сен 2006, 20:22, всего редактировалось 1 раз.
- папа Карло
- Шарманщик
- Сообщения: 8565
- Зарегистрирован: 17 фев 2003, 15:04
- Откуда: НН -> BC -> WA -> UT -> CA
задача о ранце это. там есть алгоритм кк решать.Старина Зотин писал(а):Да, я думал об этом. Но, откровенно говоря, пока не придумал, как к этой задаче симплекс-метод приложить..Дима писал(а):Раздел называется Линейное программирование. Ключевые слова алгоритма - симплекс-метод, если мне память не изменяет..

- sz
- Маньяк
- Сообщения: 1266
- Зарегистрирован: 17 фев 2003, 19:34
- sz
- Маньяк
- Сообщения: 1266
- Зарегистрирован: 17 фев 2003, 19:34
Самое забавное, что эта фигня, которую я написал в виде прототипа, оказывается, называется громким именем Martello and Toth greedy approximation algorithm.
Наверное, чуваки очень долго думали..
Кстати, мне придется с ним и остаться. Динамическое программирование в моем случае не работает. Я с целью упрощения не все рассказал о задаче. На самом деле у меня каждый предмет представляет из себя дерево предметов, суммарное value которых составляет value корня, ну и price, соответственно распределяется по ветвям. Если дерево перестает помещаться, его можно раздробить и включать отдельные ветви. В этом случае этот самый Martello and Toth обеспечивает довольно плотное заполнение (хотя и не оптимальное, но не слишком от него далекое - явно больше V/2, как с линейным списком), а кроме того я придумал, как все сделать за один проход дерева.
А динамическое программирование не работает, потому что результаты предыдущей итерации в этом случае, не обязательно подходят для следующей. Иногда можно добиться лучшего заполнения при неоптимальном заполнении на предыдущем шагу.
Наверное, чуваки очень долго думали..
Кстати, мне придется с ним и остаться. Динамическое программирование в моем случае не работает. Я с целью упрощения не все рассказал о задаче. На самом деле у меня каждый предмет представляет из себя дерево предметов, суммарное value которых составляет value корня, ну и price, соответственно распределяется по ветвям. Если дерево перестает помещаться, его можно раздробить и включать отдельные ветви. В этом случае этот самый Martello and Toth обеспечивает довольно плотное заполнение (хотя и не оптимальное, но не слишком от него далекое - явно больше V/2, как с линейным списком), а кроме того я придумал, как все сделать за один проход дерева.
А динамическое программирование не работает, потому что результаты предыдущей итерации в этом случае, не обязательно подходят для следующей. Иногда можно добиться лучшего заполнения при неоптимальном заполнении на предыдущем шагу.
- nemiga
- Маньяк
- Сообщения: 2425
- Зарегистрирован: 02 сен 2006, 19:05
- Откуда: Minsk -> Seoul -> Ottawa
Re: Кто знает правильные алгоритмы?
Вводим параметр товара "отношение качество-цена" (Goodie.value:=Goodie.quality/Goodie.price). Сортируем все товары по убыванию параметра value и отбираем сверху, пока денег хватит.Старина Зотин писал(а):Для задачи оптимизации покупок.
Ну, например, есть односвязный список товаров:
struct Goodie
{
float price;
float quality;
Goodie* next;
};
И нужно написать функцию, которая в пределах бюджета соберет максимальный quality. Ну, скажем:
Goodie* CreateBusket( Goodie* list, float budget );
Возвращает, разумеется, односвязный список. Исходный список можно (да, в общем-то, и нужно) разрушать после прохождения.
Время исполнения очень критично, но к счастью, списки довольно маленькие - порядка десятков.
Наверняка ведь напридумывано уже до фига алгоритмов, швырните в меня ключевыми словами. Куда копать?
.
- aissp
- Маньяк
- Сообщения: 2710
- Зарегистрирован: 07 ноя 2005, 09:51