0

我正在寻找一种在GecodeSpace中复制实例的方法,然后再分析空间之间的差异。

但是,在第一次复制后它已经出错了。当一个人复制Gecode 中的建模和编程一书中的代码时,如下所示,并简单地修改它以便首先复制 ( SendMoreMoney* smm = m->copy(true);),无论选项是还是,都会出现Segmentation faultsharedtruefalse

#include <gecode/int.hh>
#include <gecode/search.hh>

using namespace Gecode;

class SendMoreMoney : public Space {
protected:
  IntVarArray l;
public:
  SendMoreMoney(void) : l(*this, 8, 0, 9) {
    IntVar s(l[0]), e(l[1]), n(l[2]), d(l[3]),
           m(l[4]), o(l[5]), r(l[6]), y(l[7]);
    // no leading zeros
    rel(*this, s, IRT_NQ, 0);
    rel(*this, m, IRT_NQ, 0);
    // all letters distinct
    distinct(*this, l);
    // linear equation
    IntArgs c(4+4+5); IntVarArgs x(4+4+5);
    c[0]=1000; c[1]=100; c[2]=10; c[3]=1;
    x[0]=s;    x[1]=e;   x[2]=n;  x[3]=d;
    c[4]=1000; c[5]=100; c[6]=10; c[7]=1;
    x[4]=m;    x[5]=o;   x[6]=r;  x[7]=e;
    c[8]=-10000; c[9]=-1000; c[10]=-100; c[11]=-10; c[12]=-1;
    x[8]=m;      x[9]=o;     x[10]=n;    x[11]=e;   x[12]=y;
    linear(*this, c, x, IRT_EQ, 0);
    // post branching
    branch(*this, l, INT_VAR_SIZE_MIN(), INT_VAL_MIN());
  }
  // search support
  SendMoreMoney(bool share, SendMoreMoney& s) : Space(share, s) {
    l.update(*this, share, s.l);
  }
  virtual SendMoreMoney* copy(bool share) {
    return new SendMoreMoney(share,*this);
  }
  // print solution
  void print(void) const {
    std::cout << l << std::endl;
  }
};

// main function
int main(int argc, char* argv[]) {
  // create model and search engine
  SendMoreMoney* m = new SendMoreMoney;
  SendMoreMoney* mc = m->copy(true);
  DFS<SendMoreMoney> e(m);
  delete m;
  // search and print all solutions
  while (SendMoreMoney* s = e.next()) {
    s->print(); delete s;
  }
  return 0;
}

怎样才能制作出真正的副本?

4

3 回答 3

1

我在 Gecode 邮件列表档案中找到了这个交换:https ://www.gecode.org/users-archive/2006-March/000439.html

看起来,在内部,Gecode 将复制函数和构造函数用于其内部目的,因此要制作空间的“按值复制”副本,您需要使用 Space 接口中定义的 clone() 函数。但是,如@Anonymous 回答中所述,您需要在调用 clone 之前调用 status() ,否则它将引发类型异常SpaceNotStable

我用下面的函数扩充了我的空间来自动调用状态,进行克隆,并返回我的派生类型的指针:

struct Example : public Space {
    ...
    Example * cast_clone() {
        status();
        return static_cast<Example *>(this->clone());
    }
    ...
}
于 2019-06-20T23:44:45.950 回答
1

你必须先打电话status()Space

于 2015-12-02T10:58:47.140 回答
0

作为一种解决方法,可以创建一个完全独立的空间,然后在变量级别使用等式约束来减少这些变量的域。

例子:

void cloneHalfValues(SendMoreMoney* origin) {
    int n = l.size();
    for(int i = 0x00; i < n/2; i++) {
        if(origin->l[i].assigned()) {
            rel(*this, l[i], IRT_EQ, origin->l[i].val());
        }
    }
}

然而,为什么不能克隆 a 的原因Space仍然是一个谜。

于 2014-11-12T09:49:21.753 回答