gecode中自定义brancher

实际应用中,往往要比官方的示例复杂很多,这里对变量的选择等往往需要以自定义的方式进行选择,这个时候就需要自定义brancher,相关注释在代码中

#include <gecode/int.hh>

using namespace Gecode;

class NoneMin : public Brancher {
protected:
  ViewArray<Int::IntView> x;
  // choice definition
  class PosVal : public Choice {
  public:
    int pos; int val;
    PosVal(const NoneMin& b, int p, int v)
      : Choice(b,2), pos(p), val(v) {}
    virtual size_t size(void) const {
      return sizeof(*this);
    }
    virtual void archive(Archive& e) const {
      Choice::archive(e);
      e << pos << val;
    }
  };
public:
  NoneMin(Home home, ViewArray<Int::IntView>& x0)
    : Brancher(home), x(x0) {}
  static void post(Home home, ViewArray<Int::IntView>& x) {
    (void) new (home) NoneMin(home,x);
  }
  virtual size_t dispose(Space& home) {
    (void) Brancher::dispose(home);
    return sizeof(*this);
  }
  NoneMin(Space& home, bool share, NoneMin& b)
    : Brancher(home,share,b) {
    x.update(home,share,b.x);
  }
  virtual Brancher* copy(Space& home, bool share) {
    return new (home) NoneMin(home,share,*this);
  }
  // status 选择某个变量,有时有些变量需要有优处理,这时可以在这个地方选择
  virtual bool status(const Space& home) const {
    for (int i=0; i<x.size(); i++)
      if (!x[i].assigned())
        return true;
    return false;
  }
  // choice 通过这个函数取得choice
  virtual Choice* choice(Space& home) {
    for (int i=0; true; i++)
      if (!x[i].assigned())
        return new PosVal(*this,i,x[i].min());
    GECODE_NEVER;
    return NULL;
  }
  virtual Choice* choice(const Space&, Archive& e) {
    int pos, val;
    e >> pos >> val;
    return new PosVal(*this, pos, val);
  }
  // commit
  virtual ExecStatus commit(Space& home,
                            const Choice& c,
                            unsigned int a) {
    const PosVal& pv = static_cast<const PosVal&>(c);
    int pos=pv.pos, val=pv.val;
    if (a == 0) //这里对应的一个节点的两个分支,左边的节点为付值,右边的节点为排除。
      return me_failed(x[pos].eq(home,val)) ? ES_FAILED : ES_OK;
    else
      return me_failed(x[pos].nq(home,val)) ? ES_FAILED : ES_OK;
  }
  // print
  virtual void print(const Space& home, const Choice& c,
                     unsigned int a,
                     std::ostream& o) const {
    const PosVal& pv = static_cast<const PosVal&>(c);
    int pos=pv.pos, val=pv.val;
    if (a == 0)
      o << "x[" << pos << "] = " << val;
    else
      o << "x[" << pos << "] != " << val;
  }
};
void nonemin(Home home, const IntVarArgs& x) {
  if (home.failed()) return;
  ViewArray<Int::IntView> y(home,x);
  NoneMin::post(home,y);
}

commit函数在worker中被调用

  void
  Space::_commit(const Choice& c, unsigned int a) {
    if (a >= c.alternatives())
      throw SpaceIllegalAlternative("Space::commit");
    if (failed())
      return;
    if (Brancher* b = brancher(c.bid)) {
      // There is a matching brancher
      pc.p.ei.brancher(*b);
      ExecStatus es = b->commit(*this,c,a);
      pc.p.ei.other();
      if (es == ES_FAILED)
        fail();
    } else {
      // There is no matching brancher!
      throw SpaceNoBrancher("Space::commit");
    }
  }

  

时间: 2024-10-10 06:40:20

gecode中自定义brancher的相关文章

vue中自定义指令

在vue中自定义标签,首先要调用vue中一个directive的方法,具体方法:Vue.direction('指令名称',function(){ }); 例如我们要写一个关于颜色的指令,叫v-colorred: 1 Vue.directive('colorred',function(){ 2 3 this.el.style.color='red'; 4 }); 在html中,我直接用v-colorred指令就可以了,例如: 1 <p v-colorred>1234567890</p>

在Tableau中自定义版块地图 (Polygon)

在Tableau的地图报表中有一个‘Filed Map’的类型,可以根据版块来显示数据. 但实际应用中Tableau固有的版块划分可能不是我们想要的,下面介绍如何自定义版块并且用作数据分析. 自定义版块 在Tableau中自定义版块是非常容易的.如下图我们把每个点链接起来就是一个多边形的版块 上面的经纬度就不用说了.State 是我们版块的名字.其中Point Order告诉Tableau链接的顺序. Polygon ID 用来指定各个闭合的区域.如下图,State 都叫Michigan,由两块

linux中自定义回收站

myrm(){ D=/tmp/$(date +%Y%m%d%H%M%S); mkdir -p $D; mv "[email protected]" $D && echo "moved to $D ok"; } [[email protected] test]# myrm(){ D=/tmp/$(date +%Y%m%d%H%M%S); mkdir -p $D;  mv "[email protected]" $D &&am

PB中自定义事件ID含义

PB中自定义事件ID含义 单选或多选按钮消息(前缀:pbm_bm) pbm_bmgetcheck 单选按钮或多选按钮是否被选. pbm_bmgetstate 按钮是否加亮. pbm_bmsetcheck 将无线按钮或确认框的选中状态改为未选中状态,反之亦然. pbm_bmsetstate 加亮或不加亮按钮. pbm_bmchange 改变按钮的风格,例如,改为单选按钮或组合框. 单选或多选按钮通知消息(前缀:pbm_bn) pbm_bnclicked 按钮控件被点中. pbm_bndisable

对NSArray中自定义的对象进行排序

本文译自How to sort NSArray with custom objects. 我们开发的每个程序都会使用到一些数据,而这些数据一般被封装在一个自定义的类中.例如一个音乐程序可能会有一个Song类,聊天程序则又一个Friend类,点菜程序会有一个Recipe类等.有时候我们希望在程序中显示的列表数据是按照一定顺序进行排列的,本文我们就来看看在iOS中有哪些方法可以对NSArray中的对象进行排序.下面是目录: 小引 使用NSComparator进行排序 使用NSDescriptor进行

iOS开发中自定义字体的方法

http://www.cnblogs.com/iyou/archive/2014/05/25/3751669.html 1. 首先下载你想要设置的字体库,例如设置方正启体简体 2. 添加到工程,一定要注意勾选红色框框处,默认是不勾选的  添加以后 3.在plist文件中添加 4.现在已经添加成功了,但是要使用就必须知道FontName,用以下代码可查到 NSArray *familyNames = [[NSArray alloc] initWithArray:[UIFont familyName

在.net桌面程序中自定义鼠标光标

有的时候,一个自定义的鼠标光标能给你的程序增色不少.本文这里介绍一下如何在.net桌面程序中自定义鼠标光标.由于.net的桌面程序分为WinForm和WPF两种,这里分别介绍一下. WinForm程序 对于WinForm程序,可以通过修改Control.Cursor属性来实现光标的修改,如果我们有光标文件的话,可以直接通过如下代码实现自定义光标: this.Cursor = new Cursor("myCursor.cur"); 但这种方式不是本文介绍的重点,本文主要介绍如何自己绘制光

Android中自定义下拉样式Spinner

Android中自定义下拉样式Spinner 本文继续介绍android自定义控件系列,自定义Spinner控件的使用. 实现思路 1.定义下拉控件布局(ListView及子控件布局) 2.自定义SpinerPopWindow类 3.定义填充数据的Adapter 效果图 一.定义控件布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http:/

Android中自定义View的MeasureSpec使用

有时,Android系统控件无法满足我们的需求,因此有必要自定义View.具体方法参见官方开发文档:http://developer.android.com/guide/topics/ui/custom-components.html 一般来说,自定义控件都会去重写View的onMeasure方法,因为该方法指定该控件在屏幕上的大小. protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) onMeasure传