1 /* $Id$
2  *
3  * Name:    CouenneRestoreUnused.cpp
4  * Authors: Pietro Belotti, Lehigh University
5  * Purpose: Restore a consistent value of duplicate variables
6  *
7  * This file is licensed under the Eclipse Public License (EPL)
8  */
9 
10 #include "CouenneProblem.hpp"
11 #include "CouenneExprVar.hpp"
12 
13 using namespace Couenne;
14 
15 /// Some originals may be unused due to their zero multiplicity
16 /// (that happens when they are duplicates). This procedure creates
17 /// a structure for quickly checking and restoring their value after
18 /// solving.
createUnusedOriginals()19 void CouenneProblem::createUnusedOriginals () {
20 
21   if (nUnusedOriginals_ < 0) { // no structure yet, identify and store
22 
23     nUnusedOriginals_ = 0;
24 
25     int
26       nOrig = nOrigVars (),
27       nvars = nVars     ();
28 
29     unusedOriginalsIndices_ = (int *) malloc (nvars * sizeof (int)); // will trim it later
30 
31     for (int i=0; i<nvars; i++) {
32 
33       int indVar = numbering_ [i];
34 
35       if ((indVar < nOrig) &&
36 	  (variables_ [indVar] -> Multiplicity () <= 0)) // found neglected variable!
37 	unusedOriginalsIndices_ [nUnusedOriginals_++] = indVar;
38     }
39 
40     if (nUnusedOriginals_)
41       unusedOriginalsIndices_ = (int *) realloc (unusedOriginalsIndices_,
42 						 nUnusedOriginals_ * sizeof (int));
43     else {
44       free (unusedOriginalsIndices_);
45       unusedOriginalsIndices_ = NULL;
46     }
47   }
48 }
49 
50 
51 /// Some originals may be unused due to their zero multiplicity (that
52 /// happens when they are duplicates). This procedure restores their
53 /// value after solving
restoreUnusedOriginals(CouNumber * x) const54 void CouenneProblem::restoreUnusedOriginals (CouNumber *x) const {
55 
56   if (nUnusedOriginals_ <= 0) return;
57 
58   if (x)
59     domain_.push (nVars(), x,
60 		  domain_. current () -> lb (),
61 		  domain_. current () -> ub (), false); // no need for another copy
62 
63   for (int i=0; i<nUnusedOriginals_; i++) {
64 
65     int indVar = unusedOriginalsIndices_ [i];
66     expression *img = variables_ [indVar] -> Image ();
67 
68     if (img) {
69 
70       CouNumber value = (*img) ();
71 
72       X (indVar) = value;
73 
74       if (x)
75 	x [indVar] = value;
76     }
77   }
78 
79   if (x)
80     domain_. pop ();
81 }
82