Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

search_node.cc

Go to the documentation of this file.
00001 // Search Node implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001-2003 Hermann Schichl, Evgueni Petrov, Brice Pajot
00004 //
00005 // This file is part of the COCONUT API.  This library
00006 // is free software; you can redistribute it and/or modify it under the
00007 // terms of the Library GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // Library GNU General Public License for more details.
00015 
00016 // As a special exception, you may use this file as part of a free software
00017 // library without restriction.  Specifically, if other files instantiate
00018 // templates or use macros or inline functions from this file, or you compile
00019 // this file and link it with other files to produce an executable, this
00020 // file does not by itself cause the resulting executable to be covered by
00021 // the Library GNU General Public License.  This exception does not however
00022 // invalidate any other reasons why the executable file might be covered by
00023 // the Library GNU General Public License.
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()) // this is not a new delta
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()) // this is not a new delta
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   // this makes sure that the volume, which is for finite boxes
00178   // in the range [-710,710]*num_of_var, stays finite even for
00179   // thin and inifinite boxes.
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 

Generated on Tue Nov 4 01:57:58 2003 for COCONUT API by doxygen1.2.18