Shortest path problem
Slaven Rezic
eserte at cs.tu-berlin.de
Tue Oct 19 16:40:00 PDT 1999
Pierluigi Vittori <piero at innova.it> writes:
>
> On ven, 15 ott 1999, Slaven Rezic wrote:
>
> > Hello Cameron, hello Pierluigi,
> >
> > I use the algorithm A* to get the shortest path between two places. I
> > don't know what's the format of the mapserver data, but I think it
> > should be easy to make it usable by my perl module. The module is part
> > of a larger system. The sources can be found under
> > http://pub.cs.tu-berlin.de/src/BBBike
>
> Hello Slaven!
>
> can you indicate any papers or other kind of references to turn to for a
> theoretical background on such an issue?
> I appreciate your help very much. Thanks.
>
Here are some:
Kanal, L.; and Kumar, V., Search in Artificial Intelligence,
Springer-Verlag New York, 1988.
Korf, Richard E., Optimal Path-Finding Algorithms, in Search
in Artificial Intelligence, Springer-Verlag New York, 1988, pages
233-241.
Below is a sample implementation of the algorithm in perl.
Regards,
Slaven
######################################################################
# -*- perl -*-
#
# $Id: BBBikeDiplom.pm,v 1.3 1999/08/26 19:51:59 eserte Exp $
# Author: Slaven Rezic
#
# Copyright (C) 1999 Slaven Rezic. All rights reserved.
# This package is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
# Mail: eserte at cs.tu-berlin.de
# WWW: http://user.cs.tu-berlin.de/~eserte/
#
package BBBikeDiplom;
use Strassen;
package StrassenNetz;
# implementiert die Suche mit dem Algorithmus A*
sub search_A_star {
my($self, $from, $to) = @_;
if ($data_format != 1) {
die "Only implemented for data format 1";
}
my $net = $self->{Net};
# %OPEN entspricht der Liste OPEN aus der Algorithmusbeschreibung
# Der Key des Hashs ist der Knoten n (die Koordinate im
# Straßennetz), der Value ist ein Array, wovon das erste Element
# den Vorgänger enthält (oder undef) und das zweite Element die
# bisherige Länge g(n).
# Der Startknoten wird sofort in OPEN eingefügt (Punkt 1)
my %OPEN = ($from => [undef, 0]);
my %CLOSED;
while (1) {
# Punkt 2: es gibt keine Lösung
if (keys %OPEN == 0) {
return ();
}
# Punkt 3
my(@sort_list) = sort {
# nach Minimum Sortieren
$a->[0] <=> $b->[0]
} map {
# f = g + h berechnen
my $f = $OPEN{$_}->[1] + Strassen::Util::strecke_s($_, $to);
[$f, $_];
} keys %OPEN;
# der Knoten (Koordinaten) des Minimums
my $min_node = $sort_list[0]->[1];
# ... wird aus OPEN nach CLOSED bewegt
$CLOSED{$min_node} = $OPEN{$min_node};
delete $OPEN{$min_node};
# Punkt 4
if ($min_node eq $to) {
my @path;
my $len = 0;
while (1) {
push @path, $min_node;
my $prev_node = $CLOSED{$min_node}->[0];
if (defined $prev_node) {
$len += Strassen::Util::strecke_s($min_node, $prev_node);
$min_node = $prev_node;
} else {
last;
}
}
@path = map { [ split(/,/, $_) ] } reverse @path;
return (\@path, $len, 0, 0, 0);
}
# Punkt 5
my @successors = keys %{ $net->{$min_node} };
foreach my $successor (@successors) {
my $g = $CLOSED{$min_node}->[1] + # bisherige Länge bis n
$net->{$min_node}{$successor}; # Länge bis n'
my $f = $g + Strassen::Util::strecke_s($min_node, $to); # h(n')
if (!exists $OPEN{$successor} and
!exists $CLOSED{$successor}) {
$OPEN{$successor} = [$min_node, $g];
} else {
my $OPEN_OR_CLOSED;
if (exists $OPEN{$successor}) {
$OPEN_OR_CLOSED = $OPEN{$successor};
} else {
$OPEN_OR_CLOSED = $CLOSED{$successor};
}
if ($f < $OPEN_OR_CLOSED->[1]) {
$OPEN_OR_CLOSED = [$f, $min_node];
if (exists $CLOSED{$successor}) {
$OPEN{$successor} = $CLOSED{$successor};
delete $CLOSED{$successor}; # hier oder immer? XXX
}
}
}
}
}
}
1;
__END__
######################################################################
--
use Tk;$c=tkinit->Canvas(-he,20)->grid;$x=5;map{s/\n//g;map{$c->create('line'=>
map{$a=-43+ord;($x+($a>>3)*2=>5+($a&7)*2)}split//)}split/!/;$x+=12}split/_/=>'K
PI1_+09IPK_K;-OA1_+K!;A__1;Q!7G_1+QK_3CLPI90,_+K!;A_+1!KQ!.N_K+1Q!.F_1+KN.Q__1+
KN._K+1Q!.F_1+KN.Q_+1Q__+1!KQ!.N_1;Q!7G_K3,09Q_+1!K.Q_K+1Q!.F_1+KN.Q_';MainLoop
More information about the MapServer-users
mailing list