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