30. august 2002 - 08:49Der er
12 kommentarer og 2 løsninger
Afstand ml. punkter
Har mange punkter (x,y) f.eks 10000 stk. (kan have mange flere). Skal findes afstanden mellem alle punkter, for at finde gennemsnitsafstanden mellem alle punkter og bruger derfor:
SetLength(Dist,High(Coord3D)-1,High(Coord3D)-1);
for i := 0 to High(Coord3D)-1 do begin for j := 0 to High(Coord3D)-1 do begin Dist[i,j] := Sqrt(Sqr(Coord3D[i].x-Coord3D[j].x)+Sqr(Coord3D[i].y-Coord3D[j].y)); end; end;
Hvor: type TDistanceXY = array of array of double;
type TPOINT3 = packed record X,Y,Z : Double; end;
var Coord3D: array of TPOINT3; Dist: TDistanceXY;
Problemet er at det tager jo 'lidt' tid for 10000 punker og urimmeligt lang tid og crash med 1000000 punkter.
- Du finder f.eks. afstand fra pkt. A til pkt. A - vel ikke nødvendigt - Du finder også afstande to gange: Afstand fra A til B er jo den samme som afstand B til A - Lav en løbende beregning af gennemsnit så du kan droppe Dist array'en
Vel tænkt, meninger er dog at lave et semivariogram. Så skal finde gennemsnitsafstanden (x) først. Derefter beregne variancen mellem alle punkter placeret i afstanden x, derefter i afstanden 2x, 3x, 4x ... nx. Skal derfor have en liste med alle afstande i. Bliver måske nød til at lave en aggregationsrutine først for at kondensere punkterne. Lader den stå lidt endnu.
Denne lille ændring vil skære en _pæn_ del af tiden, tro det eller ej (prøv at lave en tidstest):
H := High(Coord3D)-1; for i := 0 to H do begin for j := 0 to H do begin
Dine arrays er kæmpe store (10000 punkter kræver omkring 750MB ram!). Hvis du kunne leve uden decimaler ville du kunne få både RAM- og tidsforbrug meget længere ned. Du kunne evt. bruge fixed point math, hvis du kender det (ellers slå det op).
Men under alle omstændigheder kan du blive nødt til at gemme dine arrays på disk (med et lille caching system), for du vil næppe have RAM nok til at de bliver meget større. Det vil også være langt hurtigere end at lade Windows klare swapping.
Der findes 3 Double's i et TPOINT3... Altså fylder et TPOINT3 8 byte*3 = 24 byte...
Hvis han har 10000 af dem, så giver det altså kun 240000 bytes = 234,375 kbyte...
Hmmm... 750 mb ram behøves vist ikke alligevel! ;)
Tror du skal ha' en del flere punkter for at fylde 750 mb ram op... You do the math!
Desuden har jeg en gang haft et array af en klasse med 3 strings, 2 integers og en type jeg selv har erklæret der nok fylder omkring 1 byte... Jeg hentede en gang 7000 forskellige ting ind i det array, og det brokkede den sig egentlig ikke...
Samtidig skulle den vise egenskaberne for de ting jeg hentede ind i en TListView... No problems! :)
Forresten, så prøv en gang at lade være med at bruge et packed record... Det er langsommere end et alm. record... ;)
Oupes... Det er mig der har sovet... Underligt nok kan jeg godt se det efter at være kommet hjem fra grill-party! :D
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.