Code kata: shortest path

| No Comments

В продолжение к: http://friendfeed.com/kkapp/b5d3658c

Заняло минут 40. На полпути понял, что останавливаться на первом найденном пути нельзя. В любом случае получился неоптимальный вариант, который на графах с большим количеством дуг может стать кубическим.

#! /usr/bin/perl
use strict;
use warnings;

use Test::Most;
use Data::Dump;

# a graph is stored as its adjacency array:
# for each vertex we have a list of pairs, each containing
# the index of the incident vertex and the weight of the arc to it.

sub spath {
	my ($graph, $from, $to) = @_;

	my @path = (-1) x @$graph;

	my $was_changed = 1;

	$path[$from] = 0;

	while ($was_changed) {
		$was_changed = 0;

		for my $v (grep { $path[$_] != -1 } 0 .. $#path) {
			for my $nv (@{$graph->[$v]}) {
				if  ($path[$nv->[0]] == -1
				  || $path[$nv->[0]] > $path[$v] + $nv->[1])
				{
					$path[$nv->[0]] = $path[$v] + $nv->[1];
					$was_changed = 1;
				}
			}
		}
	}

	return $path[$to];
}

is(spath([[], []], 0, 1), -1);

my $g1 = [
	[[1 => 10], [2 => 21], [3 => 100]],	# 0
	[[2 => 30], [0 => 20], [4 => 50]],	# 1
	[[5 => 40]],				# 2
	[],					# 3
	[],					# 4
	[[5 => 11]],				# 5
];

is(spath($g1, 0, 3), 100);
is(spath($g1, 0, 4), 60);
is(spath($g1, 0, 5), 61);
is(spath($g1, 1, 0), 20);
is(spath($g1, 2, 0), -1);
is(spath($g1, 2, 2), 0);
is(spath($g1, 5, 5), 0);

# A --10-> B --10-> C --10-> D
#  \-----1----------^  ------^
#   \---------1000----/

my $g2 = [
	[[1 => 10], [2 => 1], [3 => 1000]],	# 0
	[[2 => 10]],		# 1
	[[3 => 10]],		# 2
	[],			# 3
];

is(spath($g2, 0, 3), 11);
is(spath($g2, 1, 3), 20);

#  /--1000-v
# A --10-> B --10-> C --10-> D
#  \--------100-----^
#

my $g3 = [
	[[1 => 1000], [1 => 10], [2 => 100]],
	[[2 => 10]],
	[[3 => 10]],
	[],
];

is(spath($g3, 0, 1), 10);
is(spath($g3, 0, 2), 20);

done_testing;

Leave a comment

About this Entry

This page contains a single entry by Alex Kapranoff published on December 5, 2012 4:58 PM.

Code kata: binary search was the previous entry in this blog.

Code kata: numeric integration is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Pages

  • about
Powered by Movable Type 5.2.6791-en-master-r6791-122a610d-20130202