Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Алгоритмы > Оптимизация, получение суммы используя |
Автор: Stolzen 10.8.2012, 11:19 |
Всем доброго времени суток! Задача следующая: Есть множество P каждый элемент которого имеет некоторую цену pi; и есть заданная цена W. Необходимо выбрать элементы из P так, чтобы количество элементов было минимальным, а сумма цен элементов была больше или равна W. Если вариантов несколько, выбрать тот, который ближе к W. Например, элементы [100, 20, 30, 50], цена 100, нужно выбрать [100] элементы [100, 30, 20, 50, 10], цена 80, нужно выбрать [50, 30] элементы [100, 30, 20, 50, 10], цена 85, нужно выбрать [50, 30, 10] Теорию оптимизации совсем не помню, поэтому буду признателен любой наводке. Добавлено через 2 минуты и 18 секунд Да, кстати, числа могут быть довольно большими (в пределах long) |
Автор: Stolzen 10.8.2012, 12:39 |
Вот что придумалось поиск (P, W, результат)
Чем-то напомнинает рюкзак. Что скажете? |
Автор: Stolzen 10.8.2012, 15:03 |
Да, не совсем верно сформулировал, близость к сумме конечно приоритетнее, чем количество элементов. |
Автор: korian 12.8.2012, 14:33 | ||||
Думаю так должно работать быстрее:
|
Автор: Stolzen 13.8.2012, 10:28 |
korian, спасибо. А можно на словах описать, что тут происходит? У меня http://paste.ubuntu.com/1144429/ реализация для алгоритма выше получилась. |
Автор: Akina 13.8.2012, 12:30 |
Всё равно не до конца понятно. Как они соотносятся? если нужна сумма 98, она не набирается, а набирается 99 из 11 элементов или 100 одним элементом - какой вариант выбрать? Где математическое определение критерия оптимальности? |
Автор: Stolzen 13.8.2012, 13:14 | ||
У меня нет такого, извините.
Склоняюсь к 99. Меня, по правде, больше интересовали подходы к решению подобных задач. Спасибо. |
Автор: korian 13.8.2012, 17:11 | ||
Я добавил комментарии. Мне тяжело читать функциональные языки %) Можете проверить ваш алгоритм на таких данных (я их использовал для своих тестов и это вроде как основные моменты, которые надо проверить):
Если все это у вас работает, то единственный плюс в моем алгоритме - из-за того, что элементы отсортированы, нужно делать меньший перебор. |
Автор: Akina 13.8.2012, 20:59 | ||
Ну здесь Вы собсно имеете в чистом виде задачу об одномерном раскрое. И решаете её соответственно. Либо какой-то точный переборный метод, скажем метод ветвей и границ, либо (если устраивает решение, близкое к оптимуму, а необязательно оптимум) генетика. А вот это очень плохо. Вы обязаны иметь... ммм... ну, скажем, функцию, в которую Вы передаёте два решения, а она возвращает ответ, какое из них лучше. Иначе решать задачу не получится. Ощущения класса "склоняюсь к" не программируются. |
Автор: Stolzen 14.8.2012, 11:28 | ||||||
Спасибо, именно это мне больше всего хотелось услышать. Почитаю про одномерный раскрой и метод ветвей и границ.
Дело в том, что мы пока в команде сами не знаем, какие именно критерии выбора решения лучше использовать, поэтому перебираем разные варианты и смотрим, какой из них лучше ведет себя для тестового набора данных. Ну и в данном случае ведь выбор ответа - это дело одной-двух проверок, поэтому можно сначала проверить ощущения типа "склоняюсь к", а потом другие ![]()
Спасибо, нашел пару опечаток и неточностей в коде. (http://paste.ubuntu.com/1146383/.) Да, теперь немного понятнее. Получается, примерно такая же идея, как в http://forum.vingrad.ru/index.php?showtopic=355199&view=findpost&p=2510655, только алгоритм реализован эффективнее? У этого алгоритма есть какое-нибудь название? |
Автор: Akina 14.8.2012, 12:05 |
Заодно почитай и задачу о рюкзаке (вариация - об одномерном рюкзаке). Она отличается от раскроя тем, что в ней есть относительные веса/стоимости, о чём обычно забывают, благополучно путая меж собой эти задачи. |
Автор: korian 14.8.2012, 17:03 | ||
В общем да. Эффективнее тем, что я на каждом шаге уменьшаю размер множества, если это возможно. Т.е. рассматриваю подмножество элементов, в котором только элементы, которые меньше W, плюс один наименьший элемент, который больше W. Ну и учитывая, что множество отсортированное, это стоит мне всего log(n) времени. Плюс если я правильно понимаю, моему алгоритму надо меньше времени для определения, что сумма множества меньше W. Без понятия, особо этим не интересовался. Написан за субботу от нечего делать. |
Автор: Stolzen 14.8.2012, 17:14 |
korian, Akina, спасибо вам за отклик, на пока тему можно считать закрытой. |