задачка... на алгоритмизацию

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Cyrax
Cyberninja
Cyberninja
Аватара пользователя
 
Сообщения: 891
Зарегистрирован: 25.04.2002 (Чт) 21:20
Откуда: Magnitogorsk, Russia

задачка... на алгоритмизацию

Сообщение Cyrax » 04.12.2003 (Чт) 13:03

доброго всем времени суток!

уважаемые, подскажите алгоритм решения такой задачи:
имеется ряд числовых значений и какая-то определенная сумма.
например:
ряд чисел
    5.02
    46
    10
    102.14
    70
    38

сумма:
182.14
требуется: из приведенного ряда чисел подобрать такие, что бы в результате получилас указанная сумма (или, хотя бы, сумма наиболее приближенная к указанной).

у кого какие мысли по этому поводу?
Ты это ему расскажи. Я уже пять болтов отвинтил, и конца не видно... (озадаченно) А это в какую сторону тянуть? Ну-ка... Ага, этот был лишний, этот вообще не отсюда, и этот... Точно, два болта.

Welcome to IRC

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4168
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 04.12.2003 (Чт) 15:15

Число вариантов сочетаний:

из шести по ноль - 1 (это тоже вариант, если сумма=0)
из шести по одному - 6
из шести по два - 15
...
из шести по пять -6
из шести по шесть - 1

бином Ньютона. По-моему перебрать все варианты и выбрать ближайший не проблема.

vrodo
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 09.10.2003 (Чт) 18:45
Откуда: Дубна МО, Москва

Сообщение vrodo » 04.12.2003 (Чт) 21:54

Думаю что можно проще
D = 0 ' delta
X = 0 ' наше число
Y = 234 ' Ваша сумма
A(1 to 6)=3,4,50,54,100,30
выстраиваем их попорядку
A(1 to 6)=100,54,50,30,4,3
i = 1
Metka:
Берем самое большое если оно не больше A(i) <= (Y - X) И i <= 6
x = x + A(i)
Иначе
i=i+1
Goto Metka:

Чесно печатал совершенно Случайные Числа
Начиная от Y и заканчивая массивом А
Чтобы понять свои ошибки их достаточно написать (c)
Интернет большой, ему видней
С наилучшими Пожеланиями и Всех Благ :D

_NeoN_
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 178
Зарегистрирован: 14.08.2003 (Чт) 9:48
Откуда: Новосибирск

Сообщение _NeoN_ » 06.12.2003 (Сб) 20:38

если не знаешь как делать то делай перебором.. запоминай все суммы и потом самую приближенную выбирай...

Cyrax
Cyberninja
Cyberninja
Аватара пользователя
 
Сообщения: 891
Зарегистрирован: 25.04.2002 (Чт) 21:20
Откуда: Magnitogorsk, Russia

Сообщение Cyrax » 07.12.2003 (Вс) 17:15

чего-то меня клинит... по черному... будь она не ладна эта задачка
пока получается, так сказать, промежуточный результат...
прохожусь в цикле по всему списку от самого большого вниз и считаю сумму...
после этого надо бы пройтись еще раз, уже по двум спискам (исходному и полученному после первого цикла), что бы подогнать результат еще точнее... но вот как это реализовать? :cry: чего-то никак не придумывается...
народ глянте проект, может чего подскажете...
Ты это ему расскажи. Я уже пять болтов отвинтил, и конца не видно... (озадаченно) А это в какую сторону тянуть? Ну-ка... Ага, этот был лишний, этот вообще не отсюда, и этот... Точно, два болта.

Welcome to IRC

SeRRg
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 343
Зарегистрирован: 25.11.2003 (Вт) 20:14
Откуда: Тюмень!

Сообщение SeRRg » 08.12.2003 (Пн) 13:19

P.S. Все сказанное ниже является моим предположением, и я могу ошибаться.
Тут дело совсем просто. Ты только все усложняешь: :lol:
Твоя прога находит НАИБОЛЬШЕЕ число из СУММЫ, меньшей искомой.
А надо находить еще и НАИМЕНЬШЕЕ из БОЛЬШИХ.
Тогда у тебя будет наиболее близкое.
Я вот тут дописал кое-чего. У меня работает.
Посмотри и проверь.

P.S. Я могу ошибаться.
Вложения
OtBet.rar
(2.76 Кб) Скачиваний: 40
VB - это звучит!

vrodo
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 09.10.2003 (Чт) 18:45
Откуда: Дубна МО, Москва

Сообщение vrodo » 08.12.2003 (Пн) 16:12

Я нашел в своем предложении ошибку
попробуйте этот алгоритм для порядка если число которое надо найти = 64
60
30
34
3
получится 63
хотя можно получить и 64

так что надо наверно
надо попробовать сделать еще циклы в котором будет учитыватся весь массив без последного верхнего числа и только в том случае если сумма оставшихся чисел >= 64

и тестировать на соответствие
если old_summ < new_summ <=trebuemaja_summa то old_summ =new_summ
Чтобы понять свои ошибки их достаточно написать (c)
Интернет большой, ему видней
С наилучшими Пожеланиями и Всех Благ :D

SeRRg
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 343
Зарегистрирован: 25.11.2003 (Вт) 20:14
Откуда: Тюмень!

Сообщение SeRRg » 08.12.2003 (Пн) 16:29

