Scippy

SCIP

Solving Constraint Integer Programs

validate.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-2015 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 email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file portab.h
17  * @brief Method to validate Steiner problem solutions
18  * @author Thorsten Koch
19  * @author Gerald Gamrath
20  * @author Daniel Rehfeldt
21  *
22  */
23 
24 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <math.h>
30 #include <assert.h>
31 #include "grph.h"
32 #include "portab.h"
33 
34 #if 0
35 static void show(
36  GRAPH* g,
37  int vars,
38  char* state,
39  double* xval)
40 {
41  int i;
42  for(i = 0; i < vars; i++)
43  {
44  if (xval[i] > 1e-6)
45  {
46  fprintf(stderr, "%d-%d, xval[%d]=%g (%d)\n",
47  g->tail[i % g->edges] + 1,
48  g->head[i % g->edges] + 1,
49  i,
50  xval[i],
51  state[i]);
52  }
53  }
54 }
55 #endif
56 
57 static int nail(
58  const GRAPH* g,
59  const double* xval)
60 {
61  double sum;
62  int i;
63  int l;
64  int ind;
65 
66  assert(g != NULL);
67  assert(xval != NULL);
68 
69  if (g->layers == 1)
70  return(TRUE);
71 
72  for(i = 0; i < g->edges; i += 2)
73  {
74  sum = 0.0;
75 
76  for(l = 0; l < g->layers; l++)
77  {
78  ind = l * g->edges + i;
79  sum += xval[ind] + xval[ind + 1];
80  }
81  assert(sum >= -EPSILON);
82 
83 #ifdef WITH_CAPACITIES
84  assert(g->capa[i] > 0);
85 
86  if (sum - EPSILON > (double)g->capa[i])
87  return(FALSE);
88 #else
89  if (sum - EPSILON > 1.0)
90  return(FALSE);
91 #endif
92  }
93  return(TRUE);
94 }
95 #if 1
96 /*---------------------------------------------------------------------------*/
97 /*--- Name : Trail ---*/
98 /*--- Function : Durchlaeuft einen Graphen entsprechend einer Loesung und ---*/
99 /*--- stellt fest ob er bei allen Knoten vorbeikommt ---*/
100 /*--- Parameter: Startknoten, Loesung, Herkunft, Schongewesenliste ---*/
101 /*--- Returns : Nichts ---*/
102 /*---------------------------------------------------------------------------*/
103 static void trail(
104  const GRAPH* g,
105  int i,
106  const double* xval,
107  int tail,
108  char* connected,
109  int hop,
110  int max_hops)
111 {
112  int k;
113 
114  assert(connected[i] >= 0);
115 
116  if( connected[i] < 2 )
117  {
118  ++(connected[i]);
119 
120  if ((connected[i] < 2) && (hop < max_hops))
121  {
122  for(k = g->outbeg[i]; k != EAT_LAST; k = g->oeat[k])
123  if ((g->head[k] != tail) && (xval[k] + EPSILON > 1.0))
124  trail(g, g->head[k], xval, i, connected, hop + 1, max_hops);
125  }
126  }
127 }
128 #endif
129 #if 0
130 /*---------------------------------------------------------------------------*/
131 /*--- Name : Trail ---*/
132 /*--- Function : Durchlaeuft einen Graphen entsprechend einer Loesung und ---*/
133 /*--- stellt fest ob er bei allen Knoten vorbeikommt ---*/
134 /*--- Parameter: Startknoten, Loesung, Herkunft, Schongewesenliste ---*/
135 /*--- Returns : Nichts ---*/
136 /*---------------------------------------------------------------------------*/
137 static void trail2(
138  const GRAPH* g,
139  int layer,
140  const double* xval,
141  char* connected,
142  int max_hops)
143 {
144  int* stackstart = malloc((size_t)g->knots * sizeof(int));
145  int* stackedge = malloc((size_t)g->knots * sizeof(int));
146  int* stacktail = malloc((size_t)g->knots * sizeof(int));
147  int k;
148  int i = g->source[layer];
149  int stacksize = 1;
150 
151  stackstart[0] = i;
152  stackedge[0] = g->outbeg[i];
153  stacktail[0] = -1;
154 
155  while( stacksize > 0 )
156  {
157  k = stackedge[stacksize-1];
158 
159  printf("stacksize: %d, edge %d: %d --> %d\n", stacksize, k, g->tail[k], g->head[k]);
160 
161  if ( k == EAT_LAST )
162  {
163  --stacksize;
164  }
165  else if ((g->head[k] != stacktail[stacksize-1]) && (xval[k] + EPSILON > 1.0))
166  {
167  assert(connected[g->head[k]] >= 0);
168  if( connected[g->head[k]] < 2 )
169  {
170  ++(connected[g->head[k]]);
171 
172  if ((connected[i] < 2) && (stacksize < max_hops + 1))
173  {
174  stackstart[stacksize] = g->head[k];
175  stackedge[stacksize] = g->outbeg[g->head[k]];
176  stacktail[stacksize] = stackstart[stacksize-1];
177 
178  printf("stack: size=%d start[%d]=%d, edge[%d]=%d, tail[%d]=%d\n",
179  stacksize+1, stacksize, stackstart[stacksize], stacksize, stackedge[stacksize],
180  stacksize, stacktail[stacksize]);
181 
182  ++stacksize;
183  continue;
184  }
185  }
186  }
187  if (stacksize > 0)
188  stackedge[stacksize-1] = g->oeat[k];
189  }
190 
191  free(stacktail);
192  free(stackedge);
193  free(stackstart);
194 
195  printf("done\n");
196 }
197 #endif
198 /*---------------------------------------------------------------------------*/
199 /*--- Name : Validate Solution ---*/
200 /*--- Function : Stellt fuer eine (Teil-)Loesung fest, ob sie zulaessig ---*/
201 /*--- unzulaessig oder schon eine vollstaendige Loesung ist ---*/
202 /*--- Parameter: Graph, Loesung. ---*/
203 /*--- Returns : TRUE / FALSE ---*/
204 /*---------------------------------------------------------------------------*/
205 /** validates whether a (LP) solution is feasible */
206 SCIP_RETCODE SCIPvalidateStpSol(
207  SCIP* scip,
208  const GRAPH* g,
209  const double* xval,
210  SCIP_Bool* feasible
211  )
212 {
213  char* connected;
214  int ret = TRUE;
215  int i;
216  int layer;
217  int deg;
218  int e;
219  assert(g != NULL);
220 
221  if( g->knots == 1 )
222  {
223  *feasible = TRUE;
224  return SCIP_OKAY;
225  }
226 
227  assert(xval != NULL);
228 
229  SCIP_CALL( SCIPallocClearBufferArray(scip, &connected, g->knots) );
230 
231  *feasible = FALSE;
232  for(layer = 0; ret && (layer < g->layers); layer++)
233  {
234 #if 0
235  if (layer > 0)
236  memset(connected, 0, (size_t)g->knots * sizeof(char));
237 #endif
238 #if 1
239  trail(g, g->source[layer], xval + layer * g->edges, -1,
240  connected,
241  0, 1000000000);
242 #else
243  trail2(g, layer, xval + layer * g->edges, connected, 1000000000);
244 #endif
245  for(i = 0; i < g->knots; i++)
246  {
247  if( g->stp_type == STP_DEG_CONS )
248  {
249  deg = 0;
250  for( e = g->outbeg[i]; e != EAT_LAST ; e = g->oeat[e] )
251  if( EQ(xval[e], 1.0) || EQ(xval[flipedge(e)], 1.0) )
252  deg++;
253 
254  if( deg > g->maxdeg[i] )
255  {
256  ret = FALSE;
257  SCIPdebugMessage("deg condition violated \n");
258  break;
259  }
260 
261  }
262  /* circle? */
263  if( connected[i] >= 2)
264  {
265  ret = FALSE;
266  break;
267  }
268 
269  /* vertex not reached? */
270  if ((g->grad[i] > 0) && (g->term[i] == layer) && !connected[i])
271  {
272  ret = FALSE;
273  break;
274  }
275  }
276  }
277  SCIPfreeBufferArray(scip, &connected);
278 
279  if( ret )
280  ret = nail(g, xval);
281 
282  /* SCIP-Heuristiken können (z.B. durch Runden) Lösungen konstruieren, die einen Kreis aus Steiner-Knoten enthalten, der
283  * nicht zum Baum gehört
284  */
285 #if 0
286 #ifndef NDEBUG
287  /* Test ob alle Kanten nur in eine Richtung benutzt werden.
288  */
289  if (ret)
290  {
291  int e;
292 
293  for(e = 0; e < g->edges; e += 2)
294  if ((xval[e] > EPSILON) && (xval[e + 1] > EPSILON))
295  /* CONSTCOND */
296  assert(FALSE);
297  }
298 #endif
299 #endif
300  *feasible = (SCIP_Bool) ret;
301  return SCIP_OKAY;
302 }
Definition: grph.h:55
#define TRUE
Definition: portab.h:34
#define EAT_LAST
Definition: grph.h:31
int * oeat
Definition: grph.h:100
static int nail(const GRAPH *g, const double *xval)
Definition: validate.c:57
int * head
Definition: grph.h:94
#define FALSE
Definition: portab.h:37
#define EQ(a, b)
Definition: portab.h:62
int stp_type
Definition: grph.h:123
int * outbeg
Definition: grph.h:77
int * maxdeg
Definition: grph.h:79
#define EPSILON
Definition: portab.h:31
int * tail
Definition: grph.h:93
int * term
Definition: grph.h:69
int knots
Definition: grph.h:61
#define STP_DEG_CONS
Definition: grph.h:43
includes various files containing graph methods used for Steiner problems
Portable defintions.
int layers
Definition: grph.h:64
int * grad
Definition: grph.h:74
static void trail(const GRAPH *g, int i, const double *xval, int tail, char *connected, int hop, int max_hops)
Definition: validate.c:103
int * source
Definition: grph.h:67
int edges
Definition: grph.h:89
#define flipedge(edge)
Definition: grph.h:143
SCIP_RETCODE SCIPvalidateStpSol(SCIP *scip, const GRAPH *g, const double *xval, SCIP_Bool *feasible)
Definition: validate.c:206