Scippy

SCIP

Solving Constraint Integer Programs

reader_cmin.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-2024 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file reader_cmin.c
26 * @brief cmin file reader
27 * @author Stefan Heinz
28 */
29
30/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31
32#include <stdlib.h>
33#include <assert.h>
34#include <string.h>
35#if defined(_WIN32) || defined(_WIN64)
36#else
37#include <strings.h>
38#endif
39#include <ctype.h>
40
41#include "scip/cons_linear.h"
42#include "scip/cons_setppc.h"
43#include "scip/cons_knapsack.h"
44
45#include "cons_optcumulative.h"
46#include "heur_optcumulative.h"
47#include "reader_cmin.h"
48
49#define READER_NAME "cminreader"
50#define READER_DESC "file reader for cmin file format"
51#define READER_EXTENSION "cmin"
52
53#define DEFAULT_FILENAME "-" /**< name of the file including best known solutions */
54#define DEFAULT_DUALREDUCTION TRUE /**< add locks to avoid dual reductions */
55#define DEFAULT_MIP FALSE /**< create a MIP formulation */
56#define DEFAULT_INITIAL TRUE /**< should model constraints be in initial LP? */
57#define DEFAULT_CIP TRUE /**< create a CIP formulation */
58#define DEFAULT_RELAXATION 3 /**< which relaxation should be added to the maseter (0: none; 1: single; 2: edge-finding; 3: energetic-reasoning */
59
60static const char delimchars[] = " \f\n\r\t\v";
61
62
63/*
64 * Local methods
65 */
66
67/** CP reading data */
69{
72 char* token;
76};
77typedef struct CminInput CMININPUT;
78
79/** issues an error message and marks the LP data to have errors */
80static
82 SCIP* scip, /**< SCIP data structure */
83 CMININPUT* cmininput, /**< CMIN reading data */
84 const char* msg /**< error message */
85 )
86{
87 assert(cmininput != NULL);
88
89 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error in line %d: %s ('%s')\n",
90 cmininput->linenumber, msg, cmininput->token);
91
92 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s\n", cmininput->linebuf);
93
94 cmininput->haserror = TRUE;
95}
96
97/** gets the next line out of the file stream */
98static
100 CMININPUT* cmininput /**< CMIN reading data */
101 )
102{
103 char* pch;
104 assert( cmininput->haserror == FALSE );
105
106 /* clear the line */
108
109 if( SCIPfgets(cmininput->linebuf, (int) sizeof(cmininput->linebuf), cmininput->file) == NULL )
110 return FALSE;
111
112 cmininput->linenumber++;
113 cmininput->linepos = 0;
114
115 cmininput->linebuf[SCIP_MAXSTRLEN-1] = '\0';
116
117 pch = strstr (cmininput->linebuf, "\n");
118 if( pch != NULL )
119 *pch = '\0';
120
121 if (cmininput->linebuf[0] != '\0')
122 {
123 SCIPdebugMessage("input line %d: <%s>\n", cmininput->linenumber, cmininput->linebuf);
124 return TRUE;
125 }
126
127 return FALSE;
128}
129
130/** returns whether the given character is a token delimiter */
131static
133 char c /**< input character */
134 )
135{
136 return (c == '\0') || (strchr(delimchars, c) != NULL);
137}
138
139/** reads the next token from the input file into the token buffer; returns whether a token was read */
140static
142 CMININPUT* cmininput /**< CMIN reading data */
143 )
144{
145 char* buf;
146 int tokenlen;
147
148 assert(cmininput != NULL);
149
150 /* skip delimiters */
151 buf = cmininput->linebuf;
152 while( isDelimChar(buf[cmininput->linepos]) )
153 {
154 if( buf[cmininput->linepos] == '\0' )
155 {
156 if( !getNextLine(cmininput) )
157 {
158 SCIPdebugMessage("(line %d) end of file\n", cmininput->linenumber);
159 return FALSE;
160 }
161 assert(cmininput->linepos == 0);
162 }
163 else
164 cmininput->linepos++;
165 }
166 assert(cmininput->linepos < SCIP_MAXSTRLEN);
167 assert(!isDelimChar(buf[cmininput->linepos]));
168
169 /* read value token */
170 tokenlen = 0;
171 while( isdigit(buf[cmininput->linepos]) )
172 {
173 assert(tokenlen < SCIP_MAXSTRLEN);
174 assert(!isDelimChar(buf[cmininput->linepos]));
175 cmininput->token[tokenlen] = buf[cmininput->linepos];
176 tokenlen++;
177 cmininput->linepos++;
178 }
179
180 assert(tokenlen < SCIP_MAXSTRLEN);
181 cmininput->token[tokenlen] = '\0';
182
183 SCIPdebugMessage("(line %d) read token: '%s'\n", cmininput->linenumber, cmininput->token);
184
185 return TRUE;
186}
187
188/** method parses the best known solution for the total leftover out of the give file; if file does not exist or the
189 * problem is not listed the best known solution is set to -1 which means unknown
190 */
191static
193 SCIP* scip, /**< SCIP data structure */
194 SCIP_Real* objval /**< pointer to store best known solution */
195 )
196{
198 const char* probname;
199 SCIP_Bool found;
200 char* solufile;
201 char buffer[SCIP_MAXSTRLEN];
202 char* token;
203 char* saveptr;
204
205 assert(scip != NULL);
206 assert(objval != NULL);
207
208 /* get solution file */
209 SCIP_CALL( SCIPgetStringParam(scip, "reading/"READER_NAME"/filename", &solufile) );
210
211 /* set objective value to unknown */
212 (*objval) = SCIPinfinity(scip);
213
214 if( *solufile == '-')
215 return SCIP_OKAY;
216
217 if( NULL == (file = SCIPfopen(solufile, "r")) )
218 {
219 SCIPwarningMessage(scip, "solution file <%s> does not exist\n", solufile);
220 return SCIP_OKAY;
221 }
222
223 /* get problem name */
224 probname = SCIPgetProbName(scip);
225 found = FALSE;
226
227 /* parse file line by line */
228 while( SCIPfgets(buffer, (int) sizeof(buffer), file) != NULL )
229 {
230 char status[SCIP_MAXSTRLEN];
231
232 SCIPdebugMessage("parse line <%s>\n", buffer);
233
234 /* solution status */
235 token = SCIPstrtok(buffer, " \n\t", &saveptr);
236 (void)SCIPsnprintf(status, SCIP_MAXSTRLEN, "%s", token);
237
238 /* problem name */
239 token = SCIPstrtok(NULL, " \n\t", &saveptr);
240
241 /* check if found the right line for the requested problem */
242 if( strncmp(token, probname, strlen(token)+1) == 0 )
243 {
244 SCIPdebugMessage("found problem <%s> in solution file <%s>\n", probname, solufile);
245
246 if( strncmp(status, "=opt=", 5) == 0 )
247 {
248 /* objective value */
249 token = SCIPstrtok(NULL, " \n\t", &saveptr);
250
251 (*objval) = atof(token);
252 found = TRUE;
253
254 SCIPdebugMessage("best known solution is <%g>\n", *objval);
255 }
256
257 break;
258 }
259 }
260
262
263 if( !found )
264 return SCIP_INVALIDCALL;
265
266 return SCIP_OKAY;
267}
268
269#ifdef SCIP_DEBUG
270/** display input data */
271static
272void displayInputData(
273 SCIP* scip, /**< SCIP data structure */
274 int** durations, /**< durations */
275 int** demands, /**< demands */
276 int** costs, /**< cost */
277 int* capacities, /**< machine capacities */
278 int* releasedates, /**< release dates */
279 int* deadlinedates, /**< deadline dates */
280 int njobs, /**< number of jobs */
281 int nmachines /**< number of machines */
282 )
283{
284 int j;
285 int m;
286
287 for( j = 0; j < njobs; ++j )
288 {
289 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Job %2d [%3d,%3d] ", j, releasedates[j], deadlinedates[j]);
290
291 for( m = 0; m < nmachines; ++m )
292 {
293 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "(%2d,%2d)" , durations[m][j], demands[m][j]);
294 }
296 }
297}
298#endif
299
300/** initialize the sorted event point arrays */
301static
303 SCIP* scip, /**< SCIP data structure */
304 int* releasedates, /**< release dates */
305 int* deadlinedates, /**< deadline dates */
306 int* starttimes, /**< array to store sorted start events */
307 int* endtimes, /**< array to store sorted end events */
308 int* startindices, /**< permutation with rspect to the start times */
309 int* endindices, /**< permutation with rspect to the end times */
310 int njobs /**< number of jobs */
311 )
312{
313 int j;
314
315 /* assign variables, start and endpoints to arrays */
316 for ( j = 0; j < njobs; ++j )
317 {
318 starttimes[j] = releasedates[j];
319 startindices[j] = j;
320
321 endtimes[j] = deadlinedates[j];
322 endindices[j] = j;
323 }
324
325 /* sort the arrays not-decreasing according to startsolvalues and endsolvalues (and sort the indices in the same way) */
326 SCIPsortIntInt(starttimes, startindices, njobs);
327 SCIPsortIntInt(endtimes, endindices, njobs);
328}
329
330/** computes the maximum energy for all variables which correspond to jobs which start between the given start time and
331 * end time
332 *
333 * @return Maximum energy for the given time window
334 */
335static
337 int njobs, /**< number of jobs */
338 int* durations, /**< durations */
339 int* demands, /**< demands */
340 int* releasedates, /**< release dates */
341 int* deadlinedates, /**< deadline dates */
342 int starttime, /**< start time */
343 int endtime /**< end time */
344 )
345{
346 SCIP_Longint maxenergy;
347 int v;
348
349 assert(starttime < endtime);
350 maxenergy = 0LL;
351
352 for( v = 0; v < njobs; ++v )
353 {
354 /* collect jobs which run between the start and end time */
355 if( deadlinedates[v] <= endtime && releasedates[v] >= starttime)
356 maxenergy += (SCIP_Longint)(durations[v] * demands[v]); /*lint !e647*/
357 }
358
359 return maxenergy;
360}
361
362/** remove row which have a tightness which is smaller or equal to the given one
363 *
364 * @return The number of remaining rows
365 */
366static
368 SCIP_Longint* rowtightness, /**< array containing the tightness for the previously selected rows */
369 int* startidxs, /**< array containing for each row the index for the start event */
370 int nrows, /**< current number of rows */
371 SCIP_Longint tightness /**< tightness to use to detect redundant rows */
372 )
373{
374 int keptrows;
375 int j;
376
377 keptrows = 0;
378
379 for( j = 0; j < nrows; ++j )
380 {
381 rowtightness[keptrows] = rowtightness[j];
382 startidxs[keptrows] = startidxs[j];
383
384 /* only keep this row if the tightness is better as the (current) given one */
385 if( rowtightness[j] > tightness )
386 keptrows++;
387 }
388
389 return keptrows;
390}
391
392/** create interval relaxation for given sub-problem */
393static
395 SCIP* scip, /**< SCIP data structure */
396 int relaxation, /**< a linear relaxation base on edge-finding idea or energetic-reasoning idea */
397 int resource, /**< resource id */
398 SCIP_VAR** vars, /**< assignment variables */
399 int* durations, /**< durations */
400 int* demands, /**< demands */
401 int capacity, /**< machine capacity */
402 int* releasedates, /**< release dates */
403 int* deadlinedates, /**< deadline dates */
404 int njobs /**< number of jobs */
405 )
406{
407 SCIP_Longint** rowtightness;
408 int** startidxs;
409 int* nrows;
410 int* starttimes;
411 int* endtimes;
412 int* startindices;
413 int* endindices;
414 int starttime;
415 int endtime;
416 int i;
417 int j;
418
419 int naddedcons;
420
421 SCIP_CALL( SCIPallocBufferArray(scip, &starttimes, njobs) );
422 SCIP_CALL( SCIPallocBufferArray(scip, &startindices, njobs) );
423 SCIP_CALL( SCIPallocBufferArray(scip, &endtimes, njobs) );
424 SCIP_CALL( SCIPallocBufferArray(scip, &endindices, njobs) );
425
426 SCIP_CALL( SCIPallocBufferArray(scip, &nrows, njobs) );
427 BMSclearMemoryArray(nrows, njobs);
428 SCIP_CALL( SCIPallocBufferArray(scip, &rowtightness, njobs) );
429 SCIP_CALL( SCIPallocBufferArray(scip, &startidxs, njobs) );
430 for( j = 0; j < njobs; ++j )
431 {
432 SCIP_CALL( SCIPallocBufferArray(scip, &rowtightness[j], njobs) ); /*lint !e866*/
433 SCIP_CALL( SCIPallocBufferArray(scip, &startidxs[j], njobs) ); /*lint !e866*/
434 }
435
436 createSortedEventpoints(scip, releasedates, deadlinedates, starttimes, endtimes, startindices, endindices, njobs);
437
438 starttime = -INT_MAX;
439
440 /* check each startpoint of a job whether the capacity is kept or not */
441 for( j = 0; j < njobs; ++j )
442 {
443 SCIP_Longint besttightness;
444
445 assert(starttime <= starttimes[j]);
446
447 /* if we hit the same start time again we skip the loop */
448 if( starttime == starttimes[j])
449 continue;
450
451 starttime = starttimes[j];
452 endtime = -INT_MAX;
453 besttightness = 0LL;
454
455 for( i = 0; i < njobs; ++i )
456 {
457 SCIP_Longint energy;
458 SCIP_Longint maxenergy;
459 SCIP_Longint tightness;
460
461 assert(endtime <= endtimes[i]);
462
463 /* if we hit the same end time again we skip the loop */
464 if( endtime == endtimes[i] )
465 continue;
466
467 endtime = endtimes[i];
468
469 /* skip all end times which are smaller than the start time */
470 if( endtime <= starttime )
471 continue;
472
473 maxenergy = computeMaxEnergy(njobs, durations, demands, releasedates, deadlinedates, starttime, endtime);
474
475 energy = (endtime - starttime) * capacity; /*lint !e647*/
476 tightness = maxenergy - energy;
477
478 /* check if the linear constraint is not trivially redundant */
479 if( tightness > besttightness )
480 {
481 besttightness = tightness;
482
483 nrows[i] = removeRedundantRows(rowtightness[i], startidxs[i], nrows[i], tightness);
484
485 /* add row information */
486 rowtightness[i][nrows[i]] = tightness;
487 startidxs[i][nrows[i]] = j;
488 nrows[i]++;
489 }
490 }
491 }
492
493 naddedcons = 0;
494
495 for( j = njobs-1; j >= 0; --j )
496 {
497 for( i = 0; i < nrows[j]; ++i )
498 {
499 SCIP_CONS* cons;
500 SCIP_Longint energy;
501 char name[SCIP_MAXSTRLEN];
502 int v;
503
504 starttime = starttimes[startidxs[j][i]];
505 endtime = endtimes[j];
506
507 energy = (endtime - starttime) * capacity; /*lint !e647*/
508
509 SCIPdebugMessage("create linear relaxation for time interval [%d,%d] <= %"SCIP_LONGINT_FORMAT" (tightness %"SCIP_LONGINT_FORMAT")\n",
510 starttime, endtime, energy, rowtightness[j][i]);
511
512 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "relax_%d_start_%d_end_%d", resource, starttime, endtime);
513 SCIP_CALL( SCIPcreateConsBasicKnapsack(scip, &cons, name, 0, NULL, NULL, energy) );
514
515 for( v = 0; v < njobs; ++v)
516 {
517 int overlap;
518 int duration;
519
520 duration = durations[v];
521 overlap = MIN(endtime - starttime, duration);
522 assert(overlap > 0);
523 overlap = MIN3(overlap, releasedates[v] + duration - starttime, endtime - deadlinedates[v] + duration);
524
525 /* check for edge-finding idea */
526 if( relaxation == 2 && releasedates[v] >= starttime && deadlinedates[v] <= endtime )
527 {
528 assert(duration == overlap);
529 SCIP_CALL( SCIPaddCoefKnapsack(scip, cons, vars[v], (SCIP_Longint)(duration * demands[v])) ); /*lint !e647*/
530 }
531 else if( relaxation == 3 && overlap > 0 )
532 {
533 assert(overlap <= duration);
534 SCIP_CALL( SCIPaddCoefKnapsack(scip, cons, vars[v], (SCIP_Longint)(overlap * demands[v])) ); /*lint !e647*/
535 }
536 }
537
538 SCIP_CALL( SCIPaddCons(scip, cons) );
539 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
540 naddedcons++;
541 }
542 }
543
544 SCIPinfoMessage(scip, NULL, "add %d constraint as relaxation\n", naddedcons);
545
546 /* free buffers */
547 for( j = njobs-1; j >= 0; --j )
548 {
549 SCIPfreeBufferArray(scip, &startidxs[j]);
550 SCIPfreeBufferArray(scip, &rowtightness[j]);
551 }
552 SCIPfreeBufferArray(scip, &startidxs);
553 SCIPfreeBufferArray(scip, &rowtightness);
554 SCIPfreeBufferArray(scip, &nrows);
555
556 SCIPfreeBufferArray(scip, &endindices);
557 SCIPfreeBufferArray(scip, &endtimes);
558 SCIPfreeBufferArray(scip, &startindices);
559 SCIPfreeBufferArray(scip, &starttimes);
560
561 return SCIP_OKAY;
562}
563
564/** create MIP formulation and CP constraints */
565static
567 SCIP* scip, /**< SCIP data structure */
568 int** durations, /**< durations */
569 int** demands, /**< demands */
570 int** costs, /**< cost */
571 int* capacities, /**< machine capacities */
572 int* releasedates, /**< release dates */
573 int* deadlinedates, /**< deadline dates */
574 int njobs, /**< number of jobs */
575 int nmachines /**< number of machines */
576 )
577{
578 SCIP_VAR*** vars;
579 SCIP_CONS*** conss;
580 SCIP_CONS* cons;
581
582 char name[SCIP_MAXSTRLEN];
583
584 int relaxation;
585 int maxtime;
586 int i;
587 int j;
588 int t;
589
590 SCIP_CALL( SCIPgetIntParam(scip, "reading/"READER_NAME"/relaxation", &relaxation) );
591
592 /* compute maximum time */
593 maxtime = 0;
594 for( j = 0; j < njobs; ++j )
595 {
596 maxtime = MAX(maxtime, deadlinedates[j]);
597 }
598
599 SCIP_CALL( SCIPallocBufferArray(scip, &conss, nmachines) );
600
601 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nmachines) );
602
603 /* create master problem */
604 for( i = 0; i < nmachines; ++i )
605 {
606 SCIP_CALL( SCIPallocBufferArray(scip, &vars[i], njobs) ); /*lint !e866*/
607
608 for( j = 0; j < njobs; ++j )
609 {
610 SCIP_VAR* var;
611 SCIP_Real objval;
612 SCIP_Real ub;
613
614 objval = (SCIP_Real)costs[i][j];
615
616 /* construct variable name */
617 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_machine_%d", j, i);
618
619 if( releasedates[j] > deadlinedates[j] - durations[i][j] || demands[i][j] > capacities[i] )
620 ub = 0.0;
621 else
622 ub = 1.0;
623
624 /* create binary variable */
625 SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, 0.0, ub, objval, SCIP_VARTYPE_BINARY) );
626 vars[i][j] = var;
627
628 /* add and release binary variable */
629 SCIP_CALL( SCIPaddVar(scip, var) );
630 SCIP_CALL( SCIPreleaseVar(scip, &var) );
631 }
632 }
633
634 for( j = 0; j < njobs; ++j )
635 {
636 /* construct constraint name */
637 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_to_one_machine", j);
638 SCIP_CALL( SCIPcreateConsBasicSetpart(scip, &cons, name, 0, NULL) );
639
640 for( i = 0; i < nmachines; ++i )
641 {
642 SCIP_CALL( SCIPaddCoefSetppc(scip, cons, vars[i][j]) );
643 }
644
645 SCIP_CALL( SCIPaddCons(scip, cons) );
646 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
647 }
648
649 /* create for each machines and time point a knapsack constraint */
650 for( i = 0; i < nmachines; ++i )
651 {
652 SCIP_CALL( SCIPallocBufferArray(scip, &conss[i], maxtime) ); /*lint !e866*/
653
654 for( t = 0; t < maxtime; ++t )
655 {
656 /* construct constraint name */
657 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "machines_%d_time_%d", i, t);
658
659 SCIP_CALL( SCIPcreateConsBasicKnapsack(scip, &cons, name, 0, NULL, NULL, (SCIP_Longint)capacities[i]) );
660 SCIP_CALL( SCIPaddCons(scip, cons) );
661
662 conss[i][t] = cons;
663
664 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
665 }
666 }
667
668 /* create for each job/machine/timepoint a binary variables */
669 for( j = 0; j < njobs; ++j )
670 {
671 int est;
672
673 est = releasedates[j];
674
675 for( i = 0; i < nmachines; ++i )
676 {
677 int lst;
678
679 lst = deadlinedates[j] - durations[i][j];
680
681 /* construct constraint name */
682 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_machine_%d", j, i);
683
684 SCIP_CALL( SCIPcreateConsBasicLinear(scip, &cons, name, 0, NULL, NULL, 0.0, 0.0) );
685 SCIP_CALL( SCIPaddCoefLinear(scip, cons, vars[i][j], -1.0) );
686
687 for( t = est; t <= lst; ++t )
688 {
689 SCIP_VAR* var;
690 int h;
691
692 /* construct variable name */
693 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_machine_%d_time_%d", j, i, t);
694
695 SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY) );
696
697 SCIP_CALL( SCIPaddVar(scip, var) );
698
699 /* add variable to linear constraint */
700 SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, 1.0) );
701
702 for( h = t ; h < MIN(t + durations[i][j], maxtime); ++h )
703 {
704 SCIP_CALL( SCIPaddCoefKnapsack(scip, conss[i][h], var, (SCIP_Longint)demands[i][j] ) );
705 }
706
707 SCIP_CALL( SCIPreleaseVar(scip, &var) );
708 }
709
710 SCIP_CALL( SCIPaddCons(scip, cons) );
711 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
712 }
713 }
714
715 /* free constraint buffers */
716 for( i = nmachines - 1; i >= 0; --i )
717 {
718 SCIPfreeBufferArray(scip, &conss[i]);
719 }
720 SCIPfreeBufferArray(scip, &conss);
721
722 if( relaxation == 1 )
723 {
724 /* create for each optimal resource a singe constraint relaxation */
725 for( i = 0; i < nmachines; ++i )
726 {
727 SCIP_Longint capacity;
728 int est;
729 int lct;
730
731 est = INT_MAX;
732 lct = INT_MIN;
733
734 /* compute earliest start end latest completion time */
735 for( j = 0; j < njobs; ++j )
736 {
737 if( demands[i][j] > 0 )
738 {
739 est = MIN(est, releasedates[j]);
740 lct = MAX(lct, deadlinedates[j]);
741 }
742 }
743
744 /* construct constraint name */
745 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "relax_%d", i);
746
747 capacity = capacities[i] * (lct - est); /*lint !e647*/
748
749 SCIP_CALL( SCIPcreateConsBasicKnapsack(scip, &cons, name, 0, NULL, NULL, capacity) );
750
751 for( j = 0; j < njobs; ++j )
752 {
753 if( demands[i][j] > 0 )
754 {
755 SCIP_CALL( SCIPaddCoefKnapsack(scip, cons, vars[i][j], (SCIP_Longint)(durations[i][j] * demands[i][j]) ) ); /*lint !e647*/
756 }
757 }
758
759 /* add the constraint to the problem and release it (locally) */
760 SCIP_CALL( SCIPaddCons(scip, cons) );
761 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
762 }
763 }
764 else if( relaxation >= 2 )
765 {
766 /* create for each optimal resource a singe constraint relaxation */
767 for( i = 0; i < nmachines; ++i )
768 {
769 SCIP_CALL( createIntervalRelaxation(scip, relaxation, i, vars[i], durations[i], demands[i], capacities[i], releasedates, deadlinedates, njobs) );
770 }
771 }
772
773 for( i = nmachines-1; i >= 0; --i )
774 {
775 SCIPfreeBufferArray(scip, &vars[i]);
776 }
778
779 return SCIP_OKAY;
780}
781
782/** create MIP formulation */
783static
785 SCIP* scip, /**< SCIP data structure */
786 int** durations, /**< durations */
787 int** demands, /**< demands */
788 int** costs, /**< cost */
789 int* capacities, /**< machine capacities */
790 int* releasedates, /**< release dates */
791 int* deadlinedates, /**< deadline dates */
792 int njobs, /**< number of jobs */
793 int nmachines /**< number of machines */
794 )
795{
796 SCIP_CONS*** conss;
797 SCIP_CONS* cons;
798 SCIP_VAR*** binvars;
799 SCIP_VAR*** vars;
800 SCIP_VAR* var;
801 int* nnvars;
802 int** localdemands;
803 int** localdurations;
804
805 char name[SCIP_MAXSTRLEN];
806
807 int maxtime;
808 int i;
809 int j;
810 int t;
811
812 /* compute maximum time */
813 maxtime = 0;
814 for( j = 0; j < njobs; ++j )
815 {
816 maxtime = MAX(maxtime, deadlinedates[j]);
817 }
818
819 SCIP_CALL( SCIPallocBufferArray(scip, &conss, nmachines) );
820 SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nmachines) );
821 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nmachines) );
822 SCIP_CALL( SCIPallocBufferArray(scip, &localdemands, nmachines) );
823 SCIP_CALL( SCIPallocBufferArray(scip, &localdurations, nmachines) );
824
825 SCIP_CALL( SCIPallocBufferArray(scip, &nnvars, nmachines) );
826 BMSclearMemoryArray(nnvars, nmachines);
827
828 /* create for each machines and time point a knapsack constraint */
829 for( i = 0; i < nmachines; ++i )
830 {
831 SCIP_CALL( SCIPallocBufferArray(scip, &conss[i], maxtime) ); /*lint !e866*/
832
833 for( t = 0; t < maxtime; ++t )
834 {
835 /* construct constraint name */
836 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "machines_%d_time_%d", i, t);
837
838 SCIP_CALL( SCIPcreateConsKnapsack(scip, &cons, name, 0, NULL, NULL, (SCIP_Longint)capacities[i],
840 SCIP_CALL( SCIPaddCons(scip, cons) );
841
842 conss[i][t] = cons;
843
844 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
845 }
846
847 SCIP_CALL( SCIPallocBufferArray(scip, &binvars[i], njobs) ); /*lint !e866*/
848 SCIP_CALL( SCIPallocBufferArray(scip, &vars[i], njobs) ); /*lint !e866*/
849 SCIP_CALL( SCIPallocBufferArray(scip, &localdemands[i], njobs) ); /*lint !e866*/
850 SCIP_CALL( SCIPallocBufferArray(scip, &localdurations[i], njobs) ); /*lint !e866*/
851 }
852
853 for( j = 0; j < njobs; ++j )
854 {
855 SCIP_CONS* maccons;
856 int est;
857
858 est = releasedates[j];
859
860 /* construct constraint name */
861 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d", j);
862
863 SCIP_CALL( SCIPcreateConsSetpart(scip, &cons, name, 0, NULL,
865
866 for( i = 0; i < nmachines; ++i )
867 {
868 SCIP_CONS* lincons;
869 int lst;
870 int idx;
871
872 lst = deadlinedates[j] - durations[i][j];
873
874 if( est > lst )
875 continue;
876
877 idx = nnvars[i];
878 nnvars[i]++;
879
880 /* construct constraint name */
881 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_machine_%d", j, i);
882
883 SCIP_CALL( SCIPcreateConsSetpart(scip, &maccons, name, 0, NULL,
885
886 /* construct variable name */
887 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_choose_%d", j, i);
888
889 SCIP_CALL( SCIPcreateVar(scip, &var, name, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
890 TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
891 SCIP_CALL( SCIPaddVar(scip, var) );
892 binvars[i][idx] = var;
893 SCIP_CALL( SCIPreleaseVar(scip, &var) );
894
895 SCIP_CALL( SCIPgetNegatedVar(scip, binvars[i][idx], &var) );
896
897 SCIP_CALL( SCIPaddCoefSetppc(scip, maccons, var) );
898
899 /* add variable to set partitioning constraint */
900 SCIP_CALL( SCIPaddCoefSetppc(scip, cons, binvars[i][idx]) );
901
902 /* construct variable name */
903 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_starts_%d", idx, i);
904
905 SCIP_CALL( SCIPcreateVar(scip, &var, name, 0.0, (SCIP_Real)lst, 0.0, SCIP_VARTYPE_IMPLINT,
906 TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
907
908 SCIP_CALL( SCIPaddVar(scip, var) );
909 vars[i][idx] = var;
910
911 SCIP_CALL( SCIPreleaseVar(scip, &var) );
912
913 /* construct constraint name */
914 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_machine_%d", idx, i);
915
916 SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, name, 0, NULL, NULL, 0.0, 0.0,
918
919 SCIP_CALL( SCIPaddCoefLinear(scip, lincons, vars[i][idx], -1.0) );
920
921 localdemands[i][idx] = demands[i][j];
922 localdurations[i][idx] = durations[i][j];
923
924 for( t = est; t <= lst; ++t )
925 {
926 int h;
927
928 /* construct variable name */
929 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_machine_%d_time_%d", j, i, t);
930
931 SCIP_CALL( SCIPcreateVar(scip, &var, name, 0.0, 1.0, (SCIP_Real)costs[i][j], SCIP_VARTYPE_BINARY,
932 TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
933
934 SCIP_CALL( SCIPaddVar(scip, var) );
935
936 /* add variable to linear linking constraint */
937 SCIP_CALL( SCIPaddCoefLinear(scip, lincons, var, (SCIP_Real)t) );
938
939 /* add variable to linear linking constraint */
940 SCIP_CALL( SCIPaddCoefSetppc(scip, maccons, var) );
941
942 for( h = t ; h < MIN(t + durations[i][j], maxtime); ++h )
943 {
944 SCIP_CALL( SCIPaddCoefKnapsack(scip, conss[i][h], var, (SCIP_Longint)demands[i][j] ) );
945 }
946
947 SCIP_CALL( SCIPreleaseVar(scip, &var) );
948 }
949
950 SCIP_CALL( SCIPaddCons(scip, lincons) );
951 SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
952
953 SCIP_CALL( SCIPaddCons(scip, maccons) );
954 SCIP_CALL( SCIPreleaseCons(scip, &maccons) );
955 }
956
957
958 SCIP_CALL( SCIPaddCons(scip, cons) );
959 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
960 }
961
962 /* create CP constraints */
963
964 for( i = 0; i < nmachines; ++i )
965 {
966 /* construct constraint name */
967 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "machine_%d", i);
968
969 /* create machine choice constraint */
970 SCIP_CALL( SCIPcreateConsOptcumulative(scip, &cons, name, nnvars[i], vars[i], binvars[i], localdurations[i], localdemands[i], capacities[i],
972 SCIP_CALL( SCIPaddCons(scip, cons) );
973 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
974 }
975
976
977 for( i = nmachines - 1; i >= 0; --i )
978 {
979 SCIPfreeBufferArray(scip, &localdurations[i]);
980 SCIPfreeBufferArray(scip, &localdemands[i]);
981 SCIPfreeBufferArray(scip, &vars[i]);
982 SCIPfreeBufferArray(scip, &binvars[i]);
983 SCIPfreeBufferArray(scip, &conss[i]);
984 }
985
986 SCIPfreeBufferArray(scip, &localdemands);
987 SCIPfreeBufferArray(scip, &localdurations);
988 SCIPfreeBufferArray(scip, &nnvars);
990 SCIPfreeBufferArray(scip, &binvars);
991 SCIPfreeBufferArray(scip, &conss);
992
993 return SCIP_OKAY;
994}
995
996/** create CIP formulation */
997static
999 SCIP* scip, /**< SCIP data structure */
1000 int** durations, /**< durations */
1001 int** demands, /**< demands */
1002 int** costs, /**< cost */
1003 int* capacities, /**< machine capacities */
1004 int* releasedates, /**< release dates */
1005 int* deadlinedates, /**< deadline dates */
1006 int njobs, /**< number of jobs */
1007 int nmachines /**< number of machines */
1008 )
1009{
1010 SCIP_CONS** conss;
1011 SCIP_CONS* cons;
1012 SCIP_VAR*** vars;
1013 SCIP_VAR*** binvars;
1014 SCIP_VAR* var;
1015 int* machines;
1016
1017 char name[SCIP_MAXSTRLEN];
1018
1019 SCIP_Real objval;
1020 SCIP_Bool dualreduction;
1021
1022 int relaxation;
1023 int i;
1024 int j;
1025
1026 SCIP_CALL( SCIPgetIntParam(scip, "reading/"READER_NAME"/relaxation", &relaxation) );
1027 SCIP_CALL( SCIPgetBoolParam(scip, "reading/"READER_NAME"/dualreduction", &dualreduction) );
1028
1029 SCIP_CALL( SCIPallocBufferArray(scip, &conss, njobs) );
1030
1031 /* create for each job a set partitioning constraint */
1032 for( j = 0; j < njobs; ++j )
1033 {
1034 /* construct constraint name */
1035 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d", j);
1036
1037 SCIP_CALL( SCIPcreateConsBasicSetpart(scip, &cons, name, 0, NULL) );
1038 SCIP_CALL( SCIPaddCons(scip, cons) );
1039 conss[j] = cons;
1040 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1041 }
1042
1043 SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nmachines) );
1044 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nmachines) );
1045 SCIP_CALL( SCIPallocBufferArray(scip, &machines, nmachines) );
1046
1047 for( i = 0; i < nmachines; ++i )
1048 {
1049 int nvars;
1050
1051 nvars = 0;
1052
1053 SCIP_CALL( SCIPallocBufferArray(scip, &binvars[i], njobs) ); /*lint !e866*/
1054 SCIP_CALL( SCIPallocBufferArray(scip, &vars[i], njobs) ); /*lint !e866*/
1055
1056 BMSclearMemoryArray(binvars[i], njobs); /*lint !e866*/
1057 BMSclearMemoryArray(vars[i], njobs); /*lint !e866*/
1058
1059 for( j = 0; j < njobs; ++j )
1060 {
1061 /* check if job is scheduleable on that machine */
1062 if(releasedates[j] + durations[i][j] > deadlinedates[j] || demands[i][j] > capacities[i] )
1063 continue;
1064
1065 /* construct variable name */
1066 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_choose_%d", j, i);
1067
1068 SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, 0.0, 1.0, (SCIP_Real)costs[i][j], SCIP_VARTYPE_BINARY) );
1069 SCIP_CALL( SCIPaddVar(scip, var) );
1070 binvars[i][nvars] = var;
1071 SCIP_CALL( SCIPreleaseVar(scip, &var) );
1072
1073 /* construct variable name */
1074 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "job_%d_starts_%d", j, i);
1075
1076 SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, (SCIP_Real)releasedates[j], (SCIP_Real)(deadlinedates[j] - durations[i][j]), 0.0, SCIP_VARTYPE_INTEGER) );
1077 SCIP_CALL( SCIPaddVar(scip, var) );
1078 vars[i][nvars] = var;
1079 SCIP_CALL( SCIPreleaseVar(scip, &var) );
1080
1081 if( !dualreduction )
1082 {
1083 SCIP_CALL( SCIPaddVarLocksType(scip, binvars[i][nvars], SCIP_LOCKTYPE_MODEL, 1, 1) );
1084 SCIP_CALL( SCIPaddVarLocksType(scip, vars[i][nvars], SCIP_LOCKTYPE_MODEL, 1, 1) );
1085 }
1086
1087 /* add choice variable to set partitioning constraint */
1088 SCIP_CALL( SCIPaddCoefSetppc(scip, conss[j], binvars[i][nvars]) );
1089
1090 demands[i][nvars] = demands[i][j];
1091 durations[i][nvars] = durations[i][j];
1092
1093 nvars++;
1094 }
1095
1096 machines[i] = nvars;
1097
1098 if( nvars > 0 )
1099 {
1100 SCIP_Bool initial;
1101 SCIP_Bool separate;
1102
1103 if( relaxation == 0 )
1104 {
1105 initial = FALSE;
1106 separate = FALSE;
1107 }
1108 else
1109 {
1110 initial = TRUE;
1111 separate = TRUE;
1112 }
1113
1114 /* construct constraint name */
1115 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "machine_%d", i);
1116
1117 /* create machine choice constraint */
1118 SCIP_CALL( SCIPcreateConsOptcumulative(scip, &cons, name, nvars, vars[i], binvars[i], durations[i], demands[i], capacities[i],
1119 initial, separate, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1120 SCIP_CALL( SCIPaddCons(scip, cons) );
1121 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1122 }
1123 }
1124
1125 SCIP_CALL( SCIPinitHeurOptcumulative(scip, nmachines, njobs, machines, binvars, vars, durations, demands, capacities) );
1126
1127 /* check for a given total leftover */
1129
1130 SCIP_CALL( SCIPsetObjlimit(scip, objval) );
1131
1132 /* free all buffers */
1133 for( i = 0; i < nmachines; ++i )
1134 {
1135 SCIPfreeBufferArray(scip, &vars[i]);
1136 SCIPfreeBufferArray(scip, &binvars[i]);
1137 }
1138 SCIPfreeBufferArray(scip, &machines );
1139 SCIPfreeBufferArray(scip, &vars );
1140 SCIPfreeBufferArray(scip, &binvars);
1141 SCIPfreeBufferArray(scip, &conss );
1142
1143 return SCIP_OKAY;
1144}
1145
1146/** read given file and create corresponding problem */
1147static
1149 SCIP* scip, /**< SCIP data structure */
1150 CMININPUT* cmininput, /**< CMIN reading data */
1151 const char* filename /**< file name */
1152 )
1153{
1154 int** durations;
1155 int** demands;
1156 int** costs;
1157 int* capacities;
1158 int* releasedates;
1159 int* deadlinedates;
1160
1161 int njobs;
1162 int nmachines;
1163
1164 int i;
1165 int j;
1166
1167 /* read the number of jobs */
1168 if( !getNextToken(cmininput) )
1169 {
1170 syntaxError(scip, cmininput, "missing number if jobs\n");
1171 return SCIP_OKAY;
1172 }
1173
1174 njobs = atoi(cmininput->token);
1175
1176 /* read the number of machines */
1177 if( !getNextToken(cmininput) )
1178 {
1179 syntaxError(scip, cmininput, "missing number of machines");
1180 return SCIP_OKAY;
1181 }
1182
1183 nmachines = atoi(cmininput->token);
1184
1185 SCIPdebugMessage("njobs <%d> nmachines <%d>\n", njobs, nmachines);
1186
1187 /* allocate all neccessary memory */
1188 SCIP_CALL( SCIPallocBufferArray(scip, &durations, nmachines) );
1189 SCIP_CALL( SCIPallocBufferArray(scip, &demands, nmachines) );
1190 SCIP_CALL( SCIPallocBufferArray(scip, &costs, nmachines) );
1191 for( i = 0; i < nmachines; ++i )
1192 {
1193 SCIP_CALL( SCIPallocBufferArray(scip, &durations[i], njobs) ); /*lint !e866*/
1194 SCIP_CALL( SCIPallocBufferArray(scip, &demands[i], njobs) ); /*lint !e866*/
1195 SCIP_CALL( SCIPallocBufferArray(scip, &costs[i], njobs) ); /*lint !e866*/
1196 }
1197 SCIP_CALL( SCIPallocBufferArray(scip, &capacities, nmachines) );
1198 SCIP_CALL( SCIPallocBufferArray(scip, &releasedates, njobs) );
1199 SCIP_CALL( SCIPallocBufferArray(scip, &deadlinedates, njobs) );
1200
1201 for( i = 0; i < nmachines && !cmininput->haserror; ++i )
1202 {
1203 for( j = 0; j < njobs; ++j )
1204 {
1205 /* get job duration */
1206 if( !getNextToken(cmininput) )
1207 {
1208 syntaxError(scip, cmininput, "missing job duration");
1209 break;
1210 }
1211 assert(cmininput->haserror == FALSE);
1212
1213 durations[i][j] = atoi(cmininput->token);
1214
1215 /* get demand */
1216 if( !getNextToken(cmininput) )
1217 {
1218 syntaxError(scip, cmininput, "missing job demand\n");
1219 break;
1220 }
1221 assert(cmininput->haserror == FALSE);
1222
1223 demands[i][j] = atoi(cmininput->token);
1224
1225 /* get job cost */
1226 if( !getNextToken(cmininput) )
1227 {
1228 syntaxError(scip, cmininput, "missing job cost\n");
1229 break;
1230 }
1231 assert(cmininput->haserror == FALSE);
1232
1233 costs[i][j] = atoi(cmininput->token);
1234
1235 SCIPdebugMessage("job %2d: duration %d, demand %d, cost %d\n", j, durations[i][j], demands[i][j], costs[i][j]);
1236 }
1237 }
1238
1239 /* parse the machine capacities */
1240 for( i = 0; i < nmachines && !cmininput->haserror; ++i)
1241 {
1242 /* get capacity */
1243 if( !getNextToken(cmininput) )
1244 {
1245 syntaxError(scip, cmininput, "missing machine capacity\n");
1246 break;
1247 }
1248
1249 capacities[i] = atoi(cmininput->token);
1250
1251 SCIPdebugMessage("capaciy of machine %d is %d\n", i, capacities[i]);
1252 }
1253
1254 /* get release and deadline dates */
1255 for( j = 0; j < njobs && !cmininput->haserror; ++j )
1256 {
1257
1258 /* get release date */
1259 if( !getNextToken(cmininput) )
1260 {
1261 syntaxError(scip, cmininput, "missing release date\n");
1262 break;
1263 }
1264
1265 releasedates[j] = atoi(cmininput->token);
1266
1267 /* get deadline data */
1268 if( !getNextToken(cmininput) )
1269 {
1270 syntaxError(scip, cmininput, "missing deadline date\n");
1271 break;
1272 }
1273 deadlinedates[j] = atoi(cmininput->token);
1274
1275 SCIPdebugMessage("job %2d: [%d,%d]\n", j, releasedates[j], deadlinedates[j]);
1276 }
1277
1278 if( !cmininput->haserror )
1279 {
1280 SCIP_Bool mip;
1281 SCIP_Bool cip;
1282 char* probname;
1283 char* str;
1284
1285 SCIPdebug( displayInputData(scip, durations, demands, costs, capacities, releasedates, deadlinedates, njobs, nmachines) );
1286
1287 SCIP_CALL( SCIPgetBoolParam(scip, "reading/"READER_NAME"/mip", &mip) );
1288 SCIP_CALL( SCIPgetBoolParam(scip, "reading/"READER_NAME"/cip", &cip) );
1289
1290 /* construct problem name */
1291 SCIP_CALL( SCIPduplicateBufferArray(scip, &str, filename, strlen(filename)+1) );
1292
1293 SCIPsplitFilename(str, NULL, &probname, NULL, NULL);
1294
1295 /* initialize problem data */
1296 SCIP_CALL( SCIPcreateProbBasic(scip, probname) );
1297
1299
1300 if( mip && cip )
1301 {
1302 SCIP_CALL( createMipCpFormulation(scip, durations, demands, costs, capacities, releasedates, deadlinedates, njobs, nmachines) );
1303 }
1304 else if( mip )
1305 {
1306 SCIP_CALL( createMipFormulation(scip, durations, demands, costs, capacities, releasedates, deadlinedates, njobs, nmachines) );
1307 }
1308 else if( cip )
1309 {
1310 SCIP_CALL( createCipFormulation(scip, durations, demands, costs, capacities, releasedates, deadlinedates, njobs, nmachines) );
1311 }
1312 }
1313
1314 /* free all buffers in the reverse order since the buffers are handled by a stack */
1315 SCIPfreeBufferArray(scip, &deadlinedates);
1316 SCIPfreeBufferArray(scip, &releasedates);
1317 SCIPfreeBufferArray(scip, &capacities);
1318 for( i = nmachines - 1; i >= 0; --i )
1319 {
1320 SCIPfreeBufferArray(scip, &costs[i]);
1321 SCIPfreeBufferArray(scip, &demands[i]);
1322 SCIPfreeBufferArray(scip, &durations[i]);
1323 }
1324 SCIPfreeBufferArray(scip, &costs);
1325 SCIPfreeBufferArray(scip, &demands);
1326 SCIPfreeBufferArray(scip, &durations);
1327
1328 return SCIP_OKAY;
1329}
1330
1331
1332/*
1333 * Callback methods of reader
1334 */
1335
1336
1337/** problem reading method of reader */
1338static
1340{ /*lint --e{715}*/
1341
1342 CMININPUT cmininput;
1343 SCIP_FILE* file;
1344
1345 /* try to open the file */
1346 if( NULL == (file = SCIPfopen(filename, "r")) )
1347 {
1348 perror(filename);
1349 return SCIP_NOFILE;
1350 }
1351
1352 cmininput.linebuf[0] = '\0';
1353 cmininput.linenumber = 0;
1354 cmininput.linepos = 0;
1355 cmininput.haserror = FALSE;
1356 cmininput.file = file;
1357
1359 cmininput.token[0] = '\0';
1360
1361 SCIP_CALL( readFile(scip, &cmininput, filename) );
1362
1363 SCIPfreeBufferArray(scip, &cmininput.token);
1364
1365 /* close file */
1366 (void) SCIPfclose(file);
1367
1368 if( cmininput.haserror )
1369 return SCIP_READERROR;
1370
1371 *result = SCIP_SUCCESS;
1372
1373 return SCIP_OKAY;
1374}
1375
1376/*
1377 * reader specific interface methods
1378 */
1379
1380/** includes the cp file reader in SCIP */
1382 SCIP* scip /**< SCIP data structure */
1383 )
1384{
1385 SCIP_READER* reader;
1386
1387 /* include cp reader */
1389 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadCmin) );
1390
1392 "reading/"READER_NAME"/filename", "name of the file including best known solutions",
1394
1396 "reading/"READER_NAME"/dualreduction", "add locks to avoid dual reductions?",
1398
1400 "reading/"READER_NAME"/mip", "create a MIP formulation?",
1402
1404 "reading/"READER_NAME"/initial", "should model constraints be in initial LP?",
1406
1408 "reading/"READER_NAME"/cip", "create a CIP formulation?",
1410
1412 "reading/"READER_NAME"/relaxation", "which relaxation should be added to the maseter (0: none; 1: single; 2: edge-finding; 3: energetic-reasoning",
1413 NULL, FALSE, DEFAULT_RELAXATION, 0, 3, NULL, NULL) );
1414
1415 return SCIP_OKAY;
1416}
SCIP_VAR * h
Definition: circlepacking.c:68
Constraint handler for knapsack constraints of the form , x binary and .
Constraint handler for linear constraints in their most general form, .
SCIP_RETCODE SCIPcreateConsOptcumulative(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_VAR **binvars, int *durations, int *demands, int capacity, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
constraint handler for cumulative constraints with optional activities
Constraint handler for the set partitioning / packing / covering constraints .
#define NULL
Definition: def.h:267
#define SCIP_MAXSTRLEN
Definition: def.h:288
#define SCIP_Longint
Definition: def.h:158
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:243
#define SCIP_Real
Definition: def.h:173
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:239
#define SCIP_LONGINT_FORMAT
Definition: def.h:165
#define MIN3(x, y, z)
Definition: def.h:251
#define SCIP_CALL(x)
Definition: def.h:374
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:153
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:232
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:200
SCIP_RETCODE SCIPcreateConsBasicSetpart(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars)
Definition: cons_setppc.c:9391
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPaddCoefKnapsack(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Longint weight)
SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
SCIP_RETCODE SCIPcreateConsBasicKnapsack(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Longint *weights, SCIP_Longint capacity)
SCIP_RETCODE SCIPaddCoefSetppc(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
Definition: cons_setppc.c:9522
SCIP_RETCODE SCIPcreateConsKnapsack(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Longint *weights, SCIP_Longint capacity, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPcreateConsSetpart(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_setppc.c:9351
void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
Definition: misc.c:11095
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
const char * SCIPgetProbName(SCIP *scip)
Definition: scip_prob.c:1067
SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
Definition: scip_prob.c:1422
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
SCIP_RETCODE SCIPcreateProbBasic(SCIP *scip, const char *name)
Definition: scip_prob.c:180
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:83
SCIP_RETCODE SCIPaddStringParam(SCIP *scip, const char *name, const char *desc, char **valueptr, SCIP_Bool isadvanced, const char *defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:194
SCIP_RETCODE SCIPgetStringParam(SCIP *scip, const char *name, char **value)
Definition: scip_param.c:345
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:57
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip_param.c:269
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1174
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip_reader.c:109
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4259
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1527
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:114
SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
Definition: scip_var.c:194
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:10818
SCIP_RETCODE SCIPinitHeurOptcumulative(SCIP *scip, int nmachines, int njobs, int *machines, SCIP_VAR ***binvars, SCIP_VAR ***vars, int **durations, int **demands, int *capacities)
heuristic for cumulative scheduling with optional activities
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:43
#define SCIPdebug(x)
Definition: pub_message.h:93
#define SCIPdebugMessage
Definition: pub_message.h:96
static int removeRedundantRows(SCIP_Longint *rowtightness, int *startidxs, int nrows, SCIP_Longint tightness)
Definition: reader_cmin.c:367
#define DEFAULT_MIP
Definition: reader_cmin.c:55
#define DEFAULT_FILENAME
Definition: reader_cmin.c:53
SCIP_RETCODE SCIPincludeReaderCmin(SCIP *scip)
Definition: reader_cmin.c:1381
#define DEFAULT_INITIAL
Definition: reader_cmin.c:56
static SCIP_RETCODE createIntervalRelaxation(SCIP *scip, int relaxation, int resource, SCIP_VAR **vars, int *durations, int *demands, int capacity, int *releasedates, int *deadlinedates, int njobs)
Definition: reader_cmin.c:394
static SCIP_Longint computeMaxEnergy(int njobs, int *durations, int *demands, int *releasedates, int *deadlinedates, int starttime, int endtime)
Definition: reader_cmin.c:336
static SCIP_RETCODE readFile(SCIP *scip, CMININPUT *cmininput, const char *filename)
Definition: reader_cmin.c:1148
#define DEFAULT_RELAXATION
Definition: reader_cmin.c:58
#define READER_DESC
Definition: reader_cmin.c:50
static SCIP_DECL_READERREAD(readerReadCmin)
Definition: reader_cmin.c:1339
static SCIP_Bool getNextLine(CMININPUT *cmininput)
Definition: reader_cmin.c:99
#define READER_EXTENSION
Definition: reader_cmin.c:51
static SCIP_Bool getNextToken(CMININPUT *cmininput)
Definition: reader_cmin.c:141
#define DEFAULT_DUALREDUCTION
Definition: reader_cmin.c:54
static SCIP_RETCODE createMipCpFormulation(SCIP *scip, int **durations, int **demands, int **costs, int *capacities, int *releasedates, int *deadlinedates, int njobs, int nmachines)
Definition: reader_cmin.c:784
static void createSortedEventpoints(SCIP *scip, int *releasedates, int *deadlinedates, int *starttimes, int *endtimes, int *startindices, int *endindices, int njobs)
Definition: reader_cmin.c:302
#define READER_NAME
Definition: reader_cmin.c:49
#define DEFAULT_CIP
Definition: reader_cmin.c:57
static SCIP_Bool isDelimChar(char c)
Definition: reader_cmin.c:132
static const char delimchars[]
Definition: reader_cmin.c:60
static void syntaxError(SCIP *scip, CMININPUT *cmininput, const char *msg)
Definition: reader_cmin.c:81
static SCIP_RETCODE findBestObjectiveValue(SCIP *scip, SCIP_Real *objval)
Definition: reader_cmin.c:192
static SCIP_RETCODE createMipFormulation(SCIP *scip, int **durations, int **demands, int **costs, int *capacities, int *releasedates, int *deadlinedates, int njobs, int nmachines)
Definition: reader_cmin.c:566
static SCIP_RETCODE createCipFormulation(SCIP *scip, int **durations, int **demands, int **costs, int *capacities, int *releasedates, int *deadlinedates, int njobs, int nmachines)
Definition: reader_cmin.c:998
cmin file reader
SCIP_Bool haserror
Definition: reader_cmin.c:75
char linebuf[SCIP_MAXSTRLEN]
Definition: reader_cmin.c:71
SCIP_FILE * file
Definition: reader_cmin.c:70
int linenumber
Definition: reader_cmin.c:73
int linepos
Definition: reader_cmin.c:74
char * token
Definition: reader_cmin.c:72
@ SCIP_VERBLEVEL_MINIMAL
Definition: type_message.h:54
@ SCIP_VERBLEVEL_HIGH
Definition: type_message.h:56
@ SCIP_SUCCESS
Definition: type_result.h:58
@ SCIP_NOFILE
Definition: type_retcode.h:47
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_INVALIDCALL
Definition: type_retcode.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_VARTYPE_INTEGER
Definition: type_var.h:63
@ SCIP_VARTYPE_IMPLINT
Definition: type_var.h:64
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:62
@ SCIP_LOCKTYPE_MODEL
Definition: type_var.h:97