Вообще-то ты прав...
Но тогда, следуя логике нужно:
1.Применить описанную процедуру к массиву.
2.Запомнить лучшее.
3.Уменьшить массив на одно число. (ведь и среди других может быть такое же)
4.Если чисел больше двух, то перейти к (1).
5.Выбрать из получившегося оптимальный вариант.
Я думаю Так. :)
Поправьте меня, если не так. :)
VB - это звучит!

vrodo
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 109
Зарегистрирован: 09.10.2003 (Чт) 18:45
Откуда: Дубна МО, Москва

Сообщение vrodo » 08.12.2003 (Пн) 16:42

угу
тоесть найти найти значение где abs(trebuemaja_summ-new_summ) будет наименьшим
Чтобы понять свои ошибки их достаточно написать (c)
Интернет большой, ему видней
С наилучшими Пожеланиями и Всех Благ :D

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4168
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 08.12.2003 (Пн) 17:24

Не пойму, в чем проблемы. Пусть дано N чисел, тогда число вариантов - 2^N. Номеру K соответствует сумма тех элементов массива, соответствующий бит которого в K установлен. Пробегаем от 0 до (2^N)-1, находим сумму и сравниваем с необходимой. Вот код формы, рабочий. По клику мышкой - рассчет:

Option Explicit
Const Size = 6
Dim m(Size - 1) As Single, Summ As Single

Private Sub Form_Click()
Dim n As Long
Dim Num As Long
Dim tmpRes As Single
Dim tmpSumm As Single

Me.Cls
Randomize Timer
'Заполняем массив
For n = 0 To Size - 1
m(n) = (Rnd - 0.5) * 100
Next n
Summ = (Rnd - 0.5) * 100

tmpSumm = 0
Num = 0
tmpRes = Abs(Summ - tmpSumm)
For n = 0 To (2 ^ Size) - 1
tmpSumm = TestSumm(n)
If Abs(Summ - tmpSumm) < tmpRes Then
tmpRes = Abs(Summ - tmpSumm)
Num = n
End If
Next n

For n = 0 To Size - 1
Me.Print n, m(n)
Next n
Me.Print "Дана сумма:"; Summ
Me.Print

tmpSumm = 0
For n = 0 To Size - 1
If ((2 ^ n) And Num) Then Me.Print n, m(n)
Next n
Me.Print "Итог сумма:", TestSumm(Num)

End Sub

Private Function TestSumm(NN As Long) As Single
Dim n As Long
TestSumm = 0
For n = 0 To Size - 1
If ((2 ^ n) And NN) Then TestSumm = TestSumm + m(n)
Next n
End Function

Cyrax
Cyberninja
Cyberninja
Аватара пользователя
 
Сообщения: 891
Зарегистрирован: 25.04.2002 (Чт) 21:20
Откуда: Magnitogorsk, Russia

Сообщение Cyrax » 09.12.2003 (Вт) 12:07

2 Mikle:
башое пасибо... но, объясни, пжалста, что это такое? в смысле, как называется этот алгоритм...
и где можно посмотреть подобные задачки (с возможными их решенями).
я думаю это не только мне будет полезно, но и многим посетителям форума...
Ты это ему расскажи. Я уже пять болтов отвинтил, и конца не видно... (озадаченно) А это в какую сторону тянуть? Ну-ка... Ага, этот был лишний, этот вообще не отсюда, и этот... Точно, два болта.

Welcome to IRC

corgi
ToyMan
ToyMan
 
Сообщения: 1367
Зарегистрирован: 01.10.2002 (Вт) 9:59
Откуда: Россия, Москва

Сообщение corgi » 09.12.2003 (Вт) 12:55

я бы сказал так это алгоритм "первое что пришло в голову"
2Mikle это не наезд а просто выразился я так, может чуток грубо, но все же :wink: :D
2Cyrax
если хочешь глянь тута, больше ничего особого в сети не знаю
Ничто так не ограничивает полёт мысли программиста, как компилятор

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4168
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 09.12.2003 (Вт) 15:33

Согласен - первое, что пришло.
Где есть еще решения таких задач?.. не знаю, я их сам решаю.
А алгоритм можно оптимизировать, например заменить степень сложением (равным количеством!!!), но я не сделал этого, чтобы не потерять понятность.

Cyrax
Cyberninja
Cyberninja
Аватара пользователя
 
Сообщения: 891
Зарегистрирован: 25.04.2002 (Чт) 21:20
Откуда: Magnitogorsk, Russia

Сообщение Cyrax » 10.12.2003 (Ср) 5:54

2 corgi:
спасибо... ну я полез сливать...
а то все WinAPI, да WinAPI... а такие элементарные (почти) вещи ставят в тубик... надо бы это исправить :wink:
Ты это ему расскажи. Я уже пять болтов отвинтил, и конца не видно... (озадаченно) А это в какую сторону тянуть? Ну-ка... Ага, этот был лишний, этот вообще не отсюда, и этот... Точно, два болта.

Welcome to IRC

v-adix
Постоялец
Постоялец
 
Сообщения: 490
Зарегистрирован: 14.11.2002 (Чт) 15:11

Сообщение v-adix » 10.12.2003 (Ср) 17:24

мне кажется, что если чисел немного, то надо просто сделать перебор. цикл примерно такой:

for i = 1 to сколькочисел
for k = 1 to сколькочисел

запомнить все суммы в массив а потом посмотреть самый близкий ответ

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4168
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 10.12.2003 (Ср) 17:32

v-adix
Так ты получишь только суммы из ДВУХ чисел, причем среди них недопустимые - когда i=k. Да и зачем массив, если результаты можно сравнивать СРАЗУ.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: SemrushBot, Yandex-бот и гости: 19

    TopList