Autor Beitrag
scolia
Hält's aus hier
Beiträge: 1



BeitragVerfasst: Di 13.06.06 11:21 
Hallo,

ich programmiere ein Tool, das den kürzesten Weg finden soll, um n Postleitzahlen abzuklappern. Ich habe hier keinerlei Optimierung eingebaut sondern versuche einfach durch Durchgehen aller Möglichkeiten den kürzesten Weg zu finden.

Das Programm an sich steht - ich kann die Entfernung zweier PLZ berechnen (mithilfe von OpenGeoDB). Blöderweise will der Backtracking-Algorithmus nicht so ganz.

Kann sich das mal jemand anschauen?
Ich habe das komplette Projekt angehängt und hier die Backtracking-Prozedur:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
procedure search(resList:TPlzList;distance:extended);
  VAR curLength : integer;
      srcList,temp : TPlzList;
      newDistance : extended;
begin
   srcList := PlzList;
   while (srcList <> NILdo begin
       new(temp);
       temp^.plz := srcList^.plz;
       temp^.coord := srcList^.coord;
       temp^.next := NIL;
       if resList = NIL then   begin
        resList := temp;
         end
       else
        resList^.next := temp;
       newDistance := distance + getDistance(temp^.coord,resList^.coord);
       if countList(resList) < countList(PlzList) then begin
       showmessage(resList^.plz);
         search(resList^.next,newDistance);
         end
       else if ((MinDist = 0OR (newDistance < MinDist)) then begin
         MinList := resList;
         MinDist := newDistance;
       end;
       srcList := srcList^.next;
   end;
end;


PlzList enthält alle PLZ, zu denen ich muss. getDistance() gibt mir die Entfernung zweier Koordinaten. In MinList will ich am Ende die kürzeste Reihenfolge der PLZ haben, in MinDist die dazugehörige Länge.

Wäre toll wenn mir jemand helfen kann.

Schöne Grüße,
Tim
Einloggen, um Attachments anzusehen!
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 13.06.06 20:06 
Ich hab zwar nicht direkt dein Projekt angeschaut, aber versuch's mal so:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
type
    TPLZ = Record
        PLZ: String;
        Coord : TCoords;
    end;
    TPLZList = array of TPLZ;
    TPLZListArray = Array of TPLZList;

Function search(resList:TPlzList; out: Distance: Extended;): TPLZListArray;
var 
    CurrLevel: Integer;
    CurrArray: TPLZList;

    procedure DoSearchList(List: TPLZList; Dist: Extended);
    var
        X, Y: Integer;
        Tmp: TPLZList;
    begin
        Inc(CurrLevel);
        Try
            If Length(List) = 0 Then
            Begin
                if NearbyEquals(Dist, Distance) Then
                begin
                    SetLength(Result, Length(Result) + 1);
                    Result[High(Result)] := CurrArray;
                end
                else If Dist < Distance Then
                Begin
                    SetLength(Result, 1);
                    Result[0] := CurrArray;
                    Distance := Dist;
                end;
                exit;
            end;

            If Dist > Distance Then
                Exit;

            SetLength(Tmp, High(List));
            For X := 0 To High(List) do
            Begin
                For Y := 0 To High(List) Do
                    If X <> Y Then
                        Tmp[Y - Ord(Y > X)] := List[Y];
                CurrArray[CurrLevel] := List[X];
                If CurrLevel = 0 Then
                    DistAdd := 0
                else
                    DistAdd := GetDistance(CurrArray[CurrLevel-1], CurrArray[CurrLevel]);
                DoSearchList(Tmp, Dist + DistAdd);
            end;
        finally
            Dec(CurrLevel);
        end;
    end;

begin
    SetLength(Result, 0);
    Distance := Infinity; //Unit Math, ansonsten ne Const Infinity = 1/0; deklarieren
    CurrLevel := -1;
    SetLength(CurrArray, Length(ResList));

    DoSearchPath(ResList, 0);
end;


Ungetestet ... Habsch grad mal so aus'm Kopf geschrieben, müsste aber rein theoretisch so funzen. Ach ja: GetDistance(CurrArray[CurrLevel-1], CurrArray[CurrLevel]); ermittelt den Abstand der beiden als Parameter angegebenen Postleitzahleneinträge.

HTH.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.