Название: Нужен алгоритм поиска оптимального набор Отправлено: neosapient от Сентябрь 10, 2009, 12:47 Здравствуйте.
Мне нужен алгоритм, который оптимально быстро найдет слагаемые для получению нужной суммы, либо определит, что данную сумму нельзя получить. Есть массив целых положительных и отрицательных чисел. Нуля быть не может. Сами числа могут повторяться... Например, +1,+1,+1,+7,-4,1000,-996, -3. Найти сочетание слагаемых, чтобы в сумме получить 3. Варианты решения: * 1+1+1 = 3 * 7-4 = 3 * 1000 + 1 +1 -3 -996 = 3 * и т.д. 1) Минимальное условие задачи - найти ХОТЯ БЫ ОДНО сочетание слагаемых, чтобы получить нужную сумму. 2) Оптимально будет, если будут найден вариант(ы) с минимальным числом слагаемых. ============================================================== Сейчас пошел в упор - делаю поиск в глубину, с полным перебором вариантов. Но этот подход плох тем хотя бы по тому, что решения может не быть, а я об этом узнаю, только перебрав все сочетания. Число вариантов возможных комбинаций слагаемых можно рассчитать по формуле (2^n)-1 Таким образом, * для 1 слагаемого - только 1 сочетание * для 2 слагаемых - 3 сочетания * для 3 слагаемых - 7 сочетаний * для 4 слагаемых - 15 сочетаний * для 5 слагаемых - 31 сочетание ......... * для 26 слагаемых - 67108863 сочетания Пример того какие сочетания могут быть. Допустим у меня массив слагаемых из пяти элементов: a, b, c, d, e. Тогда я составляю следующие варианты. a, b, c, d, e, ab, ac, ad, ae, bc, bd, be, cd, ce, de abc, abd, abe, acd, ace, ade, bcd, bce, bde, cde abcd, abce, abde, acde, bcde abcde Итого для пяти слагаемых 31 вариант суммы. Если для 26 элементов, программа слишком долго рассчитывает, то как быть, когда у меня будет 100 элементов? Подскажите оптимальный алгоритм Название: Re: Нужен алгоритм поиска оптимального набора слагаемый (по дереву) Отправлено: Igors от Сентябрь 10, 2009, 13:37 Добрый день
Я помню эту задачу в интерпретации "есть N монеток" :) Да, перебор, но с "коротким выходом". 1) Добавляете константу ко всем числам и к нужной сумме - делаете все положительным 2) Сортируете числа по возрастанию 3) Перебираете варианты до тех пор пока текущая сумма не превысит заданную. "Вариант" получаете как комбинацию битов какого-то "большого числа". Пример Код: typedef unsigned long long ulong; Вычисления GetMinMask и GetMaxMask очевидны Название: Re: Нужен алгоритм поиска оптимального набора слагаемый (по дереву) Отправлено: spectre71 от Сентябрь 10, 2009, 14:20 1) Добавляете константу ко всем числам и к нужной сумме - делаете все положительным Это не верно, поскольку ты не знаешь кол-во элементов в результатирующей суммеэлементы -2, 3, 5 сумма 3 3=3 -2+5=3 элементы -2+2, 3+2, 5+2 сумма 3+2(+2)? Название: Re: Нужен алгоритм поиска оптимального набора слагаемый (по дереву) Отправлено: Igors от Сентябрь 10, 2009, 14:34 элементы -2+2, 3+2, 5+2 Так ведь к сумме тоже добавили 2 и она теперь 5 :)сумма 3+2(+2)? Вообще этот шаг (сделать все положительным) необязателен. Просто лично мне было бы удобнее считать что все > 0 (интуитивнее) Название: Re: Нужен алгоритм поиска оптимального набора слагаемый (по дереву) Отправлено: spectre71 от Сентябрь 10, 2009, 14:46 Так ведь к сумме тоже добавили 2 и она теперь 5 :) Будь внимательнейВообще этот шаг (сделать все положительным) необязателен. Просто лично мне было бы удобнее считать что все > 0 (интуитивнее) элементы -2+2, 3+2, 5+2 == 0, 5, 7 сумма 3+2 = 5 было 2 варианта - (3) и (-2+5) == 5, стал один (5)==5 Другой пример: элементы -2, 1, 3, 5 сумма 4 ====== элементы -2+2, 1+2, 3+2, 5+2 == 0, 3, 5, 7 сумма 4+2 = 6 Вообще ничего не получишь, хотя было 2 варианта Название: Re: Нужен алгоритм поиска оптимального набор Отправлено: Igors от Сентябрь 10, 2009, 14:52 Вы правы, добавление некорректно :)
Название: Re: Нужен алгоритм поиска оптимального набор Отправлено: ufna от Сентябрь 10, 2009, 16:26 Просто можно каждый раз, когда сверяемся равно ли это нужной сумме, прибавлять к изначальной сумме сию разницу, помноженную на количество текущее элементов в сумме ))
Название: Re: Нужен алгоритм поиска оптимального набор Отправлено: spectre71 от Сентябрь 10, 2009, 17:09 Вобще-то экспоненциальный алгоритм это очень плохо.
Данная задача весьма нетривиальная. Надо смотреть в сторону динамического программирования. А лучше поискать в инете готовые алгоритмы решения данной задачи. Название: Re: Нужен алгоритм поиска оптимального набор Отправлено: Igors от Сентябрь 10, 2009, 17:39 Вобще-то экспоненциальный алгоритм это очень плохо. По-моему если задача "комбинаторная" - то и решать ее надо "комбинаторно" (т.е. перебирая варианты), аккуратно сделав все отсечки/оптимизации. Ну и как всегда - работать с самой задачей (постановкой). Например, такие числаДанная задача весьма нетривиальная. Надо смотреть в сторону динамического программирования. А лучше поискать в инете готовые алгоритмы решения данной задачи. 1, 1, 1. .........................1 (очень много единиц) Да, выходное число всех возможных вариантов может быть огромным. Но ведь никто не обещал что "1" взаимозаменяема с другой "1" - это и должны быть разные варианты. Давайте считать это одним - и надо делать немного по-другому Название: Re: Нужен алгоритм поиска оптимального набор Отправлено: spectre71 от Сентябрь 10, 2009, 17:46 Вот ссылочка
http://ru.wikipedia.org/wiki/Задача_о_ранце (http://ru.wikipedia.org/wiki/Задача_о_ранце) Название: Re: Нужен алгоритм поиска оптимального набор Отправлено: spectre71 от Сентябрь 10, 2009, 17:53 Вот еще ссылки(Задача о суммах подмножеств)
http://rain.ifmo.ru/cat/view.php/theory/unsorted/approx-2004 (http://rain.ifmo.ru/cat/view.php/theory/unsorted/approx-2004) http://irodov.nm.ru/cgi-bin/ikonboard/topic.cgi?forum=3&topic=138 (http://irodov.nm.ru/cgi-bin/ikonboard/topic.cgi?forum=3&topic=138) Название: Re: Нужен алгоритм поиска оптимального набор Отправлено: Igors от Сентябрь 10, 2009, 18:12 Вот ссылочка Spectre, но ведь человек о (зас)ранце не спрашивал :) И если он на этот форум подписался - то и погуглить он сам сможет. Ссылка хороша в случае "точного попадания" а иначе..http://ru.wikipedia.org/wiki/Задача_о_ранце (http://ru.wikipedia.org/wiki/Задача_о_ранце) Название: Re: Нужен алгоритм поиска оптимального набор Отправлено: spectre71 от Сентябрь 10, 2009, 18:23 Spectre, но ведь человек о (зас)ранце не спрашивал :) И если он на этот форум подписался - то и погуглить он сам сможет. Ссылка хороша в случае "точного попадания" а иначе.. Не понял смысла твоего ответа, к чему ты это написал? :)Это разновидность задачи о ранце, первое что нашел, то и дал. Человек должен понять что за задачу он решает. Наиболее близка(а скорее всего именно она либо сводится кней) "Псевдополиномиальные алгоритмы/Задача о суммах подмножеств" http://rain.ifmo.ru/cat/view.php/theory/unsorted/approx-2004 (http://rain.ifmo.ru/cat/view.php/theory/unsorted/approx-2004) Название: Re: Нужен алгоритм поиска оптимального набора слагаемый (по дереву) Отправлено: Igors от Сентябрь 11, 2009, 13:48 3) Перебираете варианты до тех пор пока текущая сумма не превысит заданную. "Вариант" получаете как комбинацию битов какого-то "большого числа". Увы, это неправильно. ПримерЧисла: 7, 7, 7, 7, 10 Нужная сумма: 17 Первые три семерки дают 21 т.е. "сумма превысила" и ответ "вариантов нет". Однако он есть (7 + 10) Я подумаю как правильно :) Название: Re: Нужен алгоритм поиска оптимального набор Отправлено: Igors от Сентябрь 12, 2009, 10:09 http://www.2shared.com/file/7739585/779ab827/Sumcpp.html
Получается довольно просто, хотя, конечно "глухой рекурс" :) |