home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tlx501.zip
/
SRC
/
CSPREP.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-08
|
12KB
|
363 lines
/****************************************************************************
$Id: csprep.cpp 501.0 1995/03/07 12:26:12 RON Exp $
Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
Project: Tarma Library for C++ V5.0
Author: Ron van der Wal
Implementation of class TLCSProblemRep, the standard problem
representation class for CSPs.
$Log: csprep.cpp $
Revision 501.0 1995/03/07 12:26:12 RON
Updated for TLX 5.01
Revision 1.14 1995/02/22 12:35:44 RON
Update for release 012
Added partial support for SunPro C++ compiler
Revision 1.13 1995/01/16 12:24:43 ron
Added subproblem parameter to varselectors
Revision 1.12 1995/01/13 15:32:09 ron
Moved a number of processing steps to the subproblem
Revision 1.11 1995/01/12 13:39:07 ron
Adapted to previous Searcher/ProblemRep model
Revision 1.10 1995/01/10 16:32:03 ron
Added warning when no variables are created
Revision 1.9 1995/01/08 11:43:55 ron
Renamed TLCSProblem to TLCSSubProblem
Revision 1.8 1995/01/06 15:56:46 ron
Adapted to new Searcher/Problem model
Revision 1.7 1995/01/05 15:22:53 ron
Added TLVarSelector classes
Brought inline with thesis
Revision 1.6 1994/11/16 15:37:52 ron
Added module info; rearranged #include directives
Revision 1.5 1994/10/13 11:50:46 ron
Changed strategy names slightly
Added |C|/(|D|^2) strategy
Revision 1.4 1994/10/11 19:02:46 ron
Replaced DeadEnd() + SolveProblem() by ProcessProblem()
Revision 1.3 1994/10/10 16:47:51 ron
Added dead-end detection, preprocess check, and implementation
of selection strategies
Revision 1.2 1994/10/07 17:05:52 ron
Implemented various selection strategies
Revision 1.1 1994/10/05 18:43:06 ron
Initial revision
****************************************************************************/
#include <tlx\501\_build.h>
TLX_MODULE_INFO("$Revision: 501.0 $");
#include <iostream.h>
#include <tlx\501\log.h>
#include <tlx\501\solve\stdcsp.h>
//----- Template source code
#include <tlx\501\template\ptrseq.cpp>
/*-------------------------------------------------------------------------*/
TLCSProblemRep::TLCSProblemRep()
/* Constructor.
---------------------------------------------------------------------------*/
: mVars(100,100), mFreeVars()
{
mPropagator = 0;
mVarSelector = 0;
mVars.BecomeOwner(true); // Will delete variables
}
/*-------------------------------------------------------------------------*/
void TLCSProblemRep::EnterState(TLProblemState *aProblem)
/* Implements the processing step required from problem representation
classes. The variable assignment is performed.
---------------------------------------------------------------------------*/
{
TLX_TRACE(TLX, (55, "CSProblemRep: EnterState"));
TLCSProblemState *csproblem = DYNACAST(TLCSProblemState *, aProblem);
TLX_ASSERT_PTR(csproblem);
TLX_ASSERT_PTR(csproblem->Var());
// Remove the variable from the set of free variables
TLX_ASSERT(mFreeVars.Contains(csproblem->Var()));
mFreeVars.Extract(csproblem->Var());
// Before the assignment takes place, save the current domain. After the
// assignment, capturing is activated; this remains in effect until the
// corresponding LeaveState().
TLX_ASSERT(csproblem->Var()->IsActive());
csproblem->SaveDomain();
csproblem->AssignVariable();
csproblem->StartCapturing();
}
/*-------------------------------------------------------------------------*/
size_t TLCSProblemRep::GenerateBranches(
TLProblemState * aParent,
TLProblemList & aList)
/* Called to decompose the given subproblem, which will act as the parent
for the new branches. If there are no free variables, this function
returns false, else it calls SelectVariable() to select the next
variable and CreateBranches() to create the branches for that variable.
---------------------------------------------------------------------------*/
{
TLX_TRACE(TLX, (55, "CSProblemRep: GenerateBranches"));
if (mFreeVars.IsEmpty())
return 0;
TLCSProblemState *csproblem = DYNACAST(TLCSProblemState *, aParent);
TLX_ASSERT(!aParent || csproblem);
TLVariable *var = SelectVariable(csproblem);
if (!var)
{
TLX_TRACE_WARN(TLX, ("No variable selected from free variables"));
return false;
}
return CreateBranches(csproblem, var, aList);
}
/*-------------------------------------------------------------------------*/
void TLCSProblemRep::LeaveState(TLProblemState *aProblem)
/* Called after processing of the subproblem has been completed. This
version uses the information captured by the underlying CSProblem to
undo the changes that were made during the processing.
---------------------------------------------------------------------------*/
{
TLX_TRACE(TLX, (55, "CSProblemRep: LeaveState"));
TLCSProblemState *csproblem = DYNACAST(TLCSProblemState *, aProblem);
TLX_ASSERT_PTR(csproblem);
TLX_ASSERT_PTR(csproblem->Var());
// Undo changes to all domains captured by this subproblem and
// reactivate the constraints on the variable. The order is the
// exact opposite of the processing order.
csproblem->Var()->ActivateConstraints();
csproblem->DoneVariable();
csproblem->StopCapturing();
csproblem->RestoreDomains();
TLX_ASSERT(csproblem->Var()->IsActive());
// Return the variable to the set of free variables
TLX_ASSERT(!mFreeVars.Contains(csproblem->Var()));
mFreeVars.Append(csproblem->Var());
}
/*-------------------------------------------------------------------------*/
bool TLCSProblemRep::PreProcess()
/* Preprocessing step. Initializes the list of free variables. If derived
classes override this function, they should call this version as part
of their own preprocessing.
---------------------------------------------------------------------------*/
{
TLX_TRACE(TLX, (55, "CSProblemRep: PreProcess"));
if (!TLProblemRep::PreProcess())
return false;
// Discard previous set of variables, if any
mVars.RemoveAll();
// Let the derived class create the set of variables
if (!CreateVariables())
return false;
mFreeVars = mVars;
// Perform initial propagation
return PreProcessVariables();
}
/*-------------------------------------------------------------------------*/
bool TLCSProblemRep::PreProcessVariables()
/* Substep of general preprocessing: preprocesses all variables that were
created earlier. By default, this function applies the propagation
strategy object to the set of all variables.
---------------------------------------------------------------------------*/
{
TLX_TRACE(TLX, (55, "CSProblemRep: PreProcessVariables"));
if (mPropagator)
{
TLX_LOG_ENTRY("Preprocessing all variables");
#ifdef __IBMCPP__
TLPtrSeqIter<TLVariable> it(mVars);
bool result = mPropagator->Propagate(it);
#else
bool result = mPropagator->Propagate(TLPtrSeqIter<TLVariable>(mVars));
#endif
TLPropagator::Stats stats;
mPropagator->GetStats(stats);
TLX_LOG_ENTRY("Propagation completed; %ld checks", stats.mCheckCount);
return result;
}
else
return true;
}
/*-------------------------------------------------------------------------*/
ostream &TLCSProblemRep::PrintOn(ostream &os) const
/* Prints the current state of the problem representation.
---------------------------------------------------------------------------*/
{
os << mVars.Count() << " variables (" << mFreeVars.Count()
<< " still free):\n";
for (index_t i = mVars.Mini(); i <= mVars.Maxi(); ++i)
{
TLVariable *var = mVars.PeekAt(i);
if (var)
{
os << *var;
if (mFreeVars.Contains(var))
os << " -- Free";
os << "\n";
}
else
os << "*** NULL variable ***\n";
}
ReportStats(os);
return os;
}
/*-------------------------------------------------------------------------*/
bool TLCSProblemRep::Process(TLProblemState *aProblem)
/* Implements the processing step required from problem representation
classes. Constraint propagation with a consistency check.
---------------------------------------------------------------------------*/
{
TLX_TRACE(TLX, (55, "CSProblemRep: Process"));
TLCSProblemState *csproblem = DYNACAST(TLCSProblemState *, aProblem);
TLX_ASSERT_PTR(csproblem);
TLX_ASSERT_PTR(csproblem->Var());
// Perform propagation-like processing, first locally, then globally.
bool result = csproblem->ProcessVariable() && Propagate(csproblem);
// Deactivate the constraints emanating from the variable
csproblem->Var()->DeactivateConstraints();
return result;
}
/*-------------------------------------------------------------------------*/
bool TLCSProblemRep::Propagate(TLCSProblemState *aProblem)
/* Checks the consistency of the system after the given variable has been
assigned. This implementation uses the currently installed propagator
(if any). It assumes that domain capturing has been activated elsewhere.
---------------------------------------------------------------------------*/
{
TLX_TRACE(TLX, (55, "CSProblemRep: Propagate"));
TLX_ASSERT_PTR(aProblem);
if (mPropagator)
return mPropagator->Propagate(aProblem->Var());
else
{
// If there are no more free variables, we must test the complete
// assignment. In that case, it is unwise to rely on this version
// if there is no propagator.
if (mFreeVars.IsEmpty())
TLX_TRACE_WARN(TLX, ("No consistency check after instantiation"));
return true;
}
}
/*-------------------------------------------------------------------------*/
TLVariable *TLCSProblemRep::SelectVariable(TLCSProblemState *aProblem)
/* Selects the next variable to explore as the branches of the given
parent subproblem. It applies the selection strategy that is
currently set and returns a pointer to the selected variable. The
variable is *not* removed from the list of free variables.
If there is no selection strategy, the first free variable is selected.
---------------------------------------------------------------------------*/
{
TLX_TRACE(TLX, (55, "CSProblemRep: SelectVariable"));
if (mFreeVars.IsEmpty())
return 0;
else if (mVarSelector)
return mVarSelector->SelectVariable(aProblem, this, mFreeVars);
else
return mFreeVars.PeekFirst();
}
/*-------------------------------------------------------------------------*/
TLPropagator *TLCSProblemRep::SetPropagator(TLPropagator *aProp)
/* Installs a new propagation strategy object and returns the previous one.
---------------------------------------------------------------------------*/
{
if (!aProp)
TLX_TRACE_WARN(TLX, ("NULL propagation strategy installed"));
TLPropagator *old = mPropagator;
mPropagator = aProp;
return old;
}
/*-------------------------------------------------------------------------*/
TLVarSelector *TLCSProblemRep::SetVarSelector(TLVarSelector *aSelect)
/* Installs a new variable selection strategy and returns the previous one.
---------------------------------------------------------------------------*/
{
if (!aSelect)
TLX_TRACE_WARN(TLX, ("NULL selection strategy installed"));
TLVarSelector *old = mVarSelector;
mVarSelector = aSelect;
return old;
}