[gecode-users] Gecode BAB Questions
Dean Hiller
hiller at employees.org
Thu Mar 28 17:18:43 CET 2013
I am very new to constraint programming, but by using the MPG have been
able to develop a fairly large Gecode application in a relatively
short period of time. Due to my lack of constraint programming
knowledge, I may not have selected the best methods for solving
my particular problem, but what I have done appears to work
with two exceptions which are shown in the attached program.
This program is the minimum program I could generate to show
what I am doing and to replicate my two problems.
In the attached program, I have an IntVar X which is to
receive ordered values from Y0, Y1, and Y2 along with an
indication of from which Y the value came.
The first problem I am having is that the program stops
after finding 6 of the 10 possible solutions and I don't
understand how to debug this problem.
The second problem I am having is that the program fails
to find any solutions if the constraints on one of the
Y variables results in it not having any solutions even
though there are other solutions for X.
I have this problem with both the 3.7.3 release and the
4.0.0 release.
I would appreciate any assistance you can provide.
Thanks,
Dean
#include <gecode/int.hh>
#include <gecode/search.hh>
#include <gecode/minimodel.hh>
using namespace Gecode;
typedef struct Y_s
{
IntVar nY;
} Y;
class GecodeTest3 : public Space {
protected:
int m_nMin;
int m_nMax;
int m_nNumY;
IntVar m_nX;
IntVarArray m_naX;
BoolVarArray m_baX;
int m_nYIndex;
IntVar m_nY0;
IntVar m_nY1;
IntVar m_nY2;
IntVar *m_vY[3];
IntVar m_nCost;
IntVarArray m_nValue;
IntArgs m_nC;
public:
void AddY(int* naY, int nSize)
{
m_nYIndex++;
*m_vY[m_nYIndex] = IntVar(*this, m_nMin, m_nMax);
ConstrainY(naY, nSize);
rel(*this, m_naX[m_nYIndex] == *m_vY[m_nYIndex]);
rel(*this, m_baX[m_nYIndex] == (m_naX[m_nYIndex] == m_nX));
branch(*this, *m_vY[m_nYIndex], INT_VAL_MIN());
}
void ConstrainY(int *naY, int nSize)
{
IntArgs nTemp;
for (int i = 0; i < nSize; i++)
{
nTemp << naY[i];
}
IntSet nsTemp(nTemp);
dom(*this, *m_vY[m_nYIndex], nsTemp);
}
int GetX(void)
{
return m_nX.val();
}
int GetWhichY(void)
{
return m_nValue[0].val();
}
int GetCost(void)
{
return m_nCost.val();
}
GecodeTest3(int nMin, int nMax, int nNumY) :
m_nMin(nMin), m_nMax(nMax), m_nNumY(nNumY), m_nYIndex(-1)
{
if (m_nMin < 0)
{
std::cout << "m_nMin must not be negative" << std::endl;
}
m_vY[0] = &m_nY0;
m_vY[1] = &m_nY1;
m_vY[2] = &m_nY2;
m_nX = IntVar(*this, m_nMin, m_nMax);
m_naX = IntVarArray(*this, m_nNumY, m_nMin, m_nMax);
m_baX = BoolVarArray(*this, m_nNumY, 0, 1);
m_nC << 1;
m_nC << m_nNumY;
int nTemp = m_nNumY * m_nMax + m_nNumY;
m_nCost = IntVar(*this, 0, nTemp);
nTemp = m_nMax > nNumY ? m_nMax : nNumY;
m_nValue = IntVarArray(*this, 2, 0, nTemp);
rel(*this, m_nX == min(m_naX));
element(*this, m_baX, m_nValue[0], 1);
rel(*this, m_nValue[1] == m_nX);
linear(*this, m_nC, m_nValue, IRT_EQ, m_nCost);
branch(*this, m_naX, INT_VAR_MIN_MIN(), INT_VAL_MIN());
branch(*this, m_nX, INT_VAL_MIN());
branch(*this, m_nValue[0], INT_VAL_MIN());
}
// search support
GecodeTest3(bool share, GecodeTest3& s) : Space(share, s) {
// s.print(std::cout);
m_vY[0] = &m_nY0;
m_vY[1] = &m_nY1;
m_vY[2] = &m_nY2;
m_nX.update(*this, share, s.m_nX);
m_naX.update(*this, share, s.m_naX);
m_baX.update(*this, share, s.m_baX);
m_nCost.update(*this, share, s.m_nCost);
m_nY0.update(*this, share, s.m_nY0);
m_nY1.update(*this, share, s.m_nY1);
m_nY2.update(*this, share, s.m_nY2);
m_nValue.update(*this, share, s.m_nValue);
for (int i = 0; i < 2; i++)
{
m_nC << s.m_nC[i];
}
}
virtual Space* copy(bool share) {
return new GecodeTest3(share,*this);
}
virtual void constrain(const Space& _b)
{
const GecodeTest3& b = static_cast<const GecodeTest3&>(_b);
rel(*this, m_nCost > b.m_nCost);
}
// print solution
void print(std::ostream& os) const {
os << "m_nX: " << m_nX << std::endl;
for (int i = 0; i < m_naX.size(); i++)
{
os << "m_naX[" << i << "]: " << m_naX[i] << " ";
os << "m_baX[" << i << "]: " << m_baX[i] << " ";
os << std::endl;
}
for (int i = 0; i < m_nC.size(); i++)
{
os << "m_nC[" << i << "]: " << m_nC[i] << std::endl;
}
for (int i = 0; i < m_nValue.size(); i++)
{
os << "m_nValue[" << i << "]: " << m_nValue[i] << std::endl;
}
os << "m_nCost: " << m_nCost << std::endl;
}
};
void BuildAndSolve(bool b2Y1)
{
int Y0[3] = {1, 3, 7};
int Y1[3] = {2, 4, 5};
int Y2[4] = {4, 6, 8, 9};
int Y1a[3] = {1, 3, 8};
// create model and search engine
GecodeTest3 *m = new GecodeTest3(0, 20, 3);
m->AddY(Y0, sizeof(Y0)/sizeof(int));
m->AddY(Y1, sizeof(Y1)/sizeof(int));
if (b2Y1)
{
m->ConstrainY(Y1a, sizeof(Y1a)/sizeof(int));
}
m->AddY(Y2, sizeof(Y2)/sizeof(int));
// m->print(std::cout);
bool bFailed = true;
BAB<GecodeTest3> e(m);
GecodeTest3 *s;
while (((s = e.next()) != 0))
{
bFailed = false;
// s->print(std::cout);
int X = s->GetX();
int whichY = s->GetWhichY();
int nCost = s->GetCost();
std::cout << "X=" << X << " from Y" << whichY << ". Cost=" << nCost <<
std::endl;
// std::cout << std::endl;
delete s;
}
if (bFailed)
{
std::cout << "Model failed" << std::endl;
}
Search::Statistics stat = e.statistics();
std::cout << "Search Statistics" << std::endl;
std::cout << " Propagations: " << stat.propagate << std::endl;
std::cout << " Nodes: " << stat.node << std::endl;
std::cout << " Failures: " << stat.fail << std::endl;
std::cout << " Depth: " << stat.depth << std::endl;
int nPeakMemoryKB = static_cast<int>((stat.memory+1023) / 1024);
std::cout << " Peak Memory " << nPeakMemoryKB << "KB" << std::endl;
std::cout << std::endl;
delete m;
return;
}
int GecodeTest3Main(int argc, char* argv[])
{
std::cout << "One Y1 constraint" << std::endl;
BuildAndSolve(false);
std::cout << "Two Y1 constraints" << std::endl;
BuildAndSolve(true);
return 0;
}
Sample output:
One Y1 constraint
X=1 from Y0. Cost=3
X=2 from Y1. Cost=7
X=3 from Y0. Cost=9
X=4 from Y1. Cost=13
X=4 from Y2. Cost=14
X=5 from Y1. Cost=16
Search Statistics
Propagations: 149
Nodes: 21
Failures: 5
Depth: 3
Peak Memory 8KB
Two Y1 constraints
Model failed
Search Statistics
Propagations: 0
Nodes: 0
Failures: 1
Depth: 0
Peak Memory 4KB
More information about the users
mailing list