source: trunk/Cbc/test/CInterfaceTest.c @ 2089

Last change on this file since 2089 was 2089, checked in by mlubin, 5 years ago

include stdlib.h for malloc(), thanks Victor Zverovich

File size: 9.6 KB
Line 
1/* $Id$ */
2/* Copyright (C) 2014, International Business Machines
3   Corporation and others.  All Rights Reserved.
4   This code is licensed under the terms of the Eclipse Public License (EPL). */
5
6#undef NDEBUG /* force asserts to work */
7#include "Cbc_C_Interface.h"
8#include <assert.h>
9#include <math.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14
15static int callback_called = 0;
16
17void (COINLINKAGE_CB test_callback)(Cbc_Model * model,int  msgno, int ndouble,
18                            const double * dvec, int nint, const int * ivec,
19                            int nchar, char ** cvec) {
20
21    callback_called = 1;
22    printf("In callback: message %d\n", msgno);
23
24}
25
26
27void testKnapsack() {
28
29    Cbc_Model *model = Cbc_newModel();
30
31    /* Simple knapsack problem
32       Maximize  5x[1] + 3x[2] + 2x[3] + 7x[4] + 4x[5]
33       s.t.      2x[1] + 8x[2] + 4x[3] + 2x[4] + 5x[5] <= 10
34       All x binary
35       */
36   
37    CoinBigIndex start[] = {0, 1, 2, 3, 4, 5, 6};
38    int rowindex[] = {0, 0, 0, 0, 0};
39    double value[] = {2, 8, 4, 2, 5};
40    double collb[] = {0,0,0,0,0};
41    double colub[] = {1,1,1,1,1};
42    double obj[] = {5, 3, 2, 7, 4};
43    double feasible[] = {1,1,0,0,0};
44    double rowlb[] = {-INFINITY};
45    double rowub[] = {10};
46    const double *sol;
47    const char* setname = "test model";
48    char *getname = malloc(20);
49    int i;
50
51    printf("Interface reports Cbc version %s\n", Cbc_getVersion());
52
53    Cbc_loadProblem(model, 5, 1, start, rowindex, value, collb, colub, obj, rowlb, rowub);
54
55    Cbc_setColName(model, 2, "var2");
56    Cbc_setRowName(model, 0, "constr0");
57
58
59    assert(Cbc_getNumCols(model) == 5);
60    assert(Cbc_getNumRows(model) == 1);
61
62    for (i = 0; i < 5; i++) {
63        Cbc_setInteger(model, i);
64        assert(Cbc_isInteger(model,i));
65    }
66
67    Cbc_setObjSense(model, -1);
68    assert(Cbc_getObjSense(model) == -1);
69
70    Cbc_setProblemName(model, setname);
71
72    Cbc_registerCallBack(model, test_callback);
73
74    Cbc_setInitialSolution(model, feasible);
75
76    Cbc_solve(model);
77
78    assert(Cbc_isProvenOptimal(model));
79    assert(!Cbc_isAbandoned(model));
80    assert(!Cbc_isProvenInfeasible(model));
81    assert(!Cbc_isContinuousUnbounded(model));
82    assert(!Cbc_isNodeLimitReached(model));
83    assert(!Cbc_isSecondsLimitReached(model));
84    assert(!Cbc_isSolutionLimitReached(model));
85    assert(fabs( Cbc_getObjValue(model)- (16.0) < 1e-6));
86    assert(fabs( Cbc_getBestPossibleObjValue(model)- (16.0) < 1e-6));
87
88    assert(callback_called == 1);
89   
90    sol = Cbc_getColSolution(model);
91   
92    assert(fabs(sol[0] - 1.0) < 1e-6);
93    assert(fabs(sol[1] - 0.0) < 1e-6);
94    assert(fabs(sol[2] - 0.0) < 1e-6);
95    assert(fabs(sol[3] - 1.0) < 1e-6);
96    assert(fabs(sol[4] - 1.0) < 1e-6);
97
98    Cbc_problemName(model, 20, getname);
99    i = strcmp(getname,setname);
100    assert( (i == 0) );
101
102    Cbc_getColName(model, 2, getname, 20);
103    i = strcmp(getname, "var2");
104    assert( (i == 0) );
105    Cbc_getRowName(model, 0, getname, 20);
106    i = strcmp(getname, "constr0");
107    assert( (i == 0) );
108    assert( Cbc_maxNameLength(model) >= 7 );
109   
110    Cbc_deleteModel(model);
111
112}
113
114/*
115void testProblemModification() {
116
117    Cbc_Model *model = Cbc_newModel();
118
119    / * Simple knapsack problem
120       Maximize  5x[1] + 3x[2] + 2x[3] + 7x[4] + 4x[5]
121       s.t.      2x[1] + 8x[2] + 4x[3] + 2x[4] + 5x[5] <= 10
122       All x binary
123       * /
124   
125    CoinBigIndex start[] = {0, 1, 2, 3, 4, 5, 6};
126    int rowindex[] = {0, 0, 0, 0, 0};
127    double value[] = {2, 8, 4, 2, 5};
128    double collb[] = {0,0,0,0,0};
129    double colub[] = {1,1,1,1,1};
130    double obj[] = {5, 3, 2, 7, 4};
131    double rowlb[] = {-INFINITY};
132    double rowub[] = {10};
133    const double *sol;
134    int i;
135
136    printf("Interface reports Cbc version %s\n", Cbc_getVersion());
137
138    Cbc_loadProblem(model, 5, 1, start, rowindex, value, collb, colub, obj, rowlb, rowub);
139
140    for (i = 0; i < 5; i++) {
141        Cbc_setInteger(model, i);
142        assert(Cbc_isInteger(model,i));
143    }
144
145    Cbc_setObjSense(model, -1);
146    assert(Cbc_getObjSense(model) == -1);
147
148    Cbc_solve(model);
149
150    assert(Cbc_isProvenOptimal(model));
151    assert(fabs( Cbc_getObjValue(model)- (16.0) < 1e-6));
152
153    sol = Cbc_getColSolution(model);
154   
155    assert(fabs(sol[0] - 1.0) < 1e-6);
156    assert(fabs(sol[1] - 0.0) < 1e-6);
157    assert(fabs(sol[2] - 0.0) < 1e-6);
158    assert(fabs(sol[3] - 1.0) < 1e-6);
159    assert(fabs(sol[4] - 1.0) < 1e-6);
160
161    Cbc_setColUpper(model, 0, 0.0);
162    Cbc_solve(model);
163
164    assert(Cbc_isProvenOptimal(model));
165    assert(fabs( Cbc_getObjValue(model)- (11.0) < 1e-6));
166
167    sol = Cbc_getColSolution(model);
168   
169    assert(fabs(sol[0] - 0.0) < 1e-6);
170    assert(fabs(sol[1] - 0.0) < 1e-6);
171    assert(fabs(sol[2] - 0.0) < 1e-6);
172    assert(fabs(sol[3] - 1.0) < 1e-6);
173    assert(fabs(sol[4] - 1.0) < 1e-6);
174
175
176    Cbc_setColLower(model, 1, 1.0);
177
178    assert(Cbc_isProvenOptimal(model));
179    assert(fabs( Cbc_getObjValue(model)- (10.0) < 1e-6));
180
181    sol = Cbc_getColSolution(model);
182   
183    assert(fabs(sol[0] - 0.0) < 1e-6);
184    assert(fabs(sol[1] - 1.0) < 1e-6);
185    assert(fabs(sol[2] - 0.0) < 1e-6);
186    assert(fabs(sol[3] - 1.0) < 1e-6);
187    assert(fabs(sol[4] - 0.0) < 1e-6);
188
189   
190    Cbc_deleteModel(model);
191
192}
193*/
194
195
196void testSOS() {
197
198    Cbc_Model *model = Cbc_newModel();
199
200    /*
201       Maximize  5x[1] + 3x[2] + 2x[3] + 7x[4] + 4x[5]
202       s.t.       x[1] +  x[2] +  x[3] +  x[4] +  x[5] == 1
203       All x binary
204       */
205   
206    CoinBigIndex start[] = {0, 0, 0, 0, 0, 0, 0};
207    double collb[] = {0,0,0,0,0};
208    double colub[] = {1,1,1,1,1};
209    double obj[] = {5, 3, 2, 7, 4};
210    int sosrowstart[] = {0,5};
211    int soscolindex[] = {0,1,2,3,4}; 
212    const double *sol;
213    int i;
214
215    Cbc_loadProblem(model, 5, 0, start, NULL, NULL, collb, colub, obj, NULL, NULL);
216
217    assert(Cbc_getNumCols(model) == 5);
218    assert(Cbc_getNumRows(model) == 0);
219
220    for (i = 0; i < 5; i++) {
221        Cbc_setInteger(model, i);
222        assert(Cbc_isInteger(model,i));
223    }
224
225    Cbc_setObjSense(model, -1);
226    assert(Cbc_getObjSense(model) == -1);
227   
228    Cbc_addSOS(model,1,sosrowstart,soscolindex,obj,1); 
229
230    Cbc_solve(model);
231
232    assert(Cbc_isProvenOptimal(model));
233    assert(!Cbc_isAbandoned(model));
234    assert(!Cbc_isProvenInfeasible(model));
235    assert(!Cbc_isContinuousUnbounded(model));
236    assert(!Cbc_isNodeLimitReached(model));
237    assert(!Cbc_isSecondsLimitReached(model));
238    assert(!Cbc_isSolutionLimitReached(model));
239    assert(fabs( Cbc_getObjValue(model)- (7.0) < 1e-6));
240    assert(fabs( Cbc_getBestPossibleObjValue(model)- (7.0) < 1e-6));
241
242    sol = Cbc_getColSolution(model);
243   
244    assert(fabs(sol[0] - 0.0) < 1e-6);
245    assert(fabs(sol[1] - 0.0) < 1e-6);
246    assert(fabs(sol[2] - 0.0) < 1e-6);
247    assert(fabs(sol[3] - 1.0) < 1e-6);
248    assert(fabs(sol[4] - 0.0) < 1e-6);
249
250    Cbc_deleteModel(model);
251
252}
253
254
255void testIntegerInfeasible() {
256
257    Cbc_Model *model = Cbc_newModel();
258
259    /* Minimize x
260     * s.t.     x <= -10
261     * x binary */
262
263    CoinBigIndex start[] = {0, 1};
264    int rowindex[] = {0};
265    double value[] = {1.0};
266    double rowlb[] = {-INFINITY};
267    double rowub[] = {-10};
268
269    double collb[] = {0.0};
270    double colub[] = {1.0};
271    double obj[] = {1.0};
272
273    Cbc_loadProblem(model, 1, 1, start, rowindex, value, collb, colub, obj, rowlb, rowub);
274
275    Cbc_setInteger(model, 0);
276
277    assert(Cbc_getNumCols(model) == 1);
278    assert(Cbc_getNumRows(model) == 1);
279
280    Cbc_solve(model);
281   
282    assert(!Cbc_isProvenOptimal(model));
283    assert(Cbc_isProvenInfeasible(model));
284   
285    Cbc_deleteModel(model);
286
287}
288
289void testIntegerUnbounded() {
290
291    Cbc_Model *model = Cbc_newModel();
292
293    /* http://list.coin-or.org/pipermail/cbc/2014-March/001276.html
294     * Minimize x
295     * s.t. x + y <= 3
296     *      x - y == 0
297     *      x,y Free
298     *      x integer */
299
300    CoinBigIndex start[] = {0,2,4};
301    int rowindex[] = {0, 1, 0, 1};
302    double value[] = {1, 1, 1, -1};
303    double rowlb[] = {-INFINITY, 0.0};
304    double rowub[] = {3.0,0.0};
305    double collb[] = {-INFINITY, -INFINITY};
306    double colub[] = {INFINITY, INFINITY};
307    double obj[] = {1.0,0.0};
308
309    Cbc_loadProblem(model, 2, 2, start, rowindex, value, collb, colub, obj, rowlb, rowub);
310
311    Cbc_setInteger(model, 0);
312
313    Cbc_setParameter(model, "log", "0");
314   
315    printf("About to solve problem silently. You should see no output except \"Done\".\n");
316    Cbc_solve(model);
317    printf("Done\n");
318   
319    assert(!Cbc_isProvenOptimal(model));
320    assert(!Cbc_isProvenInfeasible(model));
321    assert(Cbc_isContinuousUnbounded(model));
322
323    Cbc_deleteModel(model);
324
325
326}
327
328void testIntegerBounds() {
329    /* max 1.1x + 100.0z
330       st     x +      z <= 3
331         0 <= x <= 3
332         0 <= z <= 1.5, Integer
333     x* = 2, z* = 1 */
334   
335    Cbc_Model *model = Cbc_newModel();
336
337    CoinBigIndex start[] = {0,1,2};
338    int rowindex[] = {0, 0};
339    double value[] = {1, 1};
340    double rowlb[] = {-INFINITY};
341    double rowub[] = {3.0};
342    double collb[] = {0.0, 0.0};
343    double colub[] = {3.0, 1.5};
344    double obj[] = {1.1,100.0};
345    const double *sol;
346
347    Cbc_loadProblem(model, 2, 1, start, rowindex, value, collb, colub, obj, rowlb, rowub);
348
349    Cbc_setInteger(model, 1);
350    Cbc_setObjSense(model, -1);
351
352    Cbc_solve(model);
353   
354    assert(Cbc_isProvenOptimal(model));
355
356    sol = Cbc_getColSolution(model);
357   
358    assert(fabs(sol[0] - 2.0) < 1e-6);
359    assert(fabs(sol[1] - 1.0) < 1e-6);
360
361    Cbc_deleteModel(model);
362
363}
364
365
366int main() {
367
368    printf("Knapsack test\n");
369    testKnapsack();
370    printf("SOS test\n");
371    testSOS();
372    printf("Infeasible test\n");
373    testIntegerInfeasible();
374    printf("Unbounded test\n");
375    testIntegerUnbounded();
376    /*printf("Problem modification test\n");
377    testProblemModification();*/
378    printf("Integer bounds test\n");
379    testIntegerBounds();
380
381    return 0;
382}
Note: See TracBrowser for help on using the repository browser.