Algorithm-CP-IZ

 view release on metacpan or  search on metacpan

lib/Algorithm/CP/IZ.pm  view on Meta::CPAN

use Algorithm::CP::IZ::ValueSelector;
use Algorithm::CP::IZ::CriteriaValueSelector;
use Algorithm::CP::IZ::NoGoodSet;
use Algorithm::CP::IZ::SearchNotify;

our @ISA = qw(Exporter);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration	use Algorithm::CP::IZ ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'value_selector' => [ qw(
    CS_VALUE_SELECTOR_MIN_TO_MAX
    CS_VALUE_SELECTOR_MAX_TO_MIN
    CS_VALUE_SELECTOR_LOWER_AND_UPPER
    CS_VALUE_SELECTOR_UPPER_AND_LOWER
    CS_VALUE_SELECTOR_MEDIAN_AND_REST
    CS_VALUE_SELECTION_EQ
    CS_VALUE_SELECTION_NEQ
    CS_VALUE_SELECTION_LE
    CS_VALUE_SELECTION_LT
    CS_VALUE_SELECTION_GE
    CS_VALUE_SELECTION_GT
) ]);

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'value_selector'} } );

our $VERSION = '0.07';

sub AUTOLOAD {
    # This AUTOLOAD is used to 'autoload' constants from the constant()
    # XS function.

    my $constname;
    our $AUTOLOAD;
    ($constname = $AUTOLOAD) =~ s/.*:://;
    croak "&Algorithm::CP::IZ::constant not defined" if $constname eq 'constant';
    my ($error, $val) = constant($constname);
    if ($error) { croak $error; }
    {
	no strict 'refs';
	# Fixed between 5.005_53 and 5.005_61
#XXX	if ($] >= 5.00561) {
#XXX	    *$AUTOLOAD = sub () { $val };
#XXX	}
#XXX	else {
	    *$AUTOLOAD = sub { $val };
#XXX	}
    }
    goto &$AUTOLOAD;
}

require XSLoader;
XSLoader::load('Algorithm::CP::IZ', $VERSION);

# Preloaded methods go here.

# Autoload methods go after =cut, and are processed by the autosplit program.

my $Instances = 0;

sub _report_error {
    my $msg = shift;
    croak __PACKAGE__ . ": ". $msg;
}

sub new {
    my $class = shift;

    if ($Instances > 0) {
	_report_error("another instance is working.");
    }

    Algorithm::CP::IZ::cs_init();
    $Instances++;

    bless {
	_vars => [],
	_cxt0 => [],
	_cxt => [],
	_const_vars => {},
	_backtracks => {},
	_ref_int_arrays => {},
	_ref_var_arrays => {},
    }, $class;
}

sub DESTROY {
    my $self = shift;
    my $vars = $self->{_vars};

    for my $v (@$vars) {
	# we must check existence of variable for global destruction.
	$v->_invalidate if (defined $v);
    }

    Algorithm::CP::IZ::cs_end();
    $Instances--;
}

sub save_context {
    my $self = shift;
    
    my $ret = Algorithm::CP::IZ::cs_saveContext();

    my $cxt = $self->{_cxt};
    push(@$cxt, []);

    $self->backtrack(undef, 0, sub { pop(@$cxt) });

    return $ret;
}

sub restore_context {
    my $self = shift;

    my $cxt = $self->{_cxt};
    if (@$cxt == 0) {

lib/Algorithm/CP/IZ.pm  view on Meta::CPAN

  if ($rc) {
    print "ok\n";
    print "v1 = ", $v1->value, "\n";
    print "v2 = ", $v2->value, "\n";
  }
  else {
    print "fail\n";
  }

=head1 DESCRIPTION

Algorithm::CP::IZ is a simple interface of iZ-C constraint programming library.

Functions declared in iz.h are mapped to:

=over 2

=item methods of Algorithm::CP::IZ

initialize, variable constructor, most of constraints
and search related functions

=item methods of Algorithm::CP::IZ::Int

accessors of variable attributes and some relationship constraints

=back

Please refer to iZ-C reference manual to see specific meaning of methods.


=head2 SIMPLE CASE

In most simple case, this library will be used like following steps:

  # initialize
  use Algorithm::CP::IZ;
  my $iz = Algorithm::CP::IZ->new();

  # construct variables
  my $v1 = $iz->create_int(1, 9);
  my $v2 = $iz->create_int(1, 9);

  # add constraints ("v1 + v2 = 12" in this case)
  $iz->Add($v1, $v2)->Eq(12);

  # search solution
  my $rc = $iz->search([$v1, $v2]);

  # you may get "v1 = 3, v2 = 9"
  print "v1 = $v1, v2 = $v2\n";

=head1 CONSTRUCTOR

=over 2

=item new

Initialize iZ-C library (cs_init is called).
For limitation of iZ-C, living instance of Algorithm::CP::IZ must be
only one per process.

=back

=head1 METHODS

=over 2

=item create_int(INT)

Create an instance of Algorithm::CP::IZ::Int. Its domain contains INT.

=item create_int(VALUES [, NAME])

Create an instance of Algorithm::CP::IZ::Int. Its domain contains values
specified by VALUES(arrayref).

=item create_int(MIN, MAX, [, NAME])

Create an instance of Algorithm::CP::IZ::Int. Its domain is {MIN..MAX}.

=item search(VARIABLES [, PARAMS])

Try to instantiate all VARIABLES(arrayref).

PARAMS will be hashref containning following keys.

=over 2

=item FindFreeVar

FindFreeVar specifies variable selection strategy.
Choose constants from Algorithm::CP::IZ::FindFreeVar or specify your own
function as coderef here.

Most simple function will be following. (select from first)

    sub simple_find_free_var{
	my $array = shift; # VARIABLES is in parameter
	my $n = scalar @$array;

	for my $i (0..$n-1) {
	    return $i if ($array->[$i]->is_free);
	}

	return -1; # no free variable
    };

=item Criteria

Criteria specifies value selection strategy.
Specify your own function as coderef here.

    sub sample_criteria {
      # position in VARIABLES, and candidate value
      my ($index, $val) = @_;

      # first value used in search is
      # minimum value returned by criteria.
      return $val;
    };



( run in 0.838 second using v1.01-cache-2.11-cpan-5735350b133 )