Algorithm-SetCovering
view release on metacpan or search on metacpan
SetCovering.pm view on Meta::CPAN
__END__
=head1 NAME
Algorithm::SetCovering - Algorithms to solve the "set covering problem"
=head1 SYNOPSIS
use Algorithm::SetCovering;
my $alg = Algorithm::SetCovering->new(
columns => 4,
mode => "greedy");
$alg->add_row(1, 0, 1, 0);
$alg->add_row(1, 1, 0, 0);
$alg->add_row(1, 1, 1, 0);
$alg->add_row(0, 1, 0, 1);
$alg->add_row(0, 0, 1, 1);
my @to_be_opened = (@ARGV || (1, 1, 1, 1));
my @set = $alg->min_row_set(@to_be_opened);
print "To open (@to_be_opened), we need ",
scalar @set, " keys:\n";
for(@set) {
print "$_: ", join('-', $alg->row($_)), "\n";
}
=head1 DESCRIPTION
Consider having M keys and N locks. Every key opens one or more locks:
| lock1 lock2 lock3 lock4
-----+------------------------
key1 | x x
key2 | x x
key3 | x x x
key4 | x x
key5 | x x
Given an arbitrary set of locks you have to open (e.g. 2,3,4),
the task is to find a minimal set of keys to accomplish this.
In the example above, the set [key4, key5] fulfils that condition.
The underlying problem is called "set covering problem" and
the corresponding decision problem is NP-complete.
=head2 Methods
=over 4
=item $alg = Algorithm::SetCovering->new(columns => $cols, [mode => $mode]);
Create a new Algorithm::SetCovering object. The mandatory parameter
C<columns> needs to be set to the number of columns in the matrix
(the number of locks in the introductory example).
C<mode> is optional and selects an algorithm for finding the solution.
The following values for C<mode> are implemented:
=over 4
=item "brute_force"
Will iterate over all permutations of keys. Only recommended for
very small numbers of keys.
=item "greedy"
Greedy algorithm. Scales O(mn^2). Can't do much better for a NP-hard
problem.
=back
The default for C<mode> is set to "greedy".
=item $alg->add_row(@columns)
Add a new row to the matrix. In the example above, this adds one key
and specifies which locks it is able to open.
$alg->add_row(1,0,0,1);
specifies that the new key can open locks #1 and #4.
The number of elements
in @columns needs to match the previously defined number of columns.
=item $alg->min_row_set(@columns_to_cover)
Determines a minimal set of keys to cover a given set of locks
and returns an array of index numbers for those keys.
Defines which columns have to be covered by passing in an array
with true values on element positions that need to be covered.
For example,
my @idx_set = $alg->min_row_set(1,1,0,1);
specifies that all but the third column have to be covered and returns
an array of index numbers into an array, defined previously
(and implicitely) via successive add_row() commands.
If no set of keys can be found that satisfies the given requirement,
an empty list is returned.
If you've forgotten which locks the key referred to by a certain index number
can open, use the C<rows()> method to find out:
my(@opens_locks) = $alg->rows($idx_set[0]);
will give back an array of 0's and 1's, basically returning the
very parameters we've passed on to the
add_row() command previously.
=back
=head2 Strategies
( run in 0.559 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )