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

Last change on this file since 2090 was 2090, checked in by mlubin, 4 years ago

workaround for old MSVC compilers, thanks Victor Zverovich

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