|
Задача о ранце без стоимости | ☑ | ||
---|---|---|---|---|
0
zhig75
05.02.16
✎
12:21
|
Привет. Я сломался.
Есть некое множество чисел в таблице, из которых надо оптимально выбрать значения которые в сумме дадут <= необходимую сумму. Нужен алгоритм для восьмерки. Нашел вот это Нужен алгоритм набора нужной суммы, но что-то ничерта не могу понять поскольку для 7. |
|||
1
Михаил Козлов
05.02.16
✎
12:31
|
Жадным алгоритмом попробуйте: упорядочить по убыванию, добавлять очередное, если возможно.
|
|||
2
zhig75
05.02.16
✎
12:35
|
(1) А пример есть?
|
|||
3
mistеr
05.02.16
✎
12:41
|
Задача о ранце без стоимости подобна задаче о ранце со стоимостью, только... Без только, это она и есть.
|
|||
4
Михаил Козлов
05.02.16
✎
12:45
|
Какой еще пример нужен: там 5 строчек кода.
Если на тестовых примерах будет плохо подбирать, тогда нужно будет смотреть, как улучшить (литературы по ранцу полно. На форуме есть участник NZ или NS - не помню - который с ранцем плотно возился). Вы для начала озвучьте порядок количества чисел. |
|||
5
zhig75
05.02.16
✎
12:51
|
(4) К примеру 40 различных чисел, 123, 434, 5943, 334, 4322, 4343, 4445, 4303, итд, из них надо выбрать числа которые в сумме дадут <= 24500
|
|||
6
zhig75
05.02.16
✎
12:52
|
(4) Пока на ум приходит Цикл в Цикле для каждого значения.
|
|||
7
Михаил Козлов
05.02.16
✎
12:58
|
(6) Пусть числа хранятся в ТЗ.
ТЗ.Сортировать("Сумма УБЫВ"); решение = Новый Массив; подобрано = 0; ДЛЯ каждого стр ИЗ ТЗ Цикл Если подобрано+стр.Сумма<=нужнаяСумма Тогда подобрано = подобрано+стр.Сумма; решение.Добавить(стр); КонецЕсли; КонецЦикла; |
|||
8
ObjectRelation Model
05.02.16
✎
13:00
|
(7) необязательно будет лучший результат
|
|||
9
zhig75
05.02.16
✎
13:05
|
(7) Ну отберет этот цикл из первых чисел, результат не оптимален.
|
|||
10
Ma3eIIa
05.02.16
✎
13:12
|
(9) почему из первых ?
ты внимательно читал ? |
|||
11
Ma3eIIa
05.02.16
✎
13:16
|
Пусть задана пара (S, t), где S = {x1, x2, …, xn} представляет собой множество положительных целых чисел, а t — положительное целое число. Требуется отыскать среди подмножеств множества S, сумма которых не превосходит t, такое, у которого сумма ближе всего к t.
Пусть |S| = n. Обозначим (k, w) — задачу, в которой имеется k первых чисел из S и нужно набрать сумму w. Таким образом исходная задача — это задача (n, t). Для решения задачи построим таблицу T[n, t + 1], в клетку T[i, j] которой будем записывать оптимальное решение задачи (i, j). Первый столбец заполним нулями. Первую строку заполним сначала нулями, а начиная с клетки (1, x1) — числами x1. Клетку T[i, j] (i, j > 1) будем заполнять по правилу: Если j ? xi > 0, то y := T[i ? 1, j ? xi], иначе y := 0; T[i, j] := max(T [i ? 1, j], y + xi) |
|||
12
samozvanec
05.02.16
✎
13:16
|
(10) нужно косарь, числа 970, 960, 40, 20
|
|||
13
Ma3eIIa
05.02.16
✎
13:18
|
||||
14
Ma3eIIa
05.02.16
✎
13:21
|
ну или вот 1 в 1.
const N=3; //количество предметов Ves=8; //ограничение на вес рюкзака var //веса предметов в порядке возрастания, количество экземпляров не ограничено M: array[1..N] of integer; //стоимости предметов C: array[1..N] of integer; //T= максимальная ценность рюкзака данного веса //если вес набрать нельзя, T=0 T:array[0..Ves] of integer; //номер последнего слагаемого, вошедшего в рюкзак данного веса L: array[0..Ves] of byte; sum,i,j,v,k,Cmax:integer; begin M[1]:= 2; M[2]:= 4; M[3]:= 6; C[1]:= 2; C[2]:= 5; C[3]:= 6; //инициализация for j:= 0 to Ves do begin T[j]:= 0; L[j]:=0; end; for j := M[1] to Ves do for i := 1 to N do begin if (T[j]<C[i]) and (j=M[i]) then //набираем вес одним предметом begin T[j]:= C[i]; L[j]:=i; end //i-е слагаемое не превосходит набираемую сумму //и набор веса j - M[i] уже существует else if (j >= M[i])and (T[j - M[i]]>0) then begin //добавляем i-е слагаемое к решению //и запоминаем его номер if T[j]< T[j - M[i]]+ C[i] then begin T[j]:= T[j - M[i]]+C[i]; L[j]:= i; end end //i-е и все последующие слагаемые больше набираемой суммы else if (j < M[i]) then break; end; Cmax:=0; sum:=0; //ищем максимум стоимости for j:= Ves downto 1 do if T[j]> Cmax then begin Cmax:=T[j]; sum:=j; end; //восстанавливаем содержимое максимально ценного рюкзака v:=0; k:=0; while sum<>0 do begin i:= L[sum];//i-е слагаемое вошло в рюкзак writeln (M[i],' '); //уменьшили сумму sum := sum - M[i]; v:=v+M[i]; k:= k+C[i]; end; writeln('Cmax=', k,' ves=',v); readln; end. |
|||
15
Михаил Козлов
05.02.16
✎
13:25
|
(8) Кто бы спорил.
(11) Если не ошибаюсь (могу, в таком разе извините), это метод динамического программирования применительно к задаче о ранце. Как известно, может работать экспоненциально долго. Чтобы не разводить холивар: про ранец довольно много чего известно, вряд ли удастся изобрести что-то новое: проще найти. |
|||
16
Ma3eIIa
05.02.16
✎
13:34
|
(15) 100500 :). математический алгоритм 1.
Знаю что в битах обработках будет быстрее |
|||
17
Ma3eIIa
05.02.16
✎
13:36
|
||||
18
Ma3eIIa
05.02.16
✎
13:43
|
||||
19
samozvanec
05.02.16
✎
13:58
|
(18) харош уже. все хотели просто пофлеймить, а ты вариантов накидал аки профессор. ТС вообще сказал, что "алгоритм для 77 сложна, дайти на 8ку"
|
|||
20
Ma3eIIa
05.02.16
✎
14:10
|
(19) это было к (15) . вопрос по оптимизации и скорости получение результата :)
Да я себе заметки тут оставил :) |
|||
21
su_mai
05.02.16
✎
14:17
|
(8) Будет лучший вариант если исходное множество - матроид
|
|||
22
Михаил Козлов
05.02.16
✎
14:27
|
(21) К сожалению, ранец не матроид.
Матроиды вообще нынче редки :-) |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |