algorithms

Repository of programs that demonstrate basic algorithms I've been learning
git clone git://git.samirparikh.com/algorithms
Log | Files | Refs | README

commit d5b2531aa34829a42d71ddfa5e67ef4a9d5439ec
parent 888c793c53ef3aada8482d3a6028030963c99487
Author: Samir Parikh <noreply@samirparikh.com>
Date:   Mon,  3 Jan 2022 02:25:23 +0000

update to allow neighbors to both top and left (in addition to right and down as previously implemented)

Diffstat:
Mdijkstra_shortest_path.pl | 91+++++++++++++++++++++++--------------------------------------------------------
1 file changed, 26 insertions(+), 65 deletions(-)

diff --git a/dijkstra_shortest_path.pl b/dijkstra_shortest_path.pl @@ -11,7 +11,6 @@ use v5.22; # ignore when we are processing the neighbors of a node during our graph # traversal use constant LIMIT => 10; -use Data::Dumper; sub get_filehandle { if (@ARGV !=1) { @@ -32,18 +31,17 @@ sub define_matrix { } sub init_graph_costs { - #my ($matrix_ref, $graph_ref, $costs_ref) = @_; my $matrix_ref = shift; my @mat = @{ $matrix_ref }; my %grph; my %csts; - my $r = scalar @mat; + my $r = scalar @mat; my $c = scalar @{ $mat[0] }; - print Dumper (\@mat); foreach my $row (0 .. $r - 2) { foreach my $col (0 .. $c - 2) { $csts{$row, '-', $col} = 'inf'; - foreach my $neighbor ([0, 1], [1, 0]) { + foreach my $neighbor ([0, 1], [1, 0], [0, -1], [-1, 0]) { + print "i"; my $n_row = $row + $neighbor->[0]; my $n_col = $col + $neighbor->[1]; $grph{$row, '-', $col}{$n_row, '-', $n_col} = $mat[$n_row][$n_col] @@ -52,70 +50,27 @@ sub init_graph_costs { } } $grph{'start'}{0, '-', 0} = $mat[0][0]; # start node to 0, 0 - $grph{2, '-', 2}{'end'} = 0; # n, n node to end + $grph{$r - 2, '-', $c - 2}{'end'} = 0; # n, n node to end $csts{0, '-', 0} = $mat[0][0]; $csts{'end'} = 'inf'; - say "within the subroutine..."; - print Dumper (\%grph); - print Dumper (\%csts); - #$parents{0, '-', 0} = 'start'; return (\%grph, \%csts); } -my $filehandle = get_filehandle(); -my @matrix = define_matrix($filehandle); -#print Dumper (\@matrix); -#my @matrix = map{ [m/\d/g, LIMIT] } <$filehandle>; # add extra column of 9s -#my $columns = @{$matrix[0]}; -#push @matrix => [ (LIMIT) x $columns ]; # add extra row of 9s -#my $rows = @matrix; -#my $columns = $rows; -#my %graph; -#my %costs; -my %parents; -$parents{0, '-', 0} = 'start'; -# hash to track all of the nodes we have already processed -my %processed; -#init_graph_costs(\@matrix, \%graph, \%costs); -my ($graph_ref, $costs_ref) = init_graph_costs(\@matrix); -my %graph = %{ $graph_ref }; -my %costs = %{ $costs_ref }; -#my %parents; -# hash to track all of the nodes we have already processed -#my %processed; - -#print Dumper (\@matrix); -#foreach my $row (0 .. $rows - 2) { -# foreach my $col (0 .. $columns - 2) { -# $costs{$row, '-', $col} = 'inf'; -# foreach my $neighbor ([0, 1], [1, 0]) { -# my $n_row = $row + $neighbor->[0]; -# my $n_col = $col + $neighbor->[1]; -# $graph{$row, '-', $col}{$n_row, '-', $n_col} = $matrix[$n_row][$n_col] -# unless ($matrix[$n_row][$n_col] == LIMIT); -# } -# } -#} -#$graph{'start'}{0, '-', 0} = $matrix[0][0]; # start node to 0, 0 -#$graph{2, '-', 2}{'end'} = 0; # n, n node to end -#$costs{0, '-', 0} = $matrix[0][0]; -#$costs{'end'} = 'inf'; -#$parents{0, '-', 0} = 'start'; -say "after the subroutine..."; -print Dumper (\%graph); -print Dumper (\%costs); - sub find_lowest_cost_node { + my ($costs_ref, $processed_ref) = @_; + my %csts = %{ $costs_ref }; + my %proc = %{ $processed_ref }; # set lowest cost to infinity for initial comparison my $lowest_cost = 'inf'; # set default lowest cost node to None in case none if sound my $lowest_cost_node = 'None'; # for each node in our costs table - foreach my $node (keys %costs) { - my $cost = $costs{$node}; + foreach my $node (keys %csts) { + #print "f"; + my $cost = $csts{$node}; # check if node is lowest cost so far AND # it has not yet been processed by our main while loop - if ($cost < $lowest_cost && !exists $processed{$node}) { + if ($cost < $lowest_cost && !exists $proc{$node}) { # if it is, update our $lowest_cost and $lowest_cost_node $lowest_cost = $cost; $lowest_cost_node = $node; @@ -125,36 +80,42 @@ sub find_lowest_cost_node { return $lowest_cost_node; } -my $node = find_lowest_cost_node; +# initialize variables +my $filehandle = get_filehandle(); +my @matrix = define_matrix($filehandle); +my ($graph_ref, $costs_ref) = init_graph_costs(\@matrix); +my %graph = %{ $graph_ref }; +my %costs = %{ $costs_ref }; +my %parents; +$parents{0, '-', 0} = 'start'; +# hash to track all of the nodes we have already processed +my %processed; +my $node = find_lowest_cost_node(\%costs, \%processed); while ($node ne 'None') { + say "processing node $node"; my $cost = $costs{$node}; # cost to get to current node my @neighbors = keys %{$graph{$node}}; # neighbors of node - say "current node is $node. current cost is $cost"; - say "neighbors are @neighbors"; # go through all neighbors of this node foreach my $neighbor (@neighbors) { # calculate new cost of getting to neighbor via this node - say "evaluating neightbor $neighbor whose current cost is $costs{$neighbor}"; my $new_cost = $cost + $graph{$node}{$neighbor}; - say "the new cost to get to $neighbor via $node is ($cost + $graph{$node}{$neighbor}) $new_cost"; # if it's cheaper to get to this neighbor through this node if ($costs{$neighbor} > $new_cost) { # update new cost for the neighbor $costs{$neighbor} = $new_cost; # the current node becomes the parent of the neighbor $parents{$neighbor} = $node; - say "it's cheaper to get to $neighbor via $node"; - say "new cost is $new_cost"; } - say "------------------"; } # mark the node as processed $processed{$node} = 1; # find the next node to process - $node = find_lowest_cost_node; + $node = find_lowest_cost_node(\%costs, \%processed); } +print "\n"; + # @path is our array holding the shortest path # we build it up starting from the end ('fin') and append the coresponding # parent ($parents{$path[0]}) to the FRONT of the array until we reach the