00001
00002
00003
00004
00005
00006
00007 #ifndef DECOMP_H
00008 #define DECOMP_H
00009
00010 #include "standard.h"
00011 #include "usermatrix.h"
00012 #include "problem.h"
00013
00014 class DecompGraph {
00020 friend ostream& operator<<(ostream& out, const DecompGraph& g);
00021
00022 public:
00023 class Edge;
00024 class Node {
00025 friend class DecompGraph;
00026 private:
00027 int set_component(int comp);
00028 public:
00029 map<int, set<Edge>::iterator> adj;
00030 int weight;
00031 int component;
00032
00033 Node(int weight_=0)
00034 : weight(weight_), component(-1)
00035 { }
00036 };
00037
00038 class Edge {
00039 public:
00040 map<int, Node>::iterator node1, node2;
00041 mutable int weight;
00042
00043 Edge(int weight_=0)
00044 : weight(weight_)
00045 { }
00046
00047 Edge(map<int, Node>::iterator node1_, map<int, Node>::iterator node2_, int weight_=0)
00048 : node1(node1_), node2(node2_), weight(weight_)
00049 { }
00050
00055
00056
00057
00058
00059 Node& neighbour(const Node& node) const {
00060 return (&node==&node1->second) ? node2->second : node1->second;
00061 }
00062
00063 bool operator<(const Edge& e) const {
00064 return pair<int,int>(node1->first, node2->first)<pair<int,int>(e.node1->first, e.node2->first);
00065 }
00066 };
00067
00068 map<int, Node> nodes;
00069 set<Edge> edges;
00070
00071 int nrcomp;
00072
00076 DecompGraph()
00077 : nrcomp(0)
00078 { }
00079
00080 DecompGraph(const SparsityInfo& si);
00081
00082 virtual ~DecompGraph() { }
00083
00084 map<int, Node>::iterator add_node(int index, int weight=0);
00085
00086 set<Edge>::iterator add_edge(map<int, Node>::iterator node1, map<int, Node>::iterator node2, int weight=0);
00087 set<Edge>::iterator add_edge(int node1, int node2, int weight=0);
00088
00092 int n() const { return nodes.size(); }
00093
00097 int m() const { return edges.size(); }
00098
00099 void compute_connected_components();
00100
00101 void get_component_members(vector<list<int> >& members);
00102
00103 void compute_partition(int nparts);
00104 };
00105
00108 class SplitFunc: public Func {
00109 private:
00112 const Pointer<Func> orig;
00113
00116 ivector indices;
00117
00120 mutable dvector point;
00121
00122 Func::CurvatureType curv_type;
00123
00124 public:
00127 vector<bool> ignore;
00128
00135 SplitFunc(const Pointer<Func>& orig_, const ivector& indices_, const dvector& point_, const vector<int>& ignore_=vector<int>(0))
00136 : Func(indices_.dim()), orig(orig_), indices(indices_), point(point_), curv_type(orig_->get_curvature()), ignore(indices_.dim(), false)
00137 { assert(orig!=NULL);
00138 for (vector<int>::const_iterator it(ignore_.begin()); it!=ignore_.end(); it++) ignore[*it]=true;
00139 }
00140
00141 SplitFunc(const Pointer<Func>& orig_, const ivector& indices_, const dvector& point_, const set<int>& ignore_, Pointer<SparsityInfo> si=NULL)
00142 : Func(indices_.dim()), orig(orig_), indices(indices_), point(point_), curv_type(orig_->get_curvature()), ignore(indices_.dim(), false)
00143 { assert(orig!=NULL);
00144 for (set<int>::const_iterator it(ignore_.begin()); it!=ignore_.end(); ++it) ignore[*it]=true;
00145 sparsity=si;
00146 }
00147
00151 void set_point(const UserVector<double>& x) const {
00152 for (int i=0; i<indices.size(); i++)
00153 if (!ignore[i]) point[indices[i]]=x(i);
00154 }
00155
00156 double eval(const UserVector<double>& x) const {
00157 set_point(x);
00158 return orig->eval(point);
00159 }
00160
00161
00162 void grad(UserVector<double>& g, const UserVector<double>& x) const {
00163 set_point(x);
00164 dvector biggrad(orig->dim());
00165 orig->grad(biggrad, point);
00166 g=biggrad(indices);
00167 for (int i=0; i<indices.size(); i++)
00168 if (ignore[i]) g[i]=0.;
00169 }
00170
00171 using Func::grad;
00172
00173 void HessMult(UserVector<double>& y, const UserVector<double>& x, const UserVector<double>& z) const {
00174 set_point(z);
00175
00176 dvector big_x(point);
00177 for (int i=0; i<indices.size(); i++)
00178 if (!ignore[i]) big_x.SetElement(indices[i], x(i));
00179
00180 dvector bighess(orig->dim());
00181 orig->HessMult(bighess, big_x, point);
00182 y=bighess(indices);
00183 }
00184
00185 using Func::HessMult;
00186
00187 #ifdef FILIB_AVAILABLE
00188 bool is_interval_compliant() const { return orig->is_interval_compliant(); }
00189
00190 void set_point(IntervalVector& bigx, const IntervalVector& x) const {
00191 for (int i=0; i<indices.size(); i++)
00192 if (!ignore[i]) bigx[indices[i]]=x(i);
00193 }
00194
00195 interval<double> eval(const IntervalVector& x) const {
00196 IntervalVector bigx(point);
00197 set_point(bigx, x);
00198 return orig->eval(bigx);
00199 }
00200
00201 void grad(IntervalVector& g, const IntervalVector& x) const {
00202 IntervalVector bigx(point);
00203 set_point(bigx, x);
00204 IntervalVector biggrad(bigx.dim());
00205 orig->grad(biggrad, bigx);
00206 for (int i=0; i<indices.size(); i++)
00207 g[i] = ignore[i] ? interval<double>(0.) : biggrad(indices[i]);
00208 }
00209
00210 int valgrad(interval<double>& val, IntervalVector& y, const IntervalVector& x) const {
00211 IntervalVector bigx(point);
00212 set_point(bigx, x);
00213 IntervalVector biggrad(bigx.dim());
00214 int ret=orig->valgrad(val, biggrad, bigx);
00215 for (int i=0; i<indices.size(); i++)
00216 y[i] = ignore[i] ? interval<double>(0.) : biggrad(indices[i]);
00217 return ret;
00218 }
00219
00220 using Func::valgrad;
00221 #endif
00222
00223 virtual void set_curvature(CurvatureType ct) { curv_type=ct; };
00224 virtual CurvatureType get_curvature() const { return curv_type; };
00225
00226 void print(ostream& out) const;
00227 };
00228
00229
00230 class SplittingScheme2 {
00231 public:
00236 vector<list<pair<int, int> > > new_pos;
00237
00240 vector<ivector> newblock;
00241
00242 SplittingScheme2(const DecompGraph& graph);
00243 };
00244
00258 class Decomposition {
00259 private:
00262 bool replace_if_quadratic;
00263
00266 int avg_blocksize;
00267
00270 Pointer<Param> param;
00271
00272 public:
00273 Pointer<set<int> > I_var;
00274
00278 Decomposition(Pointer<Param> param_=NULL)
00279 : param(param_), replace_if_quadratic(param_ ? param_->get_i("Decomposition replace quadratic", 1) : 1),
00280 avg_blocksize(param_ ? param_->get_i("Decomposition average blocksize", 5) : 5)
00281 { }
00282
00283
00284 void set_sparsity_pattern(MinlpProblem& prob, const vector<vector<dvector> >& sample_set);
00285
00286
00297 Pointer<MinlpProblem> decompose(MinlpProblem& prob, vector<vector<dvector> >& sample_set);
00298
00299 Pointer<MinlpProblem> decompose(MinlpProblem& prob, vector<Pointer<SplittingScheme2> >& ss);
00300 void decompose(SepQcFunc& f, int block_offset, const SepQcFunc& old_f, int k, const SplittingScheme2& ss, Pointer<dvector> primal);
00301
00302 Pointer<SplittingScheme2> get_splittingscheme(MinlpProblem& prob, int blocknr);
00303
00304 Pointer<SepQcFunc> decompose(Pointer<Func> old_f, const dvector& primal);
00305 };
00306
00307 #endif