|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Подскажите как переделать это?
Исходник работает так:
-В поле Edit1 вводится произвольное целое число; -В поле Edit2 вводятся произвольное множество целых чисел через запятую; -При нажатии на кнопку Button1 в поле Memo1 выводится сумма целых чисел из ряда Edit2 максимально приблеженных к числу введеного в поле Edit2. Задача Необходимо переделать под поиск оптимальной суммы вещественных чисел с наименьшей погрешностью, хотябы до 4 знака после запятой? Помогите решить эту задачу. Заранее спасибо. Код:
procedure TForm1.Button1Click(Sender: TObject); VAR I, J : Integer; N, V : Cardinal; S, Sm : AnsiString; MaxS : Cardinal; Variants: TStringList; Current : Cardinal; Original : Integer; Mas : ARRAY OF Integer; begin Memo1.Clear; Memo1.Lines.Add('Собираем число: '+Edit1.Text); S:= Edit2.Text; N:= 1; FOR I:= 1 TO Length(S) DO IF S[i] = ',' THEN Inc(N); SetLength(Mas, N); N:= 0; Memo1.Lines.Add('Из чисел: '+Edit1.Text); REPEAT I:= Pos(',', S); IF I = 0 THEN Mas[N]:= StrToInt(S) ELSE Begin Mas[N]:= StrToInt(Copy(S, 1, I-1)); S:= Copy(S, I+1,Length(S)); End; Memo1.Lines.Add(IntToStr(Mas[N])); Inc(N); UNTIL I = 0; FOR I:= 0 TO N-1 DO Begin V:= I; FOR J:= I+1 TO N-1 DO Begin IF Mas[J] < Mas[V] THEN V:= J; End; J:= Mas[i]; Mas[i]:= Mas[V]; Mas[V]:= J; End; Memo1.Lines.Add('------------'); Original:= StrToInt(Edit1.Text); FOR I:= 0 TO N-1 DO Begin IF Mas[i] > Original THEN Begin N:= I; break; End; Memo1.Lines.Add(IntToStr(Mas[i])); End; Mas:= Copy(Mas, 0, N); Memo1.Lines.Add('------------'); Current:= 0; MaxS:= (1 shl N)-1; Variants:= TStringList.Create; Variants.AddObject('0', TObject(0)); REPEAT Inc(Current); J:= 0; Sm:= ''; V:= 1; FOR I:= 0 TO N-1 DO Begin IF (Current and V) > 0 THEN Begin J:= J+Mas[i]; Sm:= Sm+IntToStr(Mas[i])+' + '; End; V:= V shl 1; End; Sm[Length(Sm)-1]:= '='; Sm:= Sm+IntToStr(J); IF Integer(Variants.Objects[0]) = J THEN Variants.AddObject(Sm, TObject(J)) ELSE IF (J > Integer(Variants.Objects[0])) AND (J <= Original) THEN Begin Variants.Clear; Variants.AddObject(Sm, TObject(J)) End; UNTIL Current = MaxS; Memo1.Lines.AddStrings(Variants); end; Последний раз редактировалось lmikle, 04.11.2011 в 02:25. |
#2
|
||||
|
||||
Ага, обязательно помогу, как только пойму, что такое максимально приближенные (100<->1000 или нет?) и приведённый код будет упрятан в тэг [code].
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#3
|
|||
|
|||
Вот алгоритм: Задача о ранце
Пункт 4 "Единичный выбор предметов". |
#4
|
|||
|
|||
Цитата:
позиций (эквивалентно умножению на 2^N, тока быстрее работает). |
#5
|
|||
|
|||
Цитата:
Число 11 из чисел 2, 4, 6, например, не соберешь... не говоря про первый знак после запятой. Тут как фишка ляжет с числами А теперь по-существу. 1. Есть число Х0 и числа х1, х2, х3... 2. Для каждого числа х1,х2,х3... рассчитываем число, назовем его, а1,а2,а3,... Код:
var a : array of integer; x : array of real; X0 : real; i : integer; begin ... for i := 1 to length(x) do a[i] := X0 div x[i]; ... 4. Бурно радуемся по поводу полученного результата П.С. Пункт 3 конечно можно оптимизировать, но в 2 ночи не хочу насоветовать чего-нить не того Последний раз редактировалось U.B.M., 07.11.2011 в 01:54. |
#6
|
|||
|
|||
Цитата:
Так целое или вещественное? 3,14 - вещественное, но не целое. Откуда вопрос про знак после запятой если числа целые? Неплохо было бы уточнить условие. |
#7
|
|||
|
|||
Код:
unit Unit1; interface uses Windows, SysUtils, Classes, Controls, Forms, StdCtrls, StrUtils, Math; type TForm1 = class(TForm) Edit1: TEdit; Memo1: TMemo; Button1: TButton; Edit2: TEdit; procedure Button1Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} //перевод из 10-ной в 2-ную - понадобится в дальнейшем function dec_to_bin(dec_num : integer) : string; var s : string; begin s := ''; while dec_num >= 1 do begin s := IntToStr(dec_num mod 2) + s; dec_num := dec_num div 2; end; dec_to_bin := s; end; procedure TForm1.Button1Click(Sender: TObject); var dec_view, i, j : integer; delta, original, sum, min_sum : real; Mas : array of real; str : string; begin decimalseparator := '.'; //разделитель после целой части, например, 3.14 (не запятая как обычно) Memo1.Clear; Memo1.Text := Memo1.Text + AnsiReplaceStr(Edit2.Text, ',', #13#10); SetLength(Mas, Memo1.Lines.Count); for i := 0 to Memo1.Lines.Count-1 do Mas[i]:= StrToFloat(Memo1.Lines.Strings[i]); Memo1.Text := 'Собираем число '+ Edit1.Text + #13#10 + 'Из чисел:' + #13#10 + Memo1.Text + #13#10 + '--------------------------------' + #13#10; original := StrToFloat(Edit1.Text); dec_view := trunc(Power(2,Length(Mas))); // кол-во комбинаций при сложении delta := original; for i := 1 to dec_view - 1 do begin sum := 0; for j := 0 to length(dec_to_bin(i))-1 do sum := sum + Mas[j]*StrToFloat(copy(dec_to_bin(i),j+1,1)); if abs(sum-original) < delta then begin delta := abs(sum-original); min_sum := sum; str := dec_to_bin(i); end; if sum-original = 0 then break; end; Memo1.Lines.Add('Cкладывались числа:'); for i := 0 to length(str)-1 do if str[i+1] <> '0' then Memo1.Lines.Add(FloatToStr(Mas[i])); Memo1.Lines.Add('сумма = ' + FloatToStr(min_sum)); Memo1.Lines.Add('разность = ' + FloatToStr(delta)); end; end. Полностью рабочий код, кроме того что разность пишет, например, не 1.2, а 1.999999999999. Надо маленько подрехтовать, но тут сам уже разберешься. Последний раз редактировалось U.B.M., 27.11.2011 в 00:50. |
#8
|
|||
|
|||
1
Почему при поиске оптимальной суммы из 30 значений программма зависает?
|
#9
|
|||
|
|||
1
Для скорости работы сделать так чтобы выводило первых 10 результатов потом при втором нажатии следующие 10 результатов и так до конца?
Последний раз редактировалось LelikBolik, 23.04.2012 в 22:17. |
#10
|
|||
|
|||
Цитата:
Зависает это долго (скажем, больше 30 секунд/минуты) считает или вылетает с ошибкой? |
#11
|
|||
|
|||
1
Зависает и больше не отвечает программа. Может все дело в вместимости поля Memo? Т.к когда я убрал Memo1.Lines.Add........ то программа стала работать быстрее, но до 30 чисел заданых в поле Edit. Есле я вношу в поле Edit больше 30 чисел то программа неотвечает и ошибка не выскакивает.
Последний раз редактировалось LelikBolik, 24.04.2012 в 21:24. Причина: 1 |
#12
|
||||
|
||||
"Прошагать" не пробовал?
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#13
|
|||
|
|||
Цитата:
|
#14
|
|||
|
|||
Цитата:
123 число, составляем из 1,2,...,30 - секунд 10 заняло. С другими как пойдет. Кстати, ты уверен что в сумме все числа-слагаемые могут дать необходимое число? |
#15
|
|||
|
|||
Цитата:
вообще-то этот цикл указывает какие числа использовались для суммы - так что 30 мемоаддов вроде сильно влиять на время работы не должны |