1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /*                                                                           */
3 /*                  This file is part of the program and library             */
4 /*         SCIP --- Solving Constraint Integer Programs                      */
5 /*                                                                           */
6 /*    Copyright (C) 2002-2021 Konrad-Zuse-Zentrum                            */
7 /*                            fuer Informationstechnik Berlin                */
8 /*                                                                           */
9 /*  SCIP is distributed under the terms of the ZIB Academic License.         */
10 /*                                                                           */
11 /*  You should have received a copy of the ZIB Academic License              */
12 /*  along with SCIP; see the file COPYING. If not visit scipopt.org.         */
13 /*                                                                           */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file   decomptest.c
17  * @brief  unit test
18  * @author Gregor Hendel
19  */
20 
21 #include "scip/scip.h"
22 #include "scip/scipdefplugins.h"
23 #include "include/scip_test.h"
24 
25 static const char* testfilename = "../check/instances/Tests/decomp/decomptest.cip";
26 static const char* testdecname = "../check/instances/Tests/decomp/decomptest.dec";
27 #define NVARS 7
28 #define NCONSS 3
29 /** GLOBAL VARIABLES **/
30 static SCIP* scip;
31 static SCIP_DECOMP* decomp;
32 static SCIP_VAR* vars[NVARS];
33 static SCIP_CONS* conss[NCONSS];
34 static int labels_vars[] = {SCIP_DECOMP_LINKVAR,0,0,1,1,0,1};
35 static int benderslabels_vars[] = {SCIP_DECOMP_LINKVAR,SCIP_DECOMP_LINKVAR,SCIP_DECOMP_LINKVAR,SCIP_DECOMP_LINKVAR,
36    SCIP_DECOMP_LINKVAR,0,1};
37 static int labels_conss[] = {SCIP_DECOMP_LINKCONS, 0, 1};
38 static int nblocks = 2; /* only blocks that aren't linking blocks are counted */
39 static char strbuf1[1024];
40 static char strbuf2[1024];
41 
42 /** set up some data structures */
43 static
setupData(void)44 void setupData(void)
45 {
46    vars[0] = SCIPfindVar(scip, "y");
47    vars[1] = SCIPfindVar(scip, "x1");
48    vars[2] = SCIPfindVar(scip, "x2");
49    vars[3] = SCIPfindVar(scip, "x3");
50    vars[4] = SCIPfindVar(scip, "x4");
51    vars[5] = SCIPfindVar(scip, "z1");
52    vars[6] = SCIPfindVar(scip, "z2");
53 
54    conss[0] = SCIPfindCons(scip, "linkingcons");
55    conss[1] = SCIPfindCons(scip, "block1cons");
56    conss[2] = SCIPfindCons(scip, "block2cons");
57 
58 }
59 
60 /** test setup */
61 static
testData(void)62 void testData(void)
63 {
64    int i;
65 
66    /* check that all variables and constraints are there */
67    for( i = 0; i < NVARS; ++i )
68       cr_assert(vars[i] != NULL);
69 
70    for( i = 0; i < NCONSS; ++i )
71       cr_assert(conss[i] != NULL);
72 }
73 
74 /* TEST SUITE */
75 static
setup(void)76 void setup(void)
77 {
78    SCIP_CALL( SCIPcreate(&scip) );
79    SCIP_CALL( SCIPincludeDefaultPlugins(scip) );
80 
81 
82    SCIP_CALL( SCIPreadProb(scip, testfilename, NULL) );
83    SCIP_CALL( SCIPcreateDecomp(scip, &decomp, nblocks, TRUE, FALSE) );
84 
85    setupData();
86 }
87 
88 static
teardown(void)89 void teardown(void)
90 {
91    SCIPfreeDecomp(scip, &decomp);
92    SCIPfree(&scip);
93 
94    BMScheckEmptyMemory();
95 }
96 
97 TestSuite(decomptest, .init = setup, .fini = teardown);
98 
99 /* TESTS  */
Test(decomptest,create_and_free)100 Test(decomptest, create_and_free)
101 {
102    /* calls setup and teardown */
103 }
104 
105 Test(decomptest, create_decomp, .description="test constructor and destructor of decomposition")
106 {
107    SCIP_DECOMP* newdecomp;
108    SCIP_CALL( SCIPcreateDecomp(scip, &newdecomp, 1, TRUE, FALSE) );
109 
110    SCIPfreeDecomp(scip, &newdecomp);
111 }
112 
113 Test(decomptest, test_data_setup, .description = "check data setup")
114 {
115    testData();
116 }
117 
118 Test(decomptest, test_setters_and_getters, .description="check that setting labels works")
119 {
120    int returnedlabels[NVARS];
121 
122    SCIP_CALL( SCIPdecompSetVarsLabels(decomp, vars, labels_vars, NVARS) );
123 
124    SCIPdecompGetVarsLabels(decomp, vars, returnedlabels, NVARS);
125 
126    /* check that each variable has the correct label */
127    cr_assert_arr_eq(returnedlabels, labels_vars, NVARS);
128 }
129 
130 /** print integer array */
131 static
printIntArray(char * strbuf,int * array,int length)132 char* printIntArray(
133    char*                 strbuf,
134    int*                  array,
135    int                   length
136    )
137 {
138    int i;
139    char* strptr = strbuf;
140 
141    /* print entries */
142    for( i = 0; i < length; ++i )
143    {
144       strptr += sprintf(strptr, "%d ", array[i]);
145    }
146 
147    return strbuf;
148 }
149 
150 
151 /** check constraint labels of this decomposition */
152 static
checkConsLabels(SCIP_DECOMP * decomposition)153 void checkConsLabels(
154    SCIP_DECOMP*          decomposition       /**< some decomposition */
155    )
156 {
157    int returnedlabels[NCONSS];
158    cr_assert_not_null(decomposition);
159 
160    SCIPdecompGetConsLabels(decomposition, conss, returnedlabels, NCONSS);
161 
162    cr_assert_arr_eq(returnedlabels, labels_conss, NCONSS,
163       "Array {%s} not equal to {%s}\n",
164       printIntArray(strbuf1, returnedlabels, NCONSS),
165       printIntArray(strbuf2, labels_conss, NCONSS));
166 
167 }
168 
169 Test(decomptest, test_cons_labeling, .description="check constraint label computation")
170 {
171    SCIP_CALL( SCIPdecompSetVarsLabels(decomp, vars, labels_vars, NVARS) );
172 
173    SCIP_CALL( SCIPcomputeDecompConsLabels(scip, decomp, conss, NCONSS) );
174 
175    checkConsLabels(decomp);
176 
177 }
178 /** check variable labels of this decomposition */
179 static
checkVarsLabels(SCIP_DECOMP * decomposition,int varlabels[])180 void checkVarsLabels(
181    SCIP_DECOMP*          decomposition,      /**< some decomposition */
182    int                   varlabels[]         /**< the variable labels to check against */
183    )
184 {
185    int returnedlabels[NVARS];
186    cr_assert_not_null(decomposition);
187    SCIPdecompGetVarsLabels(decomposition, vars, returnedlabels, NVARS);
188 
189    cr_assert_arr_eq(returnedlabels, varlabels, NVARS,
190       "Array {%s} not equal to {%s}\n",
191       printIntArray(strbuf1, returnedlabels, NVARS),
192       printIntArray(strbuf2, varlabels, NVARS)
193       );
194 }
195 
196 Test(decomptest, test_var_labeling, .description="check variable label computation")
197 {
198 
199    SCIP_CALL( SCIPdecompSetConsLabels(decomp, conss, labels_conss, NCONSS) );
200 
201    SCIP_CALL( SCIPcomputeDecompVarsLabels(scip, decomp, conss, NCONSS) );
202 
203    checkVarsLabels(decomp, labels_vars);
204 
205 }
206 
207 Test(decomptest, test_benders_var_labeling, .description="check variable labelling for Benders' decomposition")
208 {
209    SCIPdecompSetUseBendersLabels(decomp, TRUE);
210 
211    SCIP_CALL( SCIPdecompSetConsLabels(decomp, conss, labels_conss, NCONSS) );
212 
213    SCIP_CALL( SCIPcomputeDecompVarsLabels(scip, decomp, conss, NCONSS) );
214 
215    checkVarsLabels(decomp, benderslabels_vars);
216 
217 }
218 
219 Test(decomptest, test_dec_reader, .description="test decomposition reader")
220 {
221    SCIP_DECOMP* scip_decomp;
222    SCIP_DECOMP** scip_decomps;
223    int n_decomps;
224    SCIP_VAR* transvars[NVARS];
225    int returnedlabels[NVARS];
226    int v;
227    SCIP_Bool original = TRUE;
228 
229    SCIP_CALL( SCIPreadProb(scip, testdecname, "dec") );
230 
231    SCIPgetDecomps(scip, &scip_decomps, &n_decomps, original);
232    cr_assert_eq(n_decomps, 1);
233 
234    scip_decomp = scip_decomps[0];
235    cr_assert_not_null(scip_decomp);
236 
237    checkConsLabels(scip_decomp);
238 
239    checkVarsLabels(scip_decomp, labels_vars);
240 
241    /* solve the problem without presolving */
242    SCIP_CALL( SCIPsetPresolving(scip, SCIP_PARAMSETTING_OFF, TRUE) );
243    SCIP_CALL( SCIPsolve(scip) );
244 
245    /* transform variable array */
246    for( v = 0; v < NVARS; ++v )
247    {
248       transvars[v] = SCIPvarGetTransVar(vars[v]);
249       cr_assert_not_null(transvars[v]);
250    }
251 
252    /* now get the transformed decomposition and compare its variable labels */
253    SCIPgetDecomps(scip, &scip_decomps, &n_decomps, !original);
254    cr_assert_eq(n_decomps, 1, "Number of transformed decompositions should be 1.\n");
255    scip_decomp = scip_decomps[0];
256 
257    SCIPdecompGetVarsLabels(scip_decomp, transvars, returnedlabels, NVARS);
258 
259    cr_assert_arr_eq(returnedlabels, labels_vars, NVARS,
260       "Arrays should be equal: {%s} != {%s}",
261       printIntArray(strbuf1, returnedlabels, NVARS),
262       printIntArray(strbuf2, labels_vars, NVARS)
263       );
264 }
265