Thanks for the fast answer. I tried decomposing the last constraint into
mul, sqr and linear rules, but i got the same result. I attached the code. I
compiled it by doing
g++ parallelepiped.cpp -lgecodeminimodel -lgecodeint -lgecodesearch
-lgecodegist -lgecodedriver -o parallelepiped
-- Javier Romero --


On Fri, Aug 20, 2010 at 2:58 PM, Guido Tack <[email protected]> wrote:

> Javier Romero wrote:
>
> > Hi,
> > I'm a newbie in Gecode, but in the first stages of trying it i've found
> something that puzzles me. After writing a program with a set of highly
> nonlinear constraints which includes the following constraint (apart from
> others)
> >
> >     IntVar k = expr(*this, 2*x0*x1*x2);
> >     IntVar kc01= (*this,x2*(sqr(x0)+sqr(x1)-sqr(d01min)));
> >     IntVar kc02= (*this,x1*(sqr(x0)+sqr(x2)-sqr(d02min)));
> >     IntVar kc12= (*this,x0*(sqr(x2)+sqr(x1)-sqr(d12min)));
> >     rel(*this,k*(sqr(kc01)+sqr(kc02)+sqr(kc12)) <
> (k*k*k+2*kc01*kc02*kc12));
> >
> >  i get an output like this:
> [...]
> > That is, it returns inmediately with no solution. However, the problem
> has a solution, and actually it finds it by commenting the last lined of the
> code posted above (by chance; the constraint is actually necessary). This is
> how the output looks when the solution is found:
> [...]
> > I tested manually (and with a python script) that the solution obtained
> is compliant with the constraint that was removed. So i wonder if there is a
> limitation on the level of the nonlinearities in Gecode (i think it's
> unlikely), in the number of constraints (also unlikely) or what else could
> have happened. The code is basically an adaptation of SMM example to my
> arithmetic constraints. I can post it if necessary.
>
> If you could give me a small example that I can compile and run, I can have
> a look.  The code for posting non-linear expressions is relatively new, and
> there may be bugs that our test suite has not found.
>
> One thing you could try is to decompose the constraints (in particular the
> last line) manually, i.e. not use anything from minimodel.hh, but declare
> temporary IntVars and then only use the mult, linear, and sqr functions from
> int.hh.  If that works, then it's definitely a problem in how minimodel
> decomposes the constraint.
>
> Cheers,
>        Guido
>
> --
> Guido Tack, http://people.cs.kuleuven.be/~guido.tack/
>
>
#include <gecode/driver.hh>
#include <gecode/int.hh>
#include <gecode/search.hh>
#include <gecode/minimodel.hh>
#include <gecode/gist.hh>

using namespace Gecode;
static const double minRange = 100;
static const double maxRange = 400;


class Parallelepiped : public Space {
    protected:
        IntVarArray lengths;
        IntVarArray kcosines;
    public:
        // i could constrain more the ranges of kcosines and further tmp variables, 
        // but it doesn't affect much the running time and i want to be sure that's not what's creating the bug
        Parallelepiped(const Options &opt=0) : lengths(*this, 13, minRange, maxRange), kcosines(*this,4,Int::Limits::min,Int::Limits::max){
            IntVar x0(lengths[0]), x1(lengths[1]), x2(lengths[2]),
                   d01min(lengths[3]),d01maj(lengths[4]),d02min(lengths[5]),d02maj(lengths[6]),d12min(lengths[7]),d12maj(lengths[8]),
                   m0(lengths[9]),m1(lengths[10]),m2(lengths[11]),m3(lengths[12]);
            IntVar k(kcosines[0]),kc01(kcosines[1]),kc02(kcosines[2]),kc12(kcosines[3]);

            // x0 >= x1 >= x2
            rel(*this, x0 >= x1);
            rel(*this, x1 >= x2);
            // parallelepiped x0x1 is perfect
            rel(*this, d01min > x0-x1);
            rel(*this, sqr(d01min) <= sqr(x0)+sqr(x1));
            rel(*this, 2*sqr(x0)+2*sqr(x1)-sqr(d01min)-sqr(d01maj) == 0);
            // parallelepiped x0x2 is perfect
            rel(*this, d02min > x0-x2);
            rel(*this, sqr(d02min) <= sqr(x2)+sqr(x0));
            rel(*this, 2*sqr(x2)+2*sqr(x0)-sqr(d02min)-sqr(d02maj) == 0);
            // parallelepiped x1x2 is perfect
            rel(*this, d12min > x1-x2);
            rel(*this, sqr(d12min)<= sqr(x2)+sqr(x1));
            rel(*this, 2*sqr(x2)+2*sqr(x1)-sqr(d12min)-sqr(d12maj) == 0);
            // inner diagonal m1 is an integer
            rel(*this, sqr(m0) == (-sqr(x0))+sqr(x1)+sqr(x2)+sqr(d01min)+sqr(d02min)+(-sqr(d12min)));
            rel(*this, sqr(m1)== sqr(x0)+(-sqr(x1))+sqr(x2)+sqr(d01min)+(-sqr(d02min))+sqr(d12min));
            rel(*this, sqr(m2) == sqr(x0)+sqr(x1)+(-sqr(x2))+(-sqr(d01min))+sqr(d02min)+sqr(d12min));
            rel(*this, sqr(m3) == 3*(sqr(x0)+sqr(x1)+sqr(x2))-(sqr(d01min)+sqr(d02min)+sqr(d12min)));

            // Setting those fixed variables with expr instead of rel makes the code return immediately 
            //    k = expr(*this, 2*x0*x1*x2);
            //    kc01 = expr(*this,x2*(sqr(x0)+sqr(x1)-sqr(d01min)));
            //    kc02 = expr(*this,x1*(sqr(x0)+sqr(x2)-sqr(d02min)));
            //    kc12 = expr(*this,x0*(sqr(x2)+sqr(x1)-sqr(d12min)));
            rel(*this, k==2*x0*x1*x2);
            rel(*this, kc01==x2*(sqr(x0)+sqr(x1)-sqr(d01min)));
            rel(*this, kc02==x1*(sqr(x0)+sqr(x2)-sqr(d02min)));
            rel(*this, kc12==x0*(sqr(x2)+sqr(x1)-sqr(d12min)));

#define MINIMODEL
#ifdef MINIMODEL
            // This constraint makes the code return immediately; if commented a solution which is compliant to it is returned!
            rel(*this,k*(sqr(kc01)+sqr(kc02)+sqr(kc12)) < (k*k*k+2*kc01*kc02*kc12));
#else
            // And this set of constraints (equiv to the previous one) makes it crashes equally
            // Even just the first constraint sqr makes it crash
            IntVarArray tmp(*this,7,Int::Limits::min,Int::Limits::max);
            IntVarArray lin(*this,5,Int::Limits::min,Int::Limits::max);
            IntVar kc01kc01(tmp[0]),kc02kc02(tmp[1]),kc12kc12(tmp[2]),kk(tmp[3]),kc01kc02(tmp[4]),kc01kc02kc12(tmp[5]),kkk(tmp[6]);
            IntVar _kkk(lin[0]),_2kc01kc02kc12(lin[1]),kkc01kc01(lin[2]),kkc02kc02(lin[3]),kkc12kc12(lin[4]);
            IntVar _one = expr(*this,-1);
            IntVar _two = expr(*this,-2);
            sqr(*this,kc01,kc01kc01);
            mult(*this,kc01kc01,k,kkc01kc01);
            sqr(*this,kc02,kc02kc02);
            mult(*this,kc02kc02,k,kkc02kc02);
            sqr(*this,kc12,kc12kc12);
            mult(*this,kc12kc12,k,kkc12kc12);
            sqr(*this,k,kk);
            mult(*this,kk,k,kkk);
            mult(*this,kkk,_one,_kkk);
            mult(*this,kc01,kc02,kc01kc02);
            mult(*this,kc01kc02,kc12,kc01kc02kc12);
            mult(*this,kc01kc02kc12,_two,_2kc01kc02kc12);
            linear(*this,lin,IRT_LE,0);
#endif


            // rel branching
            branch(*this, lengths, INT_VAR_SIZE_MIN, INT_VAL_MIN);
        }
        // search support
        Parallelepiped(bool share, Parallelepiped& s) : Space(share, s) {
            lengths.update(*this, share, s.lengths);
            kcosines.update(*this, share, s.kcosines);
        }
        virtual Space* copy(bool share) {
            return new Parallelepiped(share,*this);
        }
        // print solution
        void print(std::ostream& os) const {
            os << lengths << std::endl;
            os << kcosines << std::endl;
        }
        void print(void) const {
            std::cout << lengths << std::endl;
            std::cout << kcosines << std::endl;
        }
        void compare(const Space& s, std::ostream& os) const {
            os << Gist::Comparator::compare<IntVar>("lengths",lengths,
                    static_cast<const Parallelepiped&>(s).lengths);
        }

};

// main function
int main(int argc, char* argv[]) {
    Options opt("Parallelepiped");
    opt.parse(argc,argv);
    Script::run<Parallelepiped,DFS,Options>(opt);
    return 0;

    //  Parallelepiped* m = new Parallelepiped;
    //  DFS<Parallelepiped> e(m);
    //  delete m;
    //  // search and print all solutions
    //  while (Parallelepiped* s = e.next()) {
    //    s->print(); delete s;
    //  }
    //  return 0;

    //  Parallelepiped* m = new Parallelepiped;
    //  Gist::dfs(m);
    //  delete m;
    //  return 0;
}
_______________________________________________
Gecode users mailing list
[email protected]
https://www.gecode.org/mailman/listinfo/gecode-users

Reply via email to