Avatar billede lanstorp Nybegynder
30. august 2002 - 08:49 Der 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.

Er der en mere smart måde ?
Avatar billede danielks Nybegynder
30. august 2002 - 09:07 #1
Det vil jeg svare nej til.... Har selv brugt den metode du bruger...
Evt. Delphi 5.0 er måske bedre...
Avatar billede doc404 Novice
30. august 2002 - 09:20 #2
Kan din algoritme ikke optimeres lidt?

- 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
Avatar billede lanstorp Nybegynder
30. august 2002 - 09:30 #3
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.
Avatar billede dkn Nybegynder
30. august 2002 - 11:53 #4
det er lige får du skulle lave den multi threaded. Ikke så svært du skal bare køre nogle loops i hinanden
Avatar billede zimp Nybegynder
30. august 2002 - 12:19 #5
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.
Avatar billede lanstorp Nybegynder
30. august 2002 - 12:45 #6
>>Zimp skrev:
"gemme dine arrays på disk (med et lille caching system)"

- Ligger du inde med en code stump der illustrerer dette.
Avatar billede zimp Nybegynder
30. august 2002 - 13:17 #7
Desværre ikke noget der passer på dit eksempel
Avatar billede hermandsen Juniormester
30. august 2002 - 20:49 #8
Hmmm...

type
  TPOINT3 = packed record
    X,Y,Z : Double;
  end;

En Double = 8 bytes (se hjælpen)

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... ;)
Avatar billede zimp Nybegynder
30. august 2002 - 23:57 #9
Prøv at regne på hvor hvor meget Dist-arrayet fylder ;-)

Packed har iøvrigt ingen effekt på den record, den vil altid være 32-bit alligned.
Avatar billede doc404 Novice
31. august 2002 - 02:28 #10
hmmm... sikke nogle regne genier *G*

Hvis vi har 10000 punkter i Coord3D må dist (array of array...) blive 10000^2 * 24 og altså fylde ialt 2,400,000,000 bytes - rundt regnet 2.24GB

Og med 1000000 punkter? knapt 22TB... Ikke underligt, at det dør...
Avatar billede zimp Nybegynder
31. august 2002 - 03:19 #11
Din hovedregning er god nok Doc404, men Dist består ikke af TPOINT3, det er kun double (afstanden mellem to punkter er 1 tal).

Altså 10000^2 * 8 = 762MB
Avatar billede doc404 Novice
31. august 2002 - 08:35 #12
...Som jeg altid fik at vide i skolen Read the fucking question...burde have hørt efter ;-)
Avatar billede lanstorp Nybegynder
01. september 2002 - 15:28 #13
Takker for bemærkningerne.
Avatar billede hermandsen Juniormester
01. september 2002 - 23:48 #14
Oupes... Det er mig der har sovet... Underligt nok kan jeg godt se det efter at være kommet hjem fra grill-party! :D
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester