Scippy

SCIP

Solving Constraint Integer Programs

stptest_misc.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2022 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 scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file stptest_misc.c
17  * @brief tests for Steiner tree methods
18  * @author Daniel Rehfeldt
19  *
20  * This file implements tests for Steiner problem heuristics.
21  *
22  * A list of all interface methods can be found in stptest.h.
23  *
24  */
25 
26 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
27 //#define SCIP_DEBUG
28 #include <stdio.h>
29 #include <assert.h>
30 #include "stptest.h"
31 #include "graph.h"
32 #include "completegraph.h"
33 #include "heur_local.h"
34 #include "heur_tm.h"
35 
36 
37 static
39  SCIP* scip, /**< SCIP data structure */
40  GRAPH** g, /**< the graph */
41  SCIP_Bool pc /**< create pc graph? */
42 )
43 {
44  GRAPH* graph;
45  const int nnodes = 5;
46  const int nedges = 5;
47 
48  SCIP_CALL(graph_init(scip, g, nnodes, 2 * nedges, 1));
49  graph = *g;
50 
51  for( int i = 1; i < nnodes; i++ )
52  graph_knot_add(graph, -1);
53 
54  graph_knot_add(graph, 0);
55 
56  graph->source = 0;
57 
58  graph_edge_add(scip, graph, 0, 1, 1.0, 1.0);
59  graph_edge_add(scip, graph, 1, 2, 1.0, 1.0);
60  graph_edge_add(scip, graph, 1, 4, 1.0, 1.0);
61  graph_edge_add(scip, graph, 2, 3, 1.0, 1.0);
62  graph_edge_add(scip, graph, 3, 4, 1.0, 1.0);
63 
64  if( pc )
65  {
66  SCIP_CALL( graph_pc_initPrizes(scip, graph, nnodes) );
67 
68  for( int i = 0; i < nnodes; i++ )
69  graph->prize[i] = 0.0;
70 
71  graph->prize[0] = 1.0;
72 
73  SCIP_CALL( graph_transPc(scip, graph) );
74  }
75 
76  SCIP_CALL(graph_initHistory(scip, graph));
77  SCIP_CALL(graph_path_init(scip, graph));
78 
79  return SCIP_OKAY;
80 }
81 
82 static
84  SCIP* scip /**< SCIP data structure */
85 )
86 {
87  GRAPH* graph;
88  const int nnodes = 4;
89  const int nedges = 3;
90  SCIP_Real cutoff[] = {FARAWAY, FARAWAY, FARAWAY};
91  SCIP_Bool success;
92 
93  SCIP_CALL(graph_init(scip, &graph, nnodes, 2 * nedges, 1));
94 
95  for( int i = 1; i < nnodes; i++ )
96  graph_knot_add(graph, -1);
97 
98  graph_knot_add(graph, 0);
99 
100  graph->source = 0;
101 
102  graph_edge_add(scip, graph, 0, 1, 1.0, 1.0);
103  graph_edge_add(scip, graph, 0, 2, 1.0, 1.0);
104  graph_edge_add(scip, graph, 0, 3, 1.0, 1.0);
105 
106  SCIP_CALL(graph_initHistory(scip, graph));
107  SCIP_CALL(graph_path_init(scip, graph));
108 
109 
110  for( int e = 0; e < nedges; e += 2 )
111  assert(graph_edge_nPseudoAncestors(graph, e) == 0);
112 
113  SCIP_CALL( graph_knot_delPseudo(scip, graph, cutoff, NULL, NULL, 0, NULL, &success) );
114 
115  assert(success);
116 
117  for( int e = 0; e < nedges; e += 2 )
118  {
119  assert(graph_edge_nPseudoAncestors(graph, e) == 1);
120  assert(graph_edge_getPseudoAncestors(graph, e)[0] == 0);
121  }
122 
123 
124  graph_path_exit(scip, graph);
125  graph_free(scip, &graph, TRUE);
126 
127  return SCIP_OKAY;
128 }
129 
130 
131 static
133  SCIP* scip /**< SCIP data structure */
134 )
135 {
136  GRAPH* graph;
137  const int nnodes = 5;
138  const int nedges = 4;
139  SCIP_Real cutoff[] = {FARAWAY, FARAWAY, FARAWAY};
140  SCIP_Bool success;
141 
142  SCIP_CALL(graph_init(scip, &graph, nnodes, 2 * nedges, 1));
143 
144  for( int i = 1; i < nnodes; i++ )
145  graph_knot_add(graph, -1);
146 
147  graph_knot_add(graph, 0);
148 
149  graph->source = 0;
150 
151  graph_edge_add(scip, graph, 0, 1, 1.0, 1.0);
152  graph_edge_add(scip, graph, 0, 2, 1.0, 1.0);
153  graph_edge_add(scip, graph, 0, 3, 1.0, 1.0);
154  graph_edge_add(scip, graph, 3, 4, 1.0, 1.0);
155 
156  SCIP_CALL(graph_initHistory(scip, graph));
157  SCIP_CALL(graph_path_init(scip, graph));
158 
159  for( int e = 0; e < nedges; e += 2 )
160  assert(graph_edge_nPseudoAncestors(graph, e) == 0);
161 
162  SCIP_CALL( graph_knot_delPseudo(scip, graph, cutoff, NULL, NULL, 0, NULL, &success) );
163  assert(success);
164 
165  for( int e = graph->outbeg[1]; e != EAT_LAST; e = graph->oeat[e] )
166  {
167  if( graph->head[e] == 2 )
168  {
169  graph_edge_del(scip, graph, e, TRUE);
170 
171  break;
172  }
173  }
174 
175  SCIP_CALL( graph_knot_delPseudo(scip, graph, cutoff, NULL, NULL, 3, NULL, &success) );
176  assert(success);
177 
178  assert(graph->grad[1] == 1);
179  assert(graph->grad[2] == 1);
180  assert(graph->grad[4] == 2);
181 
182 
183  graph_path_exit(scip, graph);
184  graph_free(scip, &graph, TRUE);
185 
186  return SCIP_OKAY;
187 }
188 
189 static
191  SCIP* scip /**< SCIP data structure */
192 )
193 {
194  GRAPH* graph;
195  int pseudoancestor;
196 
197  assert(scip);
198 
199  SCIP_CALL( graphBuildV5E5(scip, &graph, FALSE) );
200  assert(graph->knots == 5 && graph->edges == 10);
201 
202  graph_addPseudoAncestor(graph, &pseudoancestor);
203  STPTEST_ASSERT(pseudoancestor == 0);
204  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 0, 0, graph) );
208 
209  graph_addPseudoAncestor(graph, &pseudoancestor);
210  STPTEST_ASSERT(pseudoancestor == 1);
211  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 0, 1, graph) );
214 
215  graph_addPseudoAncestor(graph, &pseudoancestor);
216  graph_addPseudoAncestor(graph, &pseudoancestor);
217  graph_addPseudoAncestor(graph, &pseudoancestor);
218  STPTEST_ASSERT(pseudoancestor == 4);
219  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 1, 4, graph) );
220  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 1, 3, graph) );
221  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 1, 2, graph) );
224 
225  graph_edge_delPseudoAncestors(scip, 1, graph);
228 
229  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 0, 2, graph) );
232 
233  graph_path_exit(scip, graph);
234  graph_free(scip, &graph, TRUE);
235 
236  return SCIP_OKAY;
237 }
238 
239 
240 static
242  SCIP* scip /**< SCIP data structure */
243 )
244 {
245  GRAPH* graph;
246  SCIP_Bool conflict;
247  int pseudoancestor;
248 
249  assert(scip);
250 
251  SCIP_CALL( graphBuildV5E5(scip, &graph, FALSE) );
252  assert(graph->knots == 5 && graph->edges == 10);
253 
254  graph_addPseudoAncestor(graph, &pseudoancestor);
255  graph_addPseudoAncestor(graph, &pseudoancestor);
256  graph_addPseudoAncestor(graph, &pseudoancestor);
257  graph_addPseudoAncestor(graph, &pseudoancestor);
258  graph_addPseudoAncestor(graph, &pseudoancestor);
259  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 0, 2, graph) );
260  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 0, 3, graph) );
261  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 4, 3, graph) );
262  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 4, 4, graph) );
263  SCIP_CALL( graph_pseudoAncestors_appendMoveEdge(scip, 0, 4, FALSE, graph, &conflict) );
264  STPTEST_ASSERT(conflict);
267 
268  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 6, 1, graph) );
269  SCIP_CALL( graph_pseudoAncestors_appendMoveEdge(scip, 0, 6, FALSE, graph, &conflict) );
270  STPTEST_ASSERT(!conflict);
273 
274  graph_path_exit(scip, graph);
275  graph_free(scip, &graph, TRUE);
276 
277  return SCIP_OKAY;
278 }
279 
280 
281 static
283  SCIP* scip /**< SCIP data structure */
284 )
285 {
286  GRAPH* graph;
287  SCIP_Bool conflict;
288 
289  assert(scip);
290 
291  SCIP_CALL( graphBuildV5E5(scip, &graph, TRUE) );
292  assert(graph->knots > 5 && graph->edges > 10);
293 
294  SCIP_CALL( graph_pseudoAncestors_addToNode(scip, 0, 2, graph) );
295  SCIP_CALL( graph_pseudoAncestors_addToNode(scip, 0, 3, graph) );
296  SCIP_CALL( graph_pseudoAncestors_addToNode(scip, 4, 3, graph) );
297  SCIP_CALL( graph_pseudoAncestors_addToNode(scip, 4, 4, graph) );
298  SCIP_CALL( graph_pseudoAncestors_appendMoveNode(scip, 0, 4, FALSE, graph, &conflict) );
299  assert(conflict);
300  assert( graph_knot_nPseudoAncestors(graph, 0) == 3 );
301  assert( graph_knot_nPseudoAncestors(graph, 4) == 0);
302 
303 
304  SCIP_CALL( graph_pseudoAncestors_addToNode(scip, 2, 1, graph) );
305  SCIP_CALL( graph_pseudoAncestors_appendMoveNode(scip, 0, 2, FALSE, graph, &conflict) );
306  assert(!conflict);
307  assert( graph_knot_nPseudoAncestors(graph, 0) == 4 );
308  assert( graph_knot_nPseudoAncestors(graph, 2) == 0);
309 
310 
311  graph_path_exit(scip, graph);
312  graph_free(scip, &graph, TRUE);
313 
314  return SCIP_OKAY;
315 }
316 
317 
318 static
320  SCIP* scip /**< SCIP data structure */
321 )
322 {
323  GRAPH* graph;
324  SCIP_Bool conflict;
325  int* hasharr;
326  int pseudoancestor;
327 
328  assert(scip);
329 
330  SCIP_CALL( graphBuildV5E5(scip, &graph, FALSE) );
331  assert(graph->knots == 5 && graph->edges == 10);
332 
334 
335  graph_addPseudoAncestor(graph, &pseudoancestor);
336  graph_addPseudoAncestor(graph, &pseudoancestor);
337  graph_addPseudoAncestor(graph, &pseudoancestor);
338  graph_addPseudoAncestor(graph, &pseudoancestor);
339  graph_addPseudoAncestor(graph, &pseudoancestor);
340  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 0, 2, graph) );
341  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 0, 3, graph) );
342  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 4, 3, graph) );
343  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 4, 4, graph) );
345  graph_pseudoAncestors_hashEdgeDirty(graph->pseudoancestors, 4, TRUE, &conflict, hasharr);
346  STPTEST_ASSERT(conflict);
347 
348  SCIP_CALL( graph_pseudoAncestors_addToEdge(scip, 6, 1, graph) );
349  graph_pseudoAncestors_hashEdgeDirty(graph->pseudoancestors, 6, TRUE, &conflict, hasharr);
350  STPTEST_ASSERT(!conflict);
351 
354 
355  for( int k = 0; k < graph->knots; k++ )
356  STPTEST_ASSERT(hasharr[k] == 0);
357 
358  SCIPfreeCleanBufferArray(scip, &hasharr);
359 
360  graph_path_exit(scip, graph);
361  graph_free(scip, &graph, TRUE);
362 
363  return SCIP_OKAY;
364 }
365 
366 static
368  SCIP* scip /**< SCIP data structure */
369 )
370 {
371  GRAPH* graph;
372  SCIP_Bool conflict;
373  int* hasharr;
374 
375  assert(scip);
376 
377  SCIP_CALL( graphBuildV5E5(scip, &graph, TRUE) );
378  assert(graph->knots > 5 && graph->edges > 10);
379 
381 
382  SCIP_CALL( graph_pseudoAncestors_addToNode(scip, 0, 2, graph) );
383  SCIP_CALL( graph_pseudoAncestors_addToNode(scip, 0, 3, graph) );
384  SCIP_CALL( graph_pseudoAncestors_addToNode(scip, 4, 3, graph) );
385  SCIP_CALL( graph_pseudoAncestors_addToNode(scip, 4, 4, graph) );
387  graph_pseudoAncestors_hashNodeDirty(graph->pseudoancestors, 4, TRUE, &conflict, hasharr);
388  assert(conflict);
389 
390 
391  SCIP_CALL( graph_pseudoAncestors_addToNode(scip, 2, 1, graph) );
392  graph_pseudoAncestors_hashNodeDirty(graph->pseudoancestors, 2, TRUE, &conflict, hasharr);
393  assert(!conflict);
394 
397 
398  for( int k = 0; k < graph->knots; k++ )
399  assert(hasharr[k] == 0);
400 
401  SCIPfreeCleanBufferArray(scip, &hasharr);
402 
403  graph_path_exit(scip, graph);
404  graph_free(scip, &graph, TRUE);
405 
406  return SCIP_OKAY;
407 }
408 
409 
410 
411 
412 /** extension test */
413 static
415  SCIP* scip /**< SCIP data structure */
416 )
417 {
418  CGRAPH* cgraph;
419  const int maxnnodes = 11;
420 
421  SCIP_CALL( cgraph_init(scip, &cgraph, maxnnodes) );
422 
423  assert(0 == cgraph->nnodes_curr);
424  assert(maxnnodes == cgraph->nnodes_max);
425 
426  cgraph_node_append(cgraph, 1);
427 
428  if( !cgraph_valid(cgraph) )
429  {
430  SCIPdebugMessage("cgraph not valid! \n");
431  return SCIP_ERROR;
432  }
433 
434  cgraph_node_deleteTop(cgraph);
435 
436  if( !cgraph_valid(cgraph) )
437  {
438  SCIPdebugMessage("cgraph not valid! \n");
439  return SCIP_ERROR;
440  }
441 
442  cgraph_node_append(cgraph, 2);
443  cgraph_node_append(cgraph, 3);
444 
445  cgraph_node_deleteTop(cgraph);
446 
447  if( cgraph->nnodes_curr != 1 )
448  {
449  SCIPdebugMessage("wrong node count cgraph not valid! \n");
450  return SCIP_ERROR;
451  }
452 
453  if( !cgraph_valid(cgraph) )
454  {
455  SCIPdebugMessage("cgraph not valid! \n");
456  return SCIP_ERROR;
457  }
458 
459  cgraph_node_deleteTop(cgraph);
460 
461  if( cgraph->nnodes_curr != 0 )
462  {
463  SCIPdebugMessage("wrong node count cgraph not valid! \n");
464  return SCIP_ERROR;
465  }
466 
467  if( !cgraph_valid(cgraph) )
468  {
469  SCIPdebugMessage("cgraph not valid! \n");
470  return SCIP_ERROR;
471  }
472 
473 
474  cgraph_free(scip, &cgraph);
475 
476  return SCIP_OKAY;
477 }
478 
479 
480 /** mst test */
481 static
483  SCIP* scip /**< SCIP data structure */
484 )
485 {
486  CGRAPH* cgraph;
487  CMST* cmst;
488  const int maxnnodes = 7;
489  SCIP_Real adjedges1[] = { FARAWAY, 2.0, 3.0, CGRAPH_EDGECOST_UNDEFINED_VALUE };
490  SCIP_Real adjedges2[] = { 2.0, FARAWAY, 3.0, CGRAPH_EDGECOST_UNDEFINED_VALUE };
491  SCIP_Real adjedges3[] = { 1.0, 0.1, FARAWAY, CGRAPH_EDGECOST_UNDEFINED_VALUE };
492 
493  SCIP_CALL( cgraph_init(scip, &cgraph, maxnnodes) );
494  SCIP_CALL( cmst_init(scip, &cmst, maxnnodes) );
495 
496  cgraph_node_append(cgraph, 1);
497  cgraph_node_append(cgraph, 2);
498  cgraph_node_append(cgraph, 3);
499 
500  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges1, 4);
501  cgraph_node_applyMinAdjCosts(cgraph, 0, 1);
502  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges2, 4);
503  cgraph_node_applyMinAdjCosts(cgraph, 1, 2);
504  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges3, 4);
505  cgraph_node_applyMinAdjCosts(cgraph, 2, 3);
506 
507  cgraph_node_repositionTop(cgraph, 2);
508 
509  cmst_computeMst(cgraph, 0, cmst);
510 
511  if( !SCIPisEQ(scip, cmst->mstobj, 1.0) )
512  {
513  printf("completemst1: wrong obj: %f \n", cmst->mstobj);
514  return SCIP_ERROR;
515  }
516 
517  if( cmst->predecessors[0] != -1 || cmst->predecessors[1] != 0 )
518  {
519  printf("completemst1: wrong ancestor \n");
520  return SCIP_ERROR;
521  }
522 
523  cmst_free(scip, &cmst);
524  cgraph_free(scip, &cgraph);
525 
526  return SCIP_OKAY;
527 }
528 
529 
530 /** mst test */
531 static
533  SCIP* scip /**< SCIP data structure */
534 )
535 {
536  CGRAPH* cgraph;
537  CMST* cmst;
538  const int maxnnodes = 3;
539  SCIP_Real adjedges1[] = { FARAWAY, 1.0, 2.0, CGRAPH_EDGECOST_UNDEFINED_VALUE };
540  SCIP_Real adjedges2[] = { 1.0, FARAWAY, 2.0, CGRAPH_EDGECOST_UNDEFINED_VALUE };
541  SCIP_Real adjedges3[] = { 2.0, 1.0 , FARAWAY, CGRAPH_EDGECOST_UNDEFINED_VALUE };
542 
543  SCIP_CALL( cgraph_init(scip, &cgraph, maxnnodes) );
544  SCIP_CALL( cmst_init(scip, &cmst, maxnnodes) );
545 
546  cgraph_node_append(cgraph, 1);
547  cgraph_node_append(cgraph, 2);
548  cgraph_node_append(cgraph, 77);
549 
550 
551  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges1, 4);
552  cgraph_node_applyMinAdjCosts(cgraph, 0, 1);
553  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges2, 4);
554  cgraph_node_applyMinAdjCosts(cgraph, 1, 2);
555  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges3, 4);
556  cgraph_node_applyMinAdjCosts(cgraph, 2, 77);
557 
558  cmst_computeMst(cgraph, 0, cmst);
559 
560  if( !SCIPisEQ(scip, cmst->mstobj, 2.0) )
561  {
562  printf("completemst2: wrong obj: %f \n", cmst->mstobj);
563  return SCIP_ERROR;
564  }
565 
566  if( cmst->predecessors[0] != -1 || cmst->predecessors[1] != 0 || cmst->predecessors[2] != 1 )
567  {
568  printf("completemst2: wrong ancestor \n");
569  return SCIP_ERROR;
570  }
571 
572  cmst_free(scip, &cmst);
573  cgraph_free(scip, &cgraph);
574 
575  return SCIP_OKAY;
576 }
577 
578 
579 /** mst test */
580 static
582  SCIP* scip /**< SCIP data structure */
583 )
584 {
585  CGRAPH* cgraph;
586  CMST* cmst;
587  const int maxnnodes = 3;
588  SCIP_Real adjedges1[] = { FARAWAY, 1.0, 2.0, CGRAPH_EDGECOST_UNDEFINED_VALUE };
589  SCIP_Real adjedges2[] = { 1.0, FARAWAY, 1.0, CGRAPH_EDGECOST_UNDEFINED_VALUE };
590  SCIP_Real adjedges3[] = { 2.0, 2.0 , FARAWAY, CGRAPH_EDGECOST_UNDEFINED_VALUE };
591 
592  SCIP_CALL( cgraph_init(scip, &cgraph, maxnnodes) );
593  SCIP_CALL( cmst_init(scip, &cmst, maxnnodes) );
594 
595  cgraph_node_append(cgraph, 1);
596  cgraph_node_append(cgraph, 2);
597  cgraph_node_append(cgraph, 77);
598 
599  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges1, 4);
600  cgraph_node_applyMinAdjCosts(cgraph, 0, 1);
601  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges2, 4);
602  cgraph_node_applyMinAdjCosts(cgraph, 1, 2);
603  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges3, 4);
604  cgraph_node_applyMinAdjCosts(cgraph, 2, 77);
605 
606  cmst_computeMst(cgraph, 0, cmst);
607 
608  if( !SCIPisEQ(scip, cmst->mstobj, 2.0) )
609  {
610  printf("completemst2: wrong obj: %f \n", cmst->mstobj);
611  return SCIP_ERROR;
612  }
613 
614  if( cmst->predecessors[0] != -1 || cmst->predecessors[1] != 0 || cmst->predecessors[2] != 1 )
615  {
616  printf("completemst2: wrong ancestor \n");
617  return SCIP_ERROR;
618  }
619 
620  cmst_free(scip, &cmst);
621  cgraph_free(scip, &cgraph);
622 
623  return SCIP_OKAY;
624 }
625 
626 
627 /** mst test */
628 static
630  SCIP* scip /**< SCIP data structure */
631 )
632 {
633  CGRAPH* cgraph;
634  CMST* cmst;
635  const int maxnnodes = 3;
636  SCIP_Real adjedges1[] = { FARAWAY, 1.0, 2.0, CGRAPH_EDGECOST_UNDEFINED_VALUE };
637  SCIP_Real adjedges2[] = { 1.0, FARAWAY, 1.0, CGRAPH_EDGECOST_UNDEFINED_VALUE };
638  SCIP_Real adjedges3[] = { 2.0, 2.0 , FARAWAY, CGRAPH_EDGECOST_UNDEFINED_VALUE };
639 
640  SCIP_CALL( cgraph_init(scip, &cgraph, maxnnodes) );
641  SCIP_CALL( cmst_init(scip, &cmst, maxnnodes) );
642 
643  cgraph_node_append(cgraph, 1);
644  cgraph_node_append(cgraph, 2);
645  cgraph_node_append(cgraph, 77);
646 
647  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges1, 4);
648  cgraph_node_applyMinAdjCosts(cgraph, 0, 1);
649  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges2, 4);
650  cgraph_node_applyMinAdjCosts(cgraph, 1, 2);
651  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges3, 4);
652  cgraph_node_applyMinAdjCosts(cgraph, 2, 77);
653 
654  cmst_computeMst(cgraph, 0, cmst);
655 
656  cgraph_node_deleteTop(cgraph);
657  cgraph_node_deleteTop(cgraph);
658 
659  cgraph_node_append(cgraph, 7);
660  cgraph_node_append(cgraph, 88);
661 
662  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges2, 4);
663  cgraph_node_applyMinAdjCosts(cgraph, 1, 7);
664  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges3, 4);
665  cgraph_node_applyMinAdjCosts(cgraph, 2, 88);
666 
667  cmst_computeMst(cgraph, 0, cmst);
668 
669  if( !SCIPisEQ(scip, cmst->mstobj, 2.0) )
670  {
671  printf("completemst2: wrong obj: %f \n", cmst->mstobj);
672  return SCIP_ERROR;
673  }
674 
675  if( cmst->predecessors[0] != -1 || cmst->predecessors[1] != 0 || cmst->predecessors[2] != 1 )
676  {
677  printf("completemst2: wrong ancestor \n");
678  return SCIP_ERROR;
679  }
680 
681  cmst_free(scip, &cmst);
682  cgraph_free(scip, &cgraph);
683 
684  return SCIP_OKAY;
685 }
686 
687 
688 
689 /** mst test */
690 static
692  SCIP* scip /**< SCIP data structure */
693 )
694 {
695  CGRAPH* cgraph;
696  CMST* cmst;
697  const int maxnnodes = 7;
699  SCIP_Real adjedges2[] = { 2.0, FARAWAY, FARAWAY, FARAWAY, FARAWAY, CGRAPH_EDGECOST_UNDEFINED_VALUE };
700  SCIP_Real adjedges3[] = { 4.0, 3.0, FARAWAY, FARAWAY, FARAWAY, CGRAPH_EDGECOST_UNDEFINED_VALUE };
701  SCIP_Real adjedges4[] = { 4.0, 4.0, 1.0, FARAWAY, FARAWAY, CGRAPH_EDGECOST_UNDEFINED_VALUE };
702  SCIP_Real adjedges5[] = { 1.0, 1.0, 2.0, 3.0, FARAWAY, CGRAPH_EDGECOST_UNDEFINED_VALUE };
703 
704  SCIP_CALL( cgraph_init(scip, &cgraph, maxnnodes) );
705  SCIP_CALL( cmst_init(scip, &cmst, maxnnodes) );
706 
707  cgraph_node_append(cgraph, 0);
708  cgraph_node_append(cgraph, 2);
709  cgraph_node_append(cgraph, 3);
710  cgraph_node_append(cgraph, 4);
711 
712  cgraph_node_deleteTop(cgraph);
713  cgraph_node_deleteTop(cgraph);
714  cgraph_node_deleteTop(cgraph);
715  cgraph_node_deleteTop(cgraph);
716 
717  cgraph_node_append(cgraph, 1);
718  cgraph_node_append(cgraph, 2);
719  cgraph_node_append(cgraph, 3);
720  cgraph_node_append(cgraph, 7);
721  cgraph_node_append(cgraph, 66);
722 
723  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges1, 6);
724  cgraph_node_applyMinAdjCosts(cgraph, 0, 1);
725  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges2, 6);
726  cgraph_node_applyMinAdjCosts(cgraph, 1, 2);
727  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges3, 6);
728  cgraph_node_applyMinAdjCosts(cgraph, 2, 3);
729  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges4, 6);
730  cgraph_node_applyMinAdjCosts(cgraph, 3, 7);
731  BMScopyMemoryArray(cgraph->adjedgecosts, adjedges5, 6);
732  cgraph_node_applyMinAdjCosts(cgraph, 4, 66);
733 
734  cmst_computeMst(cgraph, 3, cmst);
735 
736  if( !SCIPisEQ(scip, cmst->mstobj, 5.0) )
737  {
738  SCIPdebugMessage("wrong obj: %f \n", cmst->mstobj);
739  return SCIP_ERROR;
740  }
741 
742  if( cmst->predecessors[0] != 4 || cmst->predecessors[1] != 4 || cmst->predecessors[4] != 2 || cmst->predecessors[2] != 3 )
743  {
744  SCIPdebugMessage("wrong ancestor \n");
745  return SCIP_ERROR;
746  }
747 
748  cmst_free(scip, &cmst);
749  cgraph_free(scip, &cgraph);
750 
751  return SCIP_OKAY;
752 }
753 
754 
755 
756 /** test pseudo ancestors */
758  SCIP* scip /**< SCIP data structure */
759 )
760 {
761  assert(scip);
762 
768 
769  printf("pseudoAncestors_test passed \n");
770 
771  return SCIP_OKAY;
772 }
773 
774 /** test pseudo deletion */
776  SCIP* scip /**< SCIP data structure */
777 )
778 {
779  assert(scip);
780 
781  SCIP_CALL( pseudoDelSingle(scip) );
782  SCIP_CALL( pseudoDelDouble(scip) );
783 
784  printf("pseudoDeletion test: all ok \n");
785 
786  return SCIP_OKAY;
787 }
788 
789 
790 
792  SCIP* scip /**< SCIP data structure */
793 )
794 {
795  DHEAP* heap = NULL;
796 
797  int min = -1;
798  graph_heap_create(scip, 13, NULL, NULL, &heap);
799  assert(heap != NULL);
800 
801  graph_heap_correct(1, 2.0, heap);
802  graph_heap_correct(2, 1.0, heap);
803  graph_heap_correct(0, 1.5, heap);
804 
805  assert(heap->size == 3);
806 
807  graph_heap_deleteMinGetNode(&min, heap);
808  assert(min == 2);
809  graph_heap_deleteMinGetNode(&min, heap);
810  assert(min == 0);
811  graph_heap_deleteMinGetNode(&min, heap);
812  assert(min == 1);
813 
814  assert(heap->size == 0);
815  graph_heap_clean(TRUE, heap);
816 
817 
818  graph_heap_correct(1, 2.0, heap);
819  graph_heap_correct(2, 2.7, heap);
820  graph_heap_correct(0, 1.5, heap);
821  graph_heap_correct(2, 1.9, heap);
822  graph_heap_correct(4, 0.5, heap);
823 
824  assert(heap->size == 4);
825 
826  graph_heap_deleteMinGetNode(&min, heap);
827  assert(min == 4);
828  graph_heap_deleteMinGetNode(&min, heap);
829  assert(min == 0);
830  graph_heap_deleteMinGetNode(&min, heap);
831  assert(min == 2);
832  graph_heap_deleteMinGetNode(&min, heap);
833  assert(min == 1);
834 
835  assert(heap->size == 0);
836  graph_heap_clean(TRUE, heap);
837 
838  graph_heap_correct(1, 2.0, heap);
839  graph_heap_correct(2, 3.0, heap);
840  graph_heap_correct(0, 1.5, heap);
841  graph_heap_correct(2, 1.6, heap);
842  graph_heap_correct(12, 22.5, heap);
843  graph_heap_correct(12, 7.7, heap);
844  graph_heap_correct(4, 8.5, heap);
845 
846 
847  assert(heap->size == 5);
848 
849  graph_heap_deleteMinGetNode(&min, heap);
850  assert(min == 0);
851  graph_heap_deleteMinGetNode(&min, heap);
852  assert(min == 2);
853  graph_heap_deleteMinGetNode(&min, heap);
854  assert(min == 1);
855  graph_heap_deleteMinGetNode(&min, heap);
856  assert(min == 12);
857  graph_heap_deleteMinGetNode(&min, heap);
858  assert(min == 4);
859 
860 
861  assert(heap->size == 0);
862 
863 
864  graph_heap_free(scip, TRUE, TRUE, &heap);
865  assert(heap == NULL);
866 
867  graph_heap_create(scip, 3, NULL, NULL, &heap);
868 
869  graph_heap_correct(1, 2.0, heap);
870  graph_heap_correct(2, 3.0, heap);
871  graph_heap_correct(0, 1.5, heap);
872  graph_heap_correct(2, 2.5, heap);
873 
874  graph_heap_deleteMinGetNode(&min, heap);
875  assert(min == 0);
876  graph_heap_deleteMinGetNode(&min, heap);
877  assert(min == 1);
878  graph_heap_deleteMinGetNode(&min, heap);
879  assert(min == 2);
880 
881  assert(heap->size == 0);
882 
883  graph_heap_free(scip, TRUE, TRUE, &heap);
884  assert(heap == NULL);
885 
886  printf("stptest_dheap: all ok \n");
887 
888  return SCIP_OKAY;
889 }
890 
891 
892 
894  SCIP* scip /**< SCIP data structure */
895 )
896 {
897  SCIP_CALL( completegraph(scip) );
898  SCIP_CALL( completemst1(scip) );
899  SCIP_CALL( completemst2(scip) );
900  SCIP_CALL( completemst3(scip) );
901  SCIP_CALL( completemst4(scip) );
902  SCIP_CALL( completemst5(scip) );
903 
904  printf("stptest_completegraph: all ok \n");
905 
906  return SCIP_OKAY;
907 }
void graph_edge_delPseudoAncestors(SCIP *, int, GRAPH *)
int graph_edge_nPseudoAncestors(const GRAPH *, int)
SCIP_RETCODE cmst_init(SCIP *scip, CMST **cmst, int maxnnodes)
void graph_pseudoAncestors_unhashEdge(const PSEUDOANS *, int, int *)
SCIP_Bool cgraph_valid(const CGRAPH *cgraph)
#define STPTEST_ASSERT(cond)
Definition: stptest.h:63
int *RESTRICT head
Definition: graphdefs.h:224
void graph_edge_del(SCIP *, GRAPH *, int, SCIP_Bool)
Definition: graph_edge.c:368
static SCIP_RETCODE completemst1(SCIP *scip)
Definition: stptest_misc.c:482
int source
Definition: graphdefs.h:195
static SCIP_RETCODE pseudoAncestorsHashPc(SCIP *scip)
Definition: stptest_misc.c:367
static SCIP_RETCODE pseudoDelDouble(SCIP *scip)
Definition: stptest_misc.c:132
static SCIP_RETCODE completegraph(SCIP *scip)
Definition: stptest_misc.c:414
static SCIP_RETCODE completemst3(SCIP *scip)
Definition: stptest_misc.c:581
int graph_pseudoAncestorsGetHashArraySize(const PSEUDOANS *)
static SCIP_RETCODE pseudoAncestorsMergePc(SCIP *scip)
Definition: stptest_misc.c:282
includes complete graph methods, in particular for MST calculation
void cgraph_node_append(CGRAPH *cgraph, int nodeid)
void graph_free(SCIP *, GRAPH **, SCIP_Bool)
Definition: graph_base.c:796
SCIP_RETCODE graph_path_init(SCIP *, GRAPH *)
Definition: graph_path.c:480
#define FALSE
Definition: def.h:87
void graph_pseudoAncestors_unhashNode(const PSEUDOANS *, int, int *)
static SCIP_RETCODE completemst2(SCIP *scip)
Definition: stptest_misc.c:532
void graph_pseudoAncestors_hashNodeDirty(const PSEUDOANS *, int, SCIP_Bool, SCIP_Bool *, int *)
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
includes various files containing graph methods used for Steiner tree problems
void cgraph_node_deleteTop(CGRAPH *cgraph)
void graph_heap_clean(SCIP_Bool, DHEAP *)
Definition: graph_util.c:938
SCIP_RETCODE stptest_pseudoDel(SCIP *scip)
Definition: stptest_misc.c:775
#define EAT_LAST
Definition: graphdefs.h:58
#define SCIPdebugMessage
Definition: pub_message.h:87
#define FARAWAY
Definition: graphdefs.h:89
void graph_pseudoAncestors_hashEdge(const PSEUDOANS *, int, int *)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE graph_pseudoAncestors_appendMoveNode(SCIP *, int, int, SCIP_Bool, GRAPH *, SCIP_Bool *)
SCIP_RETCODE graph_pc_initPrizes(SCIP *, GRAPH *, int)
Definition: graph_pcbase.c:741
#define SCIPallocCleanBufferArray(scip, ptr, num)
Definition: scip_mem.h:133
int *RESTRICT oeat
Definition: graphdefs.h:231
static SCIP_RETCODE pseudoAncestorsMerge(SCIP *scip)
Definition: stptest_misc.c:241
PSEUDOANS * pseudoancestors
Definition: graphdefs.h:236
SCIP_RETCODE graph_transPc(SCIP *, GRAPH *)
Definition: graph_trans.c:154
#define CGRAPH_EDGECOST_UNDEFINED_VALUE
Definition: completegraph.h:39
SCIP_Real * prize
Definition: graphdefs.h:210
SCIP_RETCODE graph_initHistory(SCIP *, GRAPH *)
Definition: graph_base.c:695
void graph_edge_add(SCIP *, GRAPH *, int, int, double, double)
int *RESTRICT grad
Definition: graphdefs.h:201
void cmst_free(SCIP *scip, CMST **cmst)
void graph_knot_add(GRAPH *, int)
Definition: graph_node.c:64
SCIP_RETCODE graph_pseudoAncestors_addToEdge(SCIP *, int, int, GRAPH *)
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_RETCODE graph_knot_delPseudo(SCIP *, GRAPH *, const SCIP_Real *, const SCIP_Real *, const SCIP_Real *, int, REDCOST *, SCIP_Bool *)
SCIP_RETCODE stptest_dheap(SCIP *scip)
Definition: stptest_misc.c:791
SCIP_RETCODE stptest_pseudoAncestors(SCIP *scip)
Definition: stptest_misc.c:757
int knots
Definition: graphdefs.h:190
#define SCIP_CALL(x)
Definition: def.h:384
Improvement heuristic for Steiner problems.
void cgraph_free(SCIP *scip, CGRAPH **cgraph)
void graph_heap_free(SCIP *, SCIP_Bool, SCIP_Bool, DHEAP **)
Definition: graph_util.c:1034
#define SCIP_Bool
Definition: def.h:84
int graph_knot_nPseudoAncestors(const GRAPH *, int)
SCIP_RETCODE cgraph_init(SCIP *scip, CGRAPH **cgraph, int maxnnodes)
static SCIP_RETCODE pseudoAncestorsHash(SCIP *scip)
Definition: stptest_misc.c:319
const int * graph_edge_getPseudoAncestors(const GRAPH *, int)
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:127
void graph_heap_deleteMinGetNode(int *, DHEAP *)
Definition: graph_util.c:1065
void graph_path_exit(SCIP *, GRAPH *)
Definition: graph_path.c:515
void graph_pseudoAncestors_hashNode(const PSEUDOANS *, int, int *)
SCIP_Real * adjedgecosts
Definition: completegraph.h:46
static SCIP_RETCODE graphBuildV5E5(SCIP *scip, GRAPH **g, SCIP_Bool pc)
Definition: stptest_misc.c:38
void cgraph_node_repositionTop(CGRAPH *cgraph, int nodeid_new)
SCIP_Real mstobj
Definition: completegraph.h:74
includes various testing methods for Steiner tree problems
static SCIP_RETCODE completemst4(SCIP *scip)
Definition: stptest_misc.c:629
SCIP_RETCODE graph_heap_create(SCIP *, int, int *, DENTRY *, DHEAP **)
Definition: graph_util.c:992
#define SCIP_Real
Definition: def.h:177
#define SCIPfreeCleanBufferArray(scip, ptr)
Definition: scip_mem.h:137
void graph_pseudoAncestors_hashEdgeDirty(const PSEUDOANS *, int, SCIP_Bool, SCIP_Bool *, int *)
int *RESTRICT outbeg
Definition: graphdefs.h:204
static SCIP_RETCODE pseudoAncestorsCreation(SCIP *scip)
Definition: stptest_misc.c:190
static SCIP_RETCODE pseudoDelSingle(SCIP *scip)
Definition: stptest_misc.c:83
shortest paths based primal heuristics for Steiner problems
SCIP_RETCODE graph_pseudoAncestors_addToNode(SCIP *, int, int, GRAPH *)
void graph_addPseudoAncestor(GRAPH *, int *)
int edges
Definition: graphdefs.h:219
static SCIP_RETCODE completemst5(SCIP *scip)
Definition: stptest_misc.c:691
SCIP_RETCODE stptest_completegraph(SCIP *scip)
Definition: stptest_misc.c:893
#define nnodes
Definition: gastrans.c:65
SCIP_RETCODE graph_init(SCIP *, GRAPH **, int, int, int)
Definition: graph_base.c:607
void cgraph_node_applyMinAdjCosts(CGRAPH *cgraph, int nodepos, int nodeid)
SCIP_RETCODE graph_pseudoAncestors_appendMoveEdge(SCIP *, int, int, SCIP_Bool, GRAPH *, SCIP_Bool *)
void graph_heap_correct(int, SCIP_Real, DHEAP *)
Definition: graph_util.c:1166
int * predecessors
Definition: completegraph.h:73
void cmst_computeMst(const CGRAPH *cgraph, int mstroot, CMST *cmst)