00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00027 #include <search_node.h>
00028 #include <infeasible_delta.h>
00029
00030 work_node operator-(const work_node& _w, const delta_id& _d)
00031 {
00032 work_node _tmp(_w);
00033 std::map<delta_id,undelta>::iterator __f;
00034
00035 __f = _tmp.undeltas.find(_d);
00036 if(__f == _tmp.undeltas.end())
00037 {
00038 std::cerr << "ERROR: Cannot unapply delta <" << _d <<
00039 "> which was not previously applied to work node <" << _tmp.get_id() <<
00040 ">!";
00041 throw "Programming error: work_node -";
00042 }
00043 else
00044 {
00045 std::list<delta_id>::iterator __g, __e(_tmp.deltas.end());
00046 for(__g = _tmp.deltas.begin(); __g != __e; ++__g)
00047 if(*__g == _d)
00048 break;
00049 if(__g != __e)
00050 _tmp.deltas.erase(__g);
00051 }
00052 if(!(*__f).second.unapply(_tmp))
00053 std::cerr << "Warning: Could not unapply delta <" <<
00054 _d << "> to work node <" << _tmp.get_id() << ">!" << std::endl;
00055 else
00056 _tmp.undeltas.erase(__f);
00057 return _tmp;
00058 }
00059
00060 work_node& operator-=(work_node& _w, const delta_id& _d)
00061 {
00062 std::map<delta_id,undelta>::iterator __f;
00063
00064 __f = _w.undeltas.find(_d);
00065 if(__f == _w.undeltas.end())
00066 {
00067 std::cerr << "ERROR: Cannot unapply delta <" << _d <<
00068 "> which was not previously applied to work node <" << _w.get_id() <<
00069 ">!" << std::endl;
00070 throw "Programming error: work_node -=";
00071 }
00072 else
00073 {
00074 std::list<delta_id>::iterator __g, __e(_w.deltas.end());
00075 for(__g = _w.deltas.begin(); __g != __e; ++__g)
00076 if(*__g == _d)
00077 break;
00078 if(__g != __e)
00079 _w.deltas.erase(__g);
00080 }
00081 if(!(*__f).second.unapply(_w))
00082 std::cerr << "Warning: Could not unapply delta <" <<
00083 _d << "> to work node <" << _w.get_id() << ">!" << std::endl;
00084 else
00085 _w.undeltas.erase(__f);
00086 return _w;
00087 }
00088
00089 work_node::work_node(const search_node_id& _i, const vdbl::userid& _dui,
00090 gptr<model>& __m, gptr<vdbl::database>& __d,
00091 const std::vector<annotation>& __an,
00092 const std::list<delta_id>& __de, gptr<search_node>* _gm,
00093 search_node_relation snr) :
00094 _Base(_i, _dui, __m, _gm, __d, __an, snr),
00095 deltas(__de),
00096 undeltas(),
00097 node_ranges(),
00098 infeasible(false),
00099 gain_factor(1.),
00100 _tnum(0),
00101 proposed_splits(),
00102 n_bds(0),
00103 n_lin(0),
00104 n_quad(0),
00105 n_poly(0),
00106 n_other(0)
00107 {
00108 dtable = (vdbl::standard_table*)
00109 get_database_ptr()->get_table("deltas", get_dbuserid());
00110 if(dtable == NULL)
00111 {
00112 get_database_ptr()->create_table("deltas", get_dbuserid());
00113 dtable = (vdbl::standard_table*)
00114 get_database_ptr()->get_table("deltas", get_dbuserid());
00115 if(dtable == NULL)
00116 throw "Database inconsistency: Programming Error!";
00117 dtable_id = get_database_ptr()->get_tableid("deltas", get_dbuserid());
00118 dtable->add_col("delta",vdbl::typed_col<delta>(delta(infeasible_delta())),
00119 vdbl::colflags());
00120 vdbl::colid _c_id(dtable->get_col_id("delta"));
00121 dtable->add_col("action",
00122 vdbl::method_col<delta_get_action>(delta_get_action(_c_id)),
00123 vdbl::colflags(true));
00124 }
00125 make_node_ranges(false);
00126 init_cnumbers();
00127 }
00128
00129 void work_node::init_cnumbers()
00130 {
00131 model::walker _c;
00132 int h = (**_m).constraints.size();
00133 n_bds = n_lin = n_quad = n_poly = n_other = 0;
00134 for(int i = 0; i < h; ++i)
00135 {
00136 _c = (**_m).constraints[i];
00137 if(_c->is(ex_bound))
00138 n_bds++;
00139 else if(_c->is(ex_linear))
00140 n_lin++;
00141 else if(_c->is(ex_quadratic))
00142 n_quad++;
00143 else if(_c->is(ex_polynomial))
00144 n_poly++;
00145 else
00146 n_other++;
00147 }
00148 log_vol = compute_log_volume(node_ranges);
00149 }
00150
00151 void work_node::make_node_ranges(bool keep_old_ranges)
00152 {
00153 unsigned int n = (**_m).number_of_nodes();
00154 if(n > node_ranges.size())
00155 {
00156 node_ranges.reserve(n);
00157 node_ranges.insert(node_ranges.end(), n-node_ranges.size(),
00158 interval(-INFINITY,INFINITY));
00159 }
00160 for(unsigned int i = 0; i < n; ++i)
00161 {
00162 if((**_m).node(i) != (**_m).ground())
00163 {
00164 if(!keep_old_ranges || node_ranges[i].is_entire())
00165 node_ranges[i] = (**_m).node(i)->f_bounds;
00166 }
00167 else
00168 node_ranges[i] = interval(-INFINITY,INFINITY);
00169 }
00170 }
00171
00172 #define MAX_VOL_COMP 1.e12
00173 #define MIN_VOL_WIDTH DBL_MIN
00174
00175 double work_node::compute_log_volume(const std::vector<interval>& _r) const
00176 {
00177
00178
00179
00180 unsigned int n = (**_m).number_of_variables();
00181 double lv(0);
00182 double help;
00183
00184 for(unsigned int i = 0; i < n; ++i)
00185 {
00186 const interval& nds(_r[(**_m).var(i)->node_num]);
00187 if(nds.is_bounded())
00188 {
00189 help = nds.width();
00190 if(help < MIN_VOL_WIDTH)
00191 lv -= MAX_VOL_COMP;
00192 else
00193 lv += log(help);
00194 }
00195 else
00196 lv += MAX_VOL_COMP;
00197 }
00198 return lv;
00199 }
00200