Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Jenicek 06. 06. 2013, 17:06:52
-
Dobrý den,
jedná se o školní práci, kvůli které mám windows s Delphi a pořeboval bych, aby v proceduře NejblizsiBody došlo na konci k převodu proměnné typu real na string a dostat to do MemoPole. Nějak na to nemůžu přijít. Zjistil sem že programování asi nebude moje silná stránka a prosím o pomoc.
procedure NejblizsiBody (Mat: TMatice; n: Integer; var MemoBox: TMemo; var Xi,Xj,Yi,Yj,Min_find: Real);
var
i,j: Integer;
Vzdal: real;
begin
Min_find:= maxint;
for i := 1 to n-1 do begin
for j := i+1 to n do begin
Vzdal:= sqrt((sqr(mat[1,i]-mat[1,j]))+(sqr(mat[2,i]-mat[2,j])));
if Vzdal < Min_find then begin
Min_find:= Vzdal;
Xi:=mat[1,i];
Xj:=mat[1,j];
Yi:=mat[2,i];
Yj:=mat[2,j];
end;
floatTostr(Nejblizsibody(vzdal));
MemoBox.Lines.Add ('Nejbližší body jsou:');
MemoBox.Lines.Add (vzdal)
end;
end;
end;
Celý program:
- zadání:
Náhodným způsobem vygenerujte n dvojic reálných čísel v rozsahu A až B. Tyto dvojice považujte za kartézské souřadnice bodů v rovině. Nalezněte dva body s nejbližší vzdáleností a souřadnice obou bodů vytiskněte. Všechny dvojice a nejbližší dvojici vytiskněte do memo pole a do souboru.
Vstup: n – počet bodů – dvojic souřadnic, dolní a horní mez
Výstup: Souřadnice dvou bodů, které leží nejblíže.
unit Vzdalenost_Bodu;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const MAX = 100;
type
Tmatice = array[1..MAX] of array [1..2] of integer;
TForm1 = class(TForm)
btnKonec: TButton;
Button2: TButton;
btnBudiz: TButton;
edtB: TEdit;
edtA: TEdit;
edtN: TEdit;
tmemo: TMemo;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
btnUlozit: TButton;
procedure edtNEnter(Sender: TObject);
procedure edtAEnter(Sender: TObject);
procedure edtBEnter(Sender: TObject);
procedure btnKonecClick(Sender: TObject);
procedure btnBudizClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure btnUlozitClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
n,A,B,i,j:integer;
X1,X2,Y1,Y2:real;
Mat: TMatice;
implementation
{$R *.dfm}
procedure NahodMat (var Mat: TMatice; Min,Max: Integer);
var
i,j: Integer;
begin
Randomize;
for i := 1 to 2 do
for j := 1 to n do begin
Mat [i,j]:= Min+Random (Max-Min+1);
end;
end;
procedure MatDoTmem (var Mat: TMatice; MemoBox: TMemo; n: Integer);
var
i,j: Integer;
s: String;
begin
for j := 1 to n do begin
s:= '[' + IntToStr(j) + '] = ';
for i := 1 to 2 do begin
s:= s+ IntToStr (Mat [i,j]) + ' ';
end;
MemoBox.Lines.Add (s);
end;
end;
procedure NejblizsiBody (Mat: TMatice; n: Integer; var MemoBox: TMemo; var Xi,Xj,Yi,Yj,Min_find: Real);
var
i,j: Integer;
Vzdal: real;
begin
Min_find:= maxint;
for i := 1 to n-1 do begin
for j := i+1 to n do begin
Vzdal:= sqrt((sqr(mat[1,i]-mat[1,j]))+(sqr(mat[2,i]-mat[2,j])));
if Vzdal < Min_find then begin
Min_find:= Vzdal;
Xi:=mat[1,i];
Xj:=mat[1,j];
Yi:=mat[2,i];
Yj:=mat[2,j];
end;
floatTostr(Nejblizsibody(vzdal));
MemoBox.Lines.Add ('Nejbližší body jsou:');
MemoBox.Lines.Add (vzdal)
end;
end;
end;
procedure TForm1.btnBudizClick(Sender: TObject);
var
Xi,Xj,Yi,Yj,Min_find:real;
begin
Tmemo.Text:= '';
n:= StrToInt (edtN.Text);
A:= StrToInt (edtA.Text);
B:= StrToInt (edtB.Text);
NahodMat (Mat, A, B);
MatDoTmem (Mat, tmemo, n);
NejblizsiBody (Mat,n,tmemo,Xi,Xj,Yi,Yj,Min_find);
end;
procedure TForm1.btnKonecClick(Sender: TObject);
begin
close;
end;
procedure TForm1.btnUlozitClick(Sender: TObject);
var
F: TextFile;
i,j: Integer;
begin
AssignFile (F, 'data.txt');
ReWrite (F);
for j := 1 to n do
for i := 1 to 2 do
WriteLn (F, '[' + IntToStr(j) + '] = ' + IntToStr(Mat[i,j]));
CloseFile (F);
ShowMessage ('Soubor data.txt byl vytvoren');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
edtN.Text:= '';
edtA.Text:= '';
edtB.Text:= '';
self.tmemo.Text:= '';
end;
procedure TForm1.edtAEnter(Sender: TObject);
begin
self.edtA.Text:='';
end;
procedure TForm1.edtBEnter(Sender: TObject);
begin
self.edtB.Text:='';
end;
procedure TForm1.edtNEnter(Sender: TObject);
begin
self.edtN.Text:='';
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
Randomize;
self.tmemo.Text:='';
end;
end.
Za jakoukoliv pomoc předem děkuji.
-
O Delphi celkem nic nevim, takze bez podrobneho zkoumani ciste k logice jako takove:
Zapsani vzdalenosti by urcite melo byt az za cyklem, ktery ji hleda, nikoliv uvnitr.
Vysledna hodnota neni v promenne vzdal, ale min_find.
floatToStr je asi podle nazvu funkce, ktera pro float vstup vraci String, tzn. tak jak je zavolana to nema smysl, asi by to melo byt az v tom vypisu MemoBox.Lines.Add(floatTostr(min_find)).
Mas vypsat souradnice bodu, coz nikde nevidim - i po upravach viz vyse vypises pri trose stesti pouze vzdalenost. Souradnice si ale samozrejme muzes zapamatovat analogicky min_find a pak je vypsat.
-
Děkuji za radu stačilo to opravit jak jste říkal a trošku doladit s těmi body a už to běží. :) Takto ted vypadá kód:
procedure NejblizsiBody (Mat: TMatice; n: Integer; var MemoBox: TMemo; var Xi,Xj,Yi,Yj,Min_find: Real);
var
i,j: Integer;
Vzdal: real;
begin
Min_find:= maxint;
for i := 1 to n-1 do begin
for j := i+1 to n do begin
Vzdal:= sqrt((sqr(mat[1,i]-mat[1,j]))+(sqr(mat[2,i]-mat[2,j])));
if Vzdal < Min_find then begin
Min_find:= Vzdal;
Xi:=mat[1,i];
Xj:=mat[1,j];
Yi:=mat[2,i];
Yj:=mat[2,j];
end;
end;
end;
MemoBox.Lines.Add ('-----');
MemoBox.Lines.Add ('Vzdálenost nejbližších bodů je:');
MemoBox.Lines.Add(floatTostr(min_find));
MemoBox.Lines.Add ('-----');
MemoBox.Lines.Add ('Nejbližší body jsou:');
MemoBox.Lines.Add('['+floatTostr(Xi)+','+floatTostr(Yi)+'] a ['+floatTostr(Xj)+','+floatTostr(Yj)+']');
MemoBox.Lines.Add ('-----');
end;
-
Ať žije "brute force" :D
-
Jeníčku, slyšels někdy o tomhle http://en.wikipedia.org/wiki/R-tree (http://en.wikipedia.org/wiki/R-tree)? Nejenom programování zřejmě nebude tvoje silná stránka.
-
Jeníčku, slyšels někdy o tomhle http://en.wikipedia.org/wiki/R-tree (http://en.wikipedia.org/wiki/R-tree)? Nejenom programování zřejmě nebude tvoje silná stránka.
Jaký smysl má trápit se s tím ve školním projektu? Jeho řešení odpovídá zadání a zcela ho splňuje. Mimochodem r-tree není zdaleka jediná metoda, jak to udělat:
http://en.wikipedia.org/wiki/Nearest_neighbor_search
-
Nikdy jsem o tom neslyšel. :o Potřebuji pouze udělat zápočet + zkoušku z technické informatiky a dostudovat Strojního inženýra. ;) Nemyslím si, že se budu programováním někdy živit, ale je pravda že jsem se ho vždycky naučit. Na druhou stranu člověk nikdy neví. Ovšem momentálně na to mám "hrozně moc" času... :(
-
Jaký smysl má trápit se s tím ve školním projektu? Jeho řešení odpovídá zadání a zcela ho splňuje. Mimochodem r-tree není zdaleka jediná metoda, jak to udělat:
http://en.wikipedia.org/wiki/Nearest_neighbor_search
Jde o to, co vlastně člověk chce. Něco se naučit nebo to nějak spatlat, abych to měl za sebou. Tady jde zřejmě o ten druhý případ.
-
@ Jaký smysl má trápit se s tím ve školním projektu? Jeho řešení odpovídá zadání a zcela ho splňuje.
Souhlas. Při pohledu na algoritmus mě ale napadá jedna snadná optimalizace. Protože mocnina a odmocnina jsou výpočetně náročnější, nejdřív bych si zkontroloval vzdálenost pouze x-ových souřadnic a y-ových souřadnic. Pokud jsou tyto větší než nejmenší nalezená vzdálenost (Min_Find), pak ani nemá smysl tu odmocninu počítat.
-
Souhlas. Při pohledu na algoritmus mě ale napadá jedna snadná optimalizace. Protože mocnina a odmocnina jsou výpočetně náročnější, nejdřív bych si zkontroloval vzdálenost pouze x-ových souřadnic a y-ových souřadnic. Pokud jsou tyto větší než nejmenší nalezená vzdálenost (Min_Find), pak ani nemá smysl tu odmocninu počítat.
Ono by se to obešlo bez odmocniny úplně, když jde jen o porovnání, a výsledek ponechat jako int.
-
Jde o to, co vlastně člověk chce. Něco se naučit nebo to nějak spatlat, abych to měl za sebou. Tady jde zřejmě o ten druhý případ.
Nemá smysl věnovat zbytečný čas školním projektům, protože když tam uděláš něco navíc, stejně to nikdo neocení. Lepší je využít volný čas na studium toho, co tě opravdu zajímá a čemu se chceš věnovat. Mimochodem když už doporučuješ použít k hledání nejbližších bodů nějaký super-hyperprostor-ideal-hashing-tree, bylo by také dobré zmínit, že konstrukce toho něco stojí, kód bude delší a méně přehledný a paměťová náročnost bude mnohem větší. A každý strom má oproti flat paměťové struktuře na reálném hardware jednu velkou chybu, téměř každý přístup k prvku znamená cache miss, který je hodně drahý, protože pamět je hrozně fragmentovaná. Nedá se říct, který algoritmus bude lepší, bez znalosti výchozích podmínek (kolik tam bude typicky prvků, jak často se budou ty prvky měnit a jak často je potřeba něco hledat, kolik na to mám paměti, na jakém hardware to vlasně poběží...). Znevažovat schopnosti Jeníčka jen kvůli algoritmu, který použil, je hloupé, on naopak po tom co dostal radu velmi rychle pochopil, kde má chybu a opravil to, takže hloupý nebude.