1+ package edu .illinois .cs .cogcomp .lbjava .infer ;
2+
3+ import edu .illinois .cs .cogcomp .lbjava .classify .Score ;
4+ import org .ojalgo .optimisation .Expression ;
5+ import org .ojalgo .optimisation .ExpressionsBasedModel ;
6+ import org .ojalgo .optimisation .Optimisation ;
7+ import org .ojalgo .optimisation .Variable ;
8+
9+ public class OJalgoHook implements ILPSolver {
10+
11+ private int numvars = 0 ; // initially there are no variables in the model.
12+
13+ private int numConstraints = 0 ; // intiial number of constraints
14+
15+ private ExpressionsBasedModel model = new ExpressionsBasedModel ();
16+
17+ private String nameOfObjectiveExpression = "objective" ;
18+ private Expression objectiveFunction = model .getObjectiveExpression (); //model.addExpression(nameOfObjectiveExpression);
19+
20+ // Internal flag for keeping optimization state
21+ private boolean minimize = true ;
22+
23+ // internal variable for result of optimization
24+ private Optimisation .Result result ;
25+
26+ /**
27+ * Set bounds of variable in the specified position.
28+ *
29+ * @param colId position of the variable
30+ * @param lower domain lower bound
31+ * @param upper domain upper bound
32+ */
33+ public void setBounds (int colId , double lower , double upper ) {
34+ if (upper == Double .POSITIVE_INFINITY )
35+ model .getVariable (colId ).upper (null );
36+ else
37+ model .getVariable (colId ).upper (upper );
38+
39+ if (lower == Double .NEGATIVE_INFINITY )
40+ model .getVariable (colId ).lower (null );
41+ else
42+ model .getVariable (colId ).lower (lower );
43+ }
44+
45+ /**
46+ * Set lower bound to unbounded (infinite)
47+ *
48+ * @param colId position of the variable
49+ */
50+ public void setUnboundUpperBound (int colId ) {
51+ model .getVariable (colId ).upper (null );
52+ }
53+
54+ public void setUpperBound (int colId , double u ) {
55+ model .getVariable (colId ).upper (u );
56+ }
57+
58+ /**
59+ * Set upper bound to unbounded (infinite)
60+ *
61+ * @param colId position of the variable
62+ */
63+ public void setUnboundLowerBound (int colId ) {
64+ model .getVariable (colId ).lower (null );
65+ }
66+
67+ public void setLowerBound (int colId , double l ) {
68+ model .getVariable (colId ).lower (l );
69+ }
70+
71+ /**
72+ * Set the column/variable as an integer variable
73+ *
74+ * @param colId position of the variable
75+ */
76+ public void setInteger (int colId ) {
77+ model .getVariable (colId ).integer (true );
78+ }
79+
80+ /**
81+ * Set the column / variable as an binary integer variable
82+ *
83+ * @param colId position of the variable
84+ */
85+ public void setBinary (int colId ) {
86+ model .getVariable (colId ).binary ();
87+ }
88+
89+ /**
90+ * Set the column/variable as a float variable
91+ *
92+ * @param colId position of the variable
93+ */
94+ public void setFloat (int colId ) {
95+ model .getVariable (colId ).integer (false );
96+ }
97+
98+ public void setMaximize (boolean d ) {
99+ if (d ) {
100+ model .setMaximisation ();
101+ minimize = false ;
102+ }
103+ else {
104+ model .setMinimisation ();
105+ minimize = true ;
106+ }
107+ }
108+
109+ public int addBooleanVariable (double c ) {
110+ numvars ++;
111+ Variable var = Variable .makeBinary (Integer .toString (numvars ));
112+ model .addVariable (var );
113+ objectiveFunction .set (var , c );
114+ return numvars -1 ;
115+ }
116+
117+ public int [] addDiscreteVariable (double [] c ) {
118+ int [] varIndices = new int [c .length ];
119+ int ind = 0 ;
120+ while (ind < c .length ) {
121+ double coef = c [ind ];
122+ numvars ++;
123+ Variable var = Variable .make (Integer .toString (numvars ));
124+ var .isInteger ();
125+ model .addVariable (var );
126+ objectiveFunction .set (var , coef );
127+ varIndices [ind ] = numvars -1 ;
128+ ind ++;
129+ }
130+ return varIndices ;
131+ }
132+
133+ public int [] addDiscreteVariable (Score [] c ) {
134+ int [] varIndices = new int [c .length ];
135+ int ind = 0 ;
136+ while (ind < c .length ) {
137+ double coef = c [ind ].score ;
138+ numvars ++;
139+ Variable var = Variable .make (Integer .toString (numvars ));
140+ var .isInteger ();
141+ model .addVariable (var );
142+ objectiveFunction .set (var , coef );
143+ varIndices [ind ] = numvars -1 ;
144+ ind ++;
145+ }
146+ return varIndices ;
147+ }
148+
149+ public void addEqualityConstraint (int [] i , double [] a , double b ) {
150+ numConstraints ++;
151+ Expression constraint = model .addExpression ("EqualityConstraint: " + Integer .toString (numConstraints ));
152+ constraint .level (b );
153+ for (int ind = 0 ; ind < i .length ; ind ++) {
154+ constraint .set (i [ind ], a [ind ]);
155+ }
156+ }
157+
158+ public void addGreaterThanConstraint (int [] i , double [] a , double b ) {
159+ numConstraints ++;
160+ Expression constraint = model .addExpression ("GreaterThanConstraint: " + Integer .toString (numConstraints ));
161+ constraint .lower (b );
162+ for (int ind = 0 ; ind < i .length ; ind ++) {
163+ constraint .set (i [ind ], a [ind ]);
164+ }
165+ }
166+
167+ public void addLessThanConstraint (int [] i , double [] a , double b ) {
168+ numConstraints ++;
169+ Expression constraint = model .addExpression ("LessThanConstraint: " + Integer .toString (numConstraints ));
170+ constraint .upper (b );
171+ for (int ind = 0 ; ind < i .length ; ind ++) {
172+ constraint .set (i [ind ], a [ind ]);
173+ }
174+ }
175+
176+ // Note: oJalgo does not support pre-solving!
177+ public boolean solve () throws Exception {
178+ if (minimize )
179+ result = model .minimise ();
180+ else
181+ result = model .maximise ();
182+ if ( result .getState () == Optimisation .State .OPTIMAL )
183+ System .out .println ("Good news!: the optimizatin solution is optimal! " );
184+ if ( result .getState () == Optimisation .State .DISTINCT )
185+ System .out .println ("Good news!: the optimizatin solution is unique! " );
186+ if ( result .getState () == Optimisation .State .INFEASIBLE )
187+ System .out .println ("Warning: the optimizatin is infeasible! " );
188+ if ( result .getState () == Optimisation .State .UNBOUNDED )
189+ System .out .println ("Warning: the optimizatin is unbounded! " );
190+ if ( result .getState () == Optimisation .State .APPROXIMATE )
191+ System .out .println ("Warning: the optimizatin is approximate! " );
192+
193+ return result .getState ().isSuccess ();
194+ }
195+
196+ public boolean isSolved () {
197+ return result .getState ().isSuccess ();
198+ }
199+
200+ public boolean getBooleanValue (int index ) {
201+ if ( result .get (index ).intValue () != 1 && result .get (index ).intValue () != 0 )
202+ System .out .println ("Warning! The value of the binary variable is not 0/1! " );
203+ return (result .get (index ).intValue () == 1 );
204+ }
205+
206+ public double objectiveValue () {
207+ /** TODO(khashab2): the method `result.getValue();` doesn't return the right value. Make sure you're doing
208+ * the right thing.
209+ */
210+ double obj = 0 ;
211+ for ( Variable v : model .getVariables () )
212+ obj += objectiveFunction .get (v ).doubleValue () * v .getValue ().doubleValue ();
213+ return obj ;
214+ }
215+
216+ public void reset () {
217+ // no implementation
218+ }
219+
220+ public void write (StringBuffer buffer ) {
221+ // no implementation
222+ }
223+
224+ /**
225+ * Set a time limit for solver optimization. After the limit
226+ * is reached the solver stops running.
227+ *
228+ * @param limit the time limit
229+ */
230+ public void setTimeout (int limit ) {
231+ assert (0 <= limit );
232+ model .options .time_abort = limit ;
233+ }
234+
235+ public void printModelInfo () {
236+ System .out .println (model .toString ());
237+ }
238+ }
0 commit comments