Algorithm-TravelingSalesman-BitonicTour
view release on metacpan or search on metacpan
t/01-setup.t view on Meta::CPAN
use warnings;
use Test::More 'no_plan';
use Test::Exception;
use Algorithm::TravelingSalesman::BitonicTour;
my $b = Algorithm::TravelingSalesman::BitonicTour->new;
ok($b);
is($b->N, 0);
throws_ok { $b->R } qr/Problem has no rightmost point/, '... with a nice error message';
# add a few points, making sure they're stored and sorted correctly
$b->add_point(0,0);
is($b->N, 1);
is($b->R, 0);
is_deeply( [$b->sorted_points], [[0,0]] );
$b->add_point(3,0);
is($b->N, 2);
t/01-setup.t view on Meta::CPAN
$b->add_point(1,1);
is($b->N, 4);
is($b->R, 3);
is_deeply( [$b->sorted_points], [[0,0], [1,1], [2,1], [3,0]] );
# make sure that attempts to add points with duplicate X-coordinates croak()
{
dies_ok { $b->add_point(2,1) } 'repeated X-coordinate should die';
dies_ok { $b->add_point(2,2) } 'repeated X-coordinate should die';
dies_ok { $b->add_point(2,3) } 'repeated X-coordinate should die';
throws_ok { $b->add_point(2,1) } qr/duplicates previous point/,
'with a nice error message';
}
# make sure we can retrieve coordinates correctly
is_deeply([ $b->coord( 0) ], [ 0, 0 ]);
is_deeply([ $b->coord( 1) ], [ 1, 1 ]);
is_deeply([ $b->coord( 2) ], [ 2, 1 ]);
is_deeply([ $b->coord( 3) ], [ 3, 0 ]);
is_deeply([ $b->coord(-1) ], [ 3, 0 ]); # sweet
t/02-optimal-tours.t view on Meta::CPAN
# set up a problem and do some basic sanity checking
my $b = Algorithm::TravelingSalesman::BitonicTour->new;
$b->add_point(0,0);
$b->add_point(1,1);
$b->add_point(2,1);
$b->add_point(3,0);
is($b->N, 4);
is_deeply( [$b->sorted_points], [[0,0], [1,1], [2,1], [3,0]] );
# optimal open tours aren't populated yet...
throws_ok { $b->tour_length(1,2) } qr/Don't know the length/, 'die on unpopulated tour length';
throws_ok { $b->tour_points(1,2) } qr/Don't know the points/, 'die on unpopulated tour points';
# make sure population with bad endpoints is caught...
throws_ok { $b->tour_points(1,2,0,1,2) } qr/ERROR/, 'die on bad endpoints';
throws_ok { $b->tour_points(1,2,1,2,3) } qr/ERROR/, 'die on bad endpoints';
throws_ok { $b->tour_points(1,2,1,2) } qr/ERROR/, 'die on wrong number of points';
# populate the optimal open tours
$b->populate_open_tours;
#diag(Dumper($b));
# make sure invalid tour queries throw an exception
throws_ok { $b->tour(1,0) } qr/ERROR/, 'die on invalid tour limits';
throws_ok { $b->tour_length(42,142) } qr/ERROR/, 'die on invalid length limits';
throws_ok { $b->tour_length(0,1,-1) } qr/ERROR/, 'die on invalid length';
throws_ok { $b->optimal_open_tour(1,0) } qr/ERROR/, 'die on invalid tour limits';
throws_ok { $b->optimal_open_tour(1.5,2) } qr/ERROR/, 'die on invalid tour limits';
{
my @tour = $b->optimal_open_tour(1,2);
is (sprintf('%.2f',$tour[0]), 3.65);
}
{
my @tour = $b->optimal_open_tour(0,2);
is (sprintf('%.3f',$tour[0]), 2.414);
}
t/10-solve-0.t view on Meta::CPAN
use Algorithm::TravelingSalesman::BitonicTour;
use Data::Dumper;
use Test::More 'no_plan';
use Test::Exception;
use_ok('Algorithm::TravelingSalesman::BitonicTour');
# make sure an attempt to solve a problem with no points dies
{
my $b = Algorithm::TravelingSalesman::BitonicTour->new;
throws_ok { $b->solve } qr/need to add some points/,
'bad problem throws exception';
}
( run in 0.530 second using v1.01-cache-2.11-cpan-496ff517765 )