| Home | - | Documentation | - | Sources | - | Contributors | - | Related Links |
SExploration) implements how to walk
through the tree; for example depth-first search.SNode. An object of this class stores the
constraint system state, and is used by the
SExploration classes. It does not, however, know
about any application details - i.e., what handler is used,
which variables are enumerated, which constraints are to be
evaluated.SChoice. It deals with selecting variables to
enumerated, and evaluates constraints. If a new JCHR handler
should be enabled for search, (only) this interface must be
implemented by a new class.X,
Y and Z:
ObjectContainer vars=new ObjectContainer();
vars.add(X);
vars.add(Y);
vars.add(Z);
SChoice collector=new SCollectorChoice(vars,cs.getVariableNames(vars));
SChoice rootChoice=SFDChoice.enumeration(vars,
cs.getVariableNames(vars),0,collector,trace);
SExploration exploration=new SDepthFirstExploration(cs,rootChoice);
boolean success=SSearch.all(exploration);
System.out.println(((SCollectorChoice)collector).toBeautifulString());
This code can be used as a simple search template. For an
explanation of the classes used, see Classes
and interfaces for using search. Different search strategies
(other than depth-first) can be used too, see Branch and bound and Limited discrepancy search.
backSChoice itself, this class has two static methods
for creating different root choices for the Finite Domains
handler:
public static SChoice
enumeration(ObjectContainer vars, ObjectContainer
varNames,int curVar,SChoice continuation, boolean trace)
This method creates a choice for simple variable
enumeration (variables and their values are picked from
left to right). The parameters are:
vars: A container with all the
variables (of type java.lang.Object, see Interface JCHR - Java)
which are to be enumerated.varNames: A container with names for
the variables. It can easily be created by using
ConstraintSystem.getVariableNames(), which
takes an ObjectContainer with variables and
returns an ObjectContainer with variable
names. This is only meaningful for the
toString() and other debugging or tracing
methods and can be null if those methods
are not used.curVar: This is used internally by the
choice classes and must be 0.continuation: This is a continuation choice.trace: If this flag is
true, the constraint system is instructed
to output tracing information while running the
search.public static SChoice splitting(ObjectContainer
vars, ObjectContainer varNames,int curVar,SChoice
continuation, boolean trace,boolean pickLargest)
The parameters are exactly the same as for the enumeration method;
additionally, if pickLargest is
true, then variables are selected so that in
each node, the variable with the currently largest domain
is splitted first.
false, then the value true. It has
the following constructor:
SBoolChoice(ObjectContainer vars,ObjectContainer
varNames,int curVar,SChoice continuation,boolean trace)
The constructor parameters are exactly the same as for the
enumeration
method of the Finite Domain choice.
SCollectorChoice(ObjectContainer vars,ObjectContainer varNames)
After the search has been run, the following methods can be used:
getSolutions(): This returns an
ObjectContainer which in turn contains one
instance of ObjectContainer per
solution. These containers contain the variable bindings
for all the variables in the same order as given in the
constructor.
toBeautifulString(): This returns a
string with a beautiful representation of the
results. It optionally takes a boolean parameter, which,
if true, gives a more dense
representation.SCollectorChoice
and no further methods interesting to the user.SCollectorChoice
and SPrintChoice. A class which derives from
this base class needs to implement one single method:
abstract void run(ConstraintSystem system)
This method will be called whenever a solution is
encountered during the search and can access the
constraint system like explained in Interface JCHR - Java.
public STraceChoice(OutputStream stream,SChoice
choice)
The stream can be System.out,
for example. The instance of STraceChoice
will have exactly the same behaviour of the root choice
passed into it, but it will also output information about
the ongoing search while it runs (e.g., it shows nodes as
they are created, along with the constraint system state
and variable bindings).
public SDepthFirstExploration(ConstraintSystem
system,SChoice choice)
SSearch
This class has several static methods for actually running the search:
public static boolean first(SExploration exp)
This method looks for the first solution and stops.public static boolean all(SExploration exp)
This method looks for all solutions.public static boolean best(SExploration
exp,SBestSearchCollector coll, ConstraintSystem system)
See Branch and bound.
SBestSearchCollector continuation=new MyCollector(...);The class
MyCollector must implement the
following method:
public void addBetterConstraint(ConstraintSystem system)
This method must insert a new constraint into the constraint
system, which takes the currently "best" solution into
account and guarantees that any further solution will be
better.
For example, this class would maximize the first variable of
a list of variables:
class MaxCollector extends SBestSearchCollector
{
private Object theVariable;
MaxCollector(ObjectContainer variables,ObjectContainer variableNames)
{
super(variables,variableNames);
theVariable=variables.get(0);
}
public void addBetterConstraint(ConstraintSystem cs)
{
ObjectContainer bestSolution=getSolution();
Object value=bestSolution.get(0);
cs.addGoalConstraint(new FDLTConstraint(value,theVariable);
}
}
SSearch must be used:
boolean success=SSearch.best(exploration,continuation,cs);
public
ObjectContainer getSolution() of the continuation must be
used. It returns a list of variable bindings which corresponds
to the list of variables passed in to the constructor of
SBestSearchCollector.
ObjectContainer vars=new ObjectContainer();
vars.add(X);
vars.add(Y);
vars.add(Z);
SBestSearchCollector coll=new MaxCollector(variables,variableNames);
SChoice rootChoice=SFDChoice.enumeration(vars,
cs.getVariableNames(vars),0,collector,trace);
SExploration exploration=new SDepthFirstExploration(cs,rootChoice);
boolean success=SSearch.best(exploration,coll,cs);
System.out.println(((SBestSearchCollector)coll).toBeautifulString());
backSDiscrepancyExploration must
be used instead of SDepthFirstExploration, using
this constructor:
public SDiscrepancyExploration(ConstraintSystem
system,SChoice choice,int startingMaxDisc,int discLimit)
system: The constraint system.choice: The root choice.startingMaxDisc: This is the initially
allowed discrepancy.discLimit: This is the maximal
allowed discrepancy.
ObjectContainer vars=new ObjectContainer();
vars.add(X);
vars.add(Y);
vars.add(Z);
SChoice collector=new SCollectorChoice(vars,cs.getVariableNames(vars));
SChoice rootChoice=SFDChoice.enumeration(vars,
cs.getVariableNames(vars),0,collector,trace);
SExploration exploration=new
SDiscrepancyExploration(cs,rootChoice,0,100);
boolean success=SSearch.all(exploration);
System.out.println(((SCollectorChoice)collector).toBeautifulString());
backSDepthFirstExploration, or Branch and Bound, which
uses a custom continuation SChoice).
For details on the implementation, and an thorough explanation of
the background of JASE, please refer to the diploma thesis of JASE.
SChoiceSChoice, this class is very interesting in most
cases. See the enumeration choice of the Finite Domain
handler for an example.
Things to do when implementing a new instance of SChoice:
implements SChoice to your class.
int curVar in each instance). Also, a
continuation should be stored. for latter use in choose.
public SChoice choose(ConstraintSystem system,boolean firstChoice)
It has the following responsibilities:
firstChoice). Example (red code)
ConstraintSystem.callGoal. Example (blue code)
SChoice which will be
called by the JASE engine when the node along that edge is
entered. This choice can either be of the same class as the
current one, or can be the continuation. Example (green code)
SChoice should be as
lean and fast as possible, since it is called most often
in the search process. Take care not to create superfluous
objects in it (for example, by "recycling" instances of your
SChoice), since they just increase memory use and
garbage collection time.
SExplorationSExploration. This interface has one important
method, public SNode performOneStep()which does exactly what its name implies - perform one transition from the current node in the search tree to the next node (where the definition of "next" depends on the algorithm to be implemented). In most cases, you can use the existing (trivial) depth first implementation and modify it.
SChoice's. If you need more functionality than just
collecting the results or printing them out, then override the
abstract class SChoiceOperator and implement its
method abstract void run(ConstraintSystem system)An object of this class can be passed to any search, and the
run method will be called whenever a solution is found. See the section
on continuation choices for more
information.
back