CouenneOrbitObj.cpp
Go to the documentation of this file.
1 /* $Id: CouenneOrbitObj.cpp 490 2011-01-14 16:07:12Z pbelotti $
2  *
3  * Name: CouenneOrbitObj.cpp
4  * Authors: Jim Ostrowski, University of Waterloo
5  * Pietro Belotti, Lehigh University
6  * Purpose: Base object for variables (to be used in branching)
7  *
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 /*
12 #include "CoinHelperFunctions.hpp"
13 #include "CoinFinite.hpp"
14 
15 #include "CouenneProblem.hpp"
16 #include "CouenneOrbitObj.hpp"
17 #include "CouenneBranchingObject.hpp"
18 
19 #include "CouenneExprGroup.hpp"
20 using namespace Couenne;
21 
22 void Node::node(int i, double c , double l, double u, int cod){
23  index = i;
24  coeff = c;
25  lb = l;
26  ub = u;
27  color = -1;
28  code = cod;
29 }
30 void Node::color_vertex(int k){
31  color = k;
32  }
33 
34 bool compare (Node a, Node b){
35  if(a.get_code() == b.get_code() )
36  if(a.get_coeff() == b.get_coeff() )
37  if(a.get_lb() == b.get_lb())
38  if(a.get_ub() == b.get_ub())
39  return 1;
40  return 0;
41  }
42 
43 bool node_sort (Node a, Node b){
44  bool is_less = 0;
45 
46  if(a.get_code() < b.get_code() )
47  is_less = 1;
48  else if(a.get_code() == b.get_code() )
49  if(a.get_coeff() < b.get_coeff() )
50  is_less = 1;
51  else if(a.get_coeff() == b.get_coeff() )
52  if(a.get_lb() < b.get_lb())
53  is_less = 1;
54  else if(a.get_lb() == b.get_lb())
55  if(a.get_ub() < b.get_ub())
56  is_less = 1;
57  else if(a.get_index() < b.get_index())
58  is_less = 1;
59 
60  return is_less;
61 }
62 bool index_sort (Node a, Node b){
63  return (a.get_index() < b.get_index() );
64 }
65 
66 
67 
68 
69 
71 CouenneOrbitObj::CouenneOrbitObj ():
72 
73  CouenneObject () {}
74 
75 CouenneOrbitObj::CouenneOrbitObj (CouenneCutGenerator *cutgen,
76  CouenneProblem *p,
77  exprVar *ref,
78  Bonmin::BabSetupBase *base,
79  JnlstPtr jnlst):
80  CouenneObject (cutgen, p, ref, base, jnlst){
81 
82 // // Find Coefficients
83 
85 
86  int num_affine = 0;
87 
88  for (std::vector <exprVar *>:: iterator i = p -> Variables (). begin ();
89  i != p -> Variables (). end (); ++i) {
90 
91  if ((*i) -> Type () == AUX) {
92  if ((*i) -> Image () -> code () != COU_EXPRGROUP) {
93  if ((*i) -> Image () -> Type () == N_ARY) {
94  for (int a=0; a < (*i) -> Image () -> nArgs(); a++) {
95  expression *arg = (*i) -> Image () -> ArgList () [a];
96 
97  if (arg -> Type () == CONST) {
98  num_affine ++;
99 
100  }
101  }
102  }
103  }
104  if ((*i) -> Image () -> code () == COU_EXPRGROUP) {
105 
106  exprGroup *e = dynamic_cast <exprGroup *> ((*i) -> Image ());
107 
108  // add a node for e -> getC0 ();
109  if (e -> getc0 () != 0 ){
110  num_affine ++;
111  }
112 
113  // for each term add nodes for their non-one coefficients and their variable
114 
115  for (exprGroup::lincoeff::iterator el = e ->lcoeff().begin (); el != e -> lcoeff ().end (); ++el) {
116  if ( el -> second !=1){
117  num_affine ++;
118  }
119  }
120  }
121  }
122  }
123 
124 
125 
126 
127 
128 
129  // Create global Nauty object
130 
131  int nc = num_affine + p-> nVars ();
132  printf (" There are %d coefficient vertices in the graph \n", num_affine);
133  printf (" Graph has %d vertices \n", nc);
134 
135 
136  nauty_info = new Nauty(nc);
137 
138  // create graph
139 
140  int coef_count= p-> nVars ();
141  for (std::vector <exprVar *>:: iterator i = p -> Variables (). begin ();
142  i != p -> Variables (). end (); ++i) {
143 
144  // printf ("I have code %d \n", (*i) -> Image() -> code() );
145 
146 
147 
148  if ((*i) -> Type () == AUX) {
149  printf ("aux is %d with code %d \n", (*i) -> Index (), (*i) -> Image () -> code() );
150  // this is an auxiliary variable
151 
152  Node vertex;
153  vertex.node( (*i) -> Index () , 0.0 , (*i) -> lb () , (*i) -> ub () , (*i) -> Image () -> code() );
154  node_info.push_back( vertex);
155 
156  // add node in nauty graph for its index, (*i) -> Index ()
157 
158  if ((*i) -> Image () -> Type () == N_ARY) {
159 
160  if ((*i) -> Image () -> code () != COU_EXPRGROUP) {
161 
162  for (int a=0; a < (*i) -> Image () -> nArgs(); a++) {
163  expression *arg = (*i) -> Image () -> ArgList () [a];
164 
165  if (arg -> Type () != CONST) {
166  printf (" add edge %d , %d\n", (*i) -> Index (), arg -> Index ());
167  nauty_info->addElement((*i) -> Index (), arg -> Index ());
168  nauty_info->addElement( arg -> Index (), (*i) -> Index ());
169  }
170 
171  else{
172 
173  assert (arg -> Type () == CONST);
174 
175  printf (" add new vertex to graph, coef # %d, value %g \n", coef_count, arg -> Value() );
176  printf (" add edge aux index %d , coef index %d\n", (*i) -> Index (), coef_count);
177  nauty_info->addElement((*i) -> Index (), coef_count);
178  nauty_info->addElement( coef_count, (*i) -> Index ());
179 
180 
181  Node coef_vertex;
182  coef_vertex.node( coef_count, arg -> Value(), arg -> Value() , arg -> Value(), -2 );
183  node_info.push_back(coef_vertex);
184  coef_count ++;
185  }
186 
187  }
188  }
189 
190 
191  if ((*i) -> Image () -> code () == COU_EXPRGROUP) {
192 
193  // dynamic_cast it to an exprGroup
194 
195  exprGroup *e = dynamic_cast <exprGroup *> ((*i) -> Image ());
196 
197  // add a node for e -> getC0 ();
198  if (e -> getc0 () != 0 ){
199  Node coef_vertex;
200  coef_vertex.node( coef_count, e -> getc0(), e -> getc0() , e -> getc0(), -2 );
201  node_info.push_back(coef_vertex);
202 
203  printf ("Add coef vertex to graph (coef value %f) \n", e -> getc0 () );
204  printf (" add edge aux index %d , coef index %d\n", (*i) -> Index (), coef_count);
205  nauty_info->addElement((*i) -> Index (), coef_count);
206  nauty_info->addElement( coef_count, (*i) -> Index ());
207 
208 
209  coef_count ++;
210  }
211 
212  // for each term add nodes for their non-one coefficients and their variable
213 
214  for (exprGroup::lincoeff::iterator el = e ->lcoeff().begin (); el != e -> lcoeff ().end (); ++el) {
215 
216  if ( el -> second ==1){
217  printf (" add edge index %d , index %d\n", (*i) -> Index (), el -> first -> Index() );
218  nauty_info->addElement((*i) -> Index (), el -> first -> Index());
219  nauty_info->addElement( el -> first -> Index (), (*i) -> Index ());
220  }
221  else{
222  printf (" add new vertex to graph, coef # %d with coef %f \n", coef_count, el -> second);
223  Node coef_vertex;
224  coef_vertex.node( coef_count, el -> second, el -> second, el -> second, -2 );
225  node_info.push_back(coef_vertex);
226 
227  printf (" add edge aux index %d , coef index %d\n", (*i) -> Index (), coef_count);
228  nauty_info->addElement((*i) -> Index (), coef_count);
229  nauty_info->addElement( coef_count, (*i) -> Index ());
230 
231  printf (" add edge coef index %d , 2nd index %d\n", coef_count, el -> first -> Index() );
232  nauty_info->addElement(coef_count, el -> first -> Index());
233  nauty_info->addElement( el -> first -> Index (), coef_count);
234  coef_count ++;
235  }
236  // coefficient = el -> second
237 
238  // variable index is el -> first -> Index ()
239  }
240 
241  }
242 
243  } else if ((*i) -> Image () -> Type () == UNARY) {
244 
245  }
246 
247  } else {
248  // printf ("variable is %d\n", (*i) -> Index ());
249  Node var_vertex;
250  var_vertex.node( (*i) -> Index () , 0 , (*i) -> lb () , (*i) -> ub () , -1 );
251  // printf( "var info index %d, coef %f, lb %f, ub %f, code %d \n", var_vertex.get_index() , var_vertex.get_coeff() , var_vertex.get_lb() , var_vertex.get_ub() , var_vertex.get_code() );
252  node_info.push_back(var_vertex);
253  // this is an original variable
254 
255  }
256  }
257 
258 }
259 
260 
262 CouenneOrbitObj::CouenneOrbitObj (exprVar *ref,
263  Bonmin::BabSetupBase *base,
264  JnlstPtr jnlst):
265 
266  CouenneObject (ref, base, jnlst) {}
267 
268 
270 CouenneOrbitObj::CouenneOrbitObj (const CouenneOrbitObj &src):
271  CouenneObject (src) {}
272 
273 
275 OsiBranchingObject *CouenneOrbitObj::createBranch (OsiSolverInterface *si,
276  const OsiBranchingInformation *info,
277  int way) const {
278 
279  return NULL;
280 }
281 
282 
283 
284 
285 
286 // set point at current LP solution
287 double CouenneOrbitObj::feasibleRegion (OsiSolverInterface*, const OsiBranchingInformation*) const {
288  return 0;
289 }
290 
291 
292 
294 double CouenneOrbitObj::infeasibility (const OsiBranchingInformation *info, int &way) const {
295 
296  return 0;
297 }
298 
299 
303 double CouenneOrbitObj::checkInfeasibility (const OsiBranchingInformation *info) const {
304 
305  return 0;
306 
307 }
308 
309 void CouenneOrbitObj::Compute_Symmetry(){
310  sort(node_info. begin (), node_info. end (), node_sort);
311 
312  int color = 1;
313  for (std::vector <Node>:: iterator i = node_info. begin ();
314  i != node_info. end (); ++i) {
315  if( (*i).get_color() == -1){
316  (*i).color_vertex(color);
317  printf ("Graph vertex %d is given color %d\n", (*i).get_index(), color);
318  nauty_info -> color_node((*i).get_index(), color);
319  for (std::vector <Node>:: iterator j = i+1; j <= node_info. end (); ++j)
320  if( compare( (*i) , (*j) ) ==1){
321  (*j).color_vertex(color);
322  nauty_info -> color_node((*j).get_index(),color);
323  printf ("Graph vertex %d is given color %d, the same as vertex %d\n", (*j).get_index(), color, (*i).get_index());
324  }
325  // else
326  // j = node_info. end();
327  color++;
328 
329  }
330  }
331 
332  nauty_info -> computeAuto();
333 }
334 
335 void CouenneOrbitObj::Print_Orbits(){
336 
337  printf("num gens = %d, num orbits = %d \n", nauty_info -> getNumGenerators(), nauty_info -> getNumOrbits() );
338 
339  std::vector<std::vector<int> > new_orbits = nauty_info->getOrbits();
340 
341  printf("There were %d orbits and %d generators\n",
342  nauty_info->getNumOrbits(),
343  nauty_info->getNumGenerators());
344 
345  for (unsigned int i = 0; i < new_orbits.size(); i++) {
346  printf( "Orbit %d [", i);
347  copy(new_orbits[i].begin(), new_orbits[i].end(),
348  std::ostream_iterator<int>(std::cout, " "));
349  printf("] \n");
350  }
351 
352 
353 
354 }
355 
356 
357 
358 void CouenneOrbitObj::ChangeBounds (CouenneProblem * p ){
359  sort(node_info. begin (), node_info. end (), index_sort);
360 
361  for (std::vector <exprVar *>:: iterator i = p->Variables (). begin ();
362  i != p->Variables (). end (); ++i) {
363  node_info[(*i)->Index() ].bounds ( (*i) -> lb () , (*i) -> ub () );
364 
365  }
366 
367 
368 }
369 */