Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Нужен алгоритм поиска оптимального набора слагаемы 
:(
    Опции темы
neosapient
Дата 10.9.2009, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Здравствуйте.
Мне нужен алгоритм, который оптимально быстро найдет слагаемые для получению нужной суммы, либо определит, что данную сумму нельзя получить.

Есть массив целых положительных и отрицательных чисел. Нуля быть не может. Сами числа могут повторяться...
Например, +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 элементов?
Подскажите оптимальный алгоритм 

Это сообщение отредактировал(а) neosapient - 10.9.2009, 13:34
PM MAIL   Вверх
Akina
Дата 10.9.2009, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



Раздели поиск "пополам". Отдельно положительные, отдельно отрицательные.
Применительно к исходному посту.
Отрицательные составляют разные суммы: -3, -4, -7, -996, -999, -1000, -1003.
Соответственно искать надо положительные, образующие одну из сумм: 3, 6, 7, 19, 999, 1992, 1003, 1006.
Количество сумм для сочетания 8 элементов (если влоб) = 255. Мы же на первом этапе обработали 7 сочетаний, на втором обработаем ещё 31 сочетание - всего 38. Чем больше набор чисел и чем ближе распределение положительных/отрицательных к 50:50, тем значительнее выигрыш. Правда, тем больше потребуется памяти для массива возможных сумм.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
neosapient
Дата 10.9.2009, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Не понял Вас, есть массив слагаемых: +1,+1,+1,+7,-4,1000,-996, -3.
Найти сочетание слагаемых, чтобы в сумме получить 3.
Варианты решения:
* 1+1+1 = 3
* 7-4 = 3
* 1000 + 1 +1 -3 -996 = 3
* и т.д.

Вы предлагаете поиск в ширину ? Но он не сможет мне сказать быстро сказать, что нет подходящих комбинаций...


Это сообщение отредактировал(а) neosapient - 10.9.2009, 13:42
PM MAIL   Вверх
Akina
Дата 10.9.2009, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



Задача переборная, куда деваться... максимум что можно сделать - это уменьшить количество переборов.
Ещё можно уменьшить это количество, если после деления набора на положительные и отрицательные отсортировать набор положительных элементов и набор искомых сумм - появятся дополнительные отсечения. Скажем, при обработке сумм 3, 6, 7, 19, 999 элемент 1000 можно из рассмотрения смело исключить.

Это сообщение отредактировал(а) Akina - 10.9.2009, 13:49


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
maxdiver
Дата 11.9.2009, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 16
Всего: 18



Это задача о рюкзаке, правда, ещё и с отрицательными весами - не совсем стандарт. Для стандартной задачи о рюкзаке есть некий эффективный алгоритм, как раз на только что прошедших олимпиадных сборах в Петрозаводске была задача на это. Чуть позже я найду разбор той задачи, и отпишусь здесь.
PM MAIL WWW ICQ   Вверх
maxdiver
Дата 14.9.2009, 00:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 16
Всего: 18



Мда, то решение (динамикой) слишком специфичное. Как минимум, наличие отрицательных весов всё портит для него. Так что просто попробуйте поискать алгоритмы по теме "задача о рюкзаке". Из несложных алгоритмов видится только обход в ширину, но судя по всему, он вас не устраивает...
PM MAIL WWW ICQ   Вверх
aram90
Дата 14.9.2009, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Bug hunter



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 1.12.2008
Где: Yerevan, Armenia

Репутация: 1
Всего: 3



Отрицательные весы не имеют значиние, важтно диапазон значений. Если числа ограничены, то можно эффективно решить задачу. Алгоритм будет O(n*d), n-количество чисел, d - разность максимально и минимально возможной суммы.
PM MAIL WWW ICQ   Вверх
maxdiver
Дата 14.9.2009, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 16
Всего: 18



За n*d работает и решение обходом в ширину, разве нет?
PM MAIL WWW ICQ   Вверх
aram90
Дата 15.9.2009, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Bug hunter



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 1.12.2008
Где: Yerevan, Armenia

Репутация: 1
Всего: 3



Что значит "обход в ширину", где здесь у нас граф и вершины?
PM MAIL WWW ICQ   Вверх
maxdiver
Дата 15.9.2009, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 16
Всего: 18



Вершины - это пары (i,sum) (i=0..n, sum=min_possible_sum..max_possible_sum), что означает, что мы просмотрели первые i слагаемых и набрали сумму sum.
Рёбра: (i,sum) -> (i+1,sum), (i,sum) -> (i+1,sum+a[i]).
Запускаем обход в ширину из состояния (0,0), а потом просто смотрим, какие вершины вида (n,sum) были достигнуты - все они и есть всевозможные суммы, которые можно было набрать. Восстановить сами слагаемые для нужной нам суммы не составит труда.
Итого асимптотика O(n*d), т.к. столько вершин и рёбер в графе. Можно даже за ту же асимптотику находить ответы с минимальным числом слагаемых, для этого просто в графе надо ввести веса (на рёбра первого типа поставить вес 0, а второго типа - вес 1).
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0729 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.