Algorithm-X-DLX
view release on metacpan or search on metacpan
lib/Algorithm/X/DLX.pm view on Meta::CPAN
package Algorithm::X::DLX;
use strict;
use warnings;
our $VERSION = '0.03';
require 5.06.0;
use Algorithm::X::LinkedMatrix;
sub new {
my ($class, $problem) = @_;
return bless { A_ => Algorithm::X::LinkedMatrix->new($problem), iterator => undef }, $class;
}
sub count_solutions {
my $self = shift;
my $options = Options();
$options->{get_solutions} = 0;
return $self->search($options)->{number_of_solutions};
}
sub find_solutions {
my ($self, $max) = @_;
my $options = Options();
$options->{max_solutions} = $max if defined $max;
return $self->search($options)->{solutions};
}
sub search {
my ($self, $options) = @_;
$options ||= Options();
if ($options->{random_engine}) {
die "The option to select a random engine has been removed in Perl";
}
my $result = { profile => [], number_of_solutions => 0, solutions => [] };
$self->{iterator} ||= $self->get_solver($options->{choose_random_column}, $result->{profile});
while (my $solution = $self->{iterator}() ) {
$result->{number_of_solutions}++;
if ($options->{get_solutions}) {
push @{$result->{solutions}}, $solution;
}
last if $result->{number_of_solutions} >= $options->{max_solutions};
}
return $result;
}
sub next_solution {
my $self = shift;
return $self->{iterator}();
}
sub get_solver {
my ($self, $random_column, $profile) = @_;
my $h = $self->{A_}->root_id();
my @placed = ();
my $level = 0;
my @state_stack = ([undef, undef]);
return sub {
# brought back on track by by Antti Ajanki, Tom Boothby at https://github.com/sagemath/sage/blob/develop/src/sage/combinat/dlx.py
while ( $level >= 0 ) {
( run in 2.836 seconds using v1.01-cache-2.11-cpan-524268b4103 )