Scippy

SCIP

Solving Constraint Integer Programs

reader_sm.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_sm.c
26 * @brief scheduling problem file reader for RCPSP format
27 * @author Michael Bastubbe
28 * @author Stefan Heinz
29 *
30 * This reader is capabale of parsing resource-constrained project scheduling problem (RCPSP) instances. The <a
31 * href="http://129.187.106.231/psplib/datasm.html">PSPlib</a> provides several instances set.
32 *
33 */
34
35/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
36
37#include <assert.h>
38#include <string.h>
39#include <ctype.h>
40
41
42#include "heur_listscheduling.h"
43#include "reader_sm.h"
44
46#include "scip/cons_linear.h"
47#include "scip/cons_varbound.h"
48
49#define READER_NAME "smreader"
50#define READER_DESC "scheduling file reader for sm files (RCPSP format)"
51#define READER_EXTENSION "sm"
52
53
54/**@name Default parameter values
55 *
56 * @{
57 */
58
59#define DEFAULT_FILENAME "-" /**< file name of precedence graph output file (in GML format), or - if no output should be created */
60
61/**@} */
62
63
64
65#define SM_MAX_LINELEN 65536 /**< size of the line buffer for reading or writing */
66
68 ERROR = 0,
76 END
77};
78typedef enum reading_states STATE;
79
80
81/** data structure for resources constrained project scheduling problems */
82struct SCIP_RcpspData
83{
84 SCIP_DIGRAPH* precedencegraph; /**< precedence graph of the jobs */
85 const char** jobnames; /**< array of job names */
86 const char** resourcenames; /**< array of resource names */
87 int** demands; /**< resource demands matrix (job i needs demands[i][j] units of resource j) */
88 int* durations; /**< array of job durations */
89 int* capacities; /**< array of resource capacities */
90 int njobs; /**< number of jobs */
91 int nresources; /**< number of resources */
92};
93typedef struct SCIP_RcpspData SCIP_RCPSPDATA;
94
95
96/*
97 * Local methods
98 */
99
100#ifdef SCIP_DEBUG
101/* print the resource constrained project scheduling data */
102static
103void outputRcpspData(
104 SCIP* scip, /**< SCIP data structure */
105 SCIP_RCPSPDATA* rcpspdata /**< pointer to resources constrained project scheduling data */
106 )
107{
108 int i;
109 int r;
110
111 /* output jobs */
112 SCIPinfoMessage(scip, NULL, "Number of jobs: %d\n", rcpspdata->njobs);
113 for(i = 0; i < rcpspdata->njobs ; ++i )
114 {
115 SCIPinfoMessage(scip, NULL, "job: %-10s \n", rcpspdata->jobnames[i]);
116 SCIPinfoMessage(scip, NULL, " duration: %3d \n", rcpspdata->durations[i] );
117 SCIPinfoMessage(scip, NULL, " resource profile: ");
118
119 for( r = 0; r < rcpspdata->nresources; ++r )
120 {
121 SCIPinfoMessage(scip, NULL, " %3d" , rcpspdata->demands[i][r] );
122 }
123
124 SCIPinfoMessage(scip, NULL, "\n");
125 }
126 SCIPinfoMessage(scip, NULL, "\n");
127
128 /* output resource capacities */
129 SCIPinfoMessage(scip, NULL, "Resource capacities: ");
130 for( r = 0; r < rcpspdata->nresources; ++r )
131 {
132 if( r == 0 )
133 {
134 SCIPinfoMessage(scip, NULL, " %d " , rcpspdata->capacities[r] );
135 }
136 else
137 {
138 SCIPinfoMessage(scip, NULL, ", %d " , rcpspdata->capacities[r] );
139 }
140 }
141 SCIPinfoMessage(scip, NULL, "\n");
142
143 /* print precedence graph */
144 SCIPinfoMessage(scip, NULL, "Precedences:\n");
145 SCIPdigraphPrint(rcpspdata->precedencegraph, SCIPgetMessagehdlr(scip), NULL);
146}
147#endif
148
149/** print error message */
150static
152 SCIP* scip, /**< SCIP data structure */
153 int lineno, /**< current line number of input file */
154 const char* msg, /**< error message to display */
155 const char* erritem, /**< token where the error occured, or NULL */
156 STATE* state /**< pointer to current reading state */
157 )
158{
159 assert(msg != NULL);
160 assert(state != NULL);
161
162 if( erritem != NULL )
163 {
164 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Line %d: %s <%s>\n", lineno, msg, erritem);
165 }
166 else
167 {
168 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Line %d: %s\n", lineno, msg);
169 }
170
171 *state = ERROR;
172}
173
174/** check if we reached a section */
175static
177 char* linestr, /**< current line */
178 STATE* state /**< pointer to current reading state */
179 )
180{
181 assert(linestr != NULL);
182 assert(state != NULL);
183
184 if( strncmp(linestr, "jobs", 4) == 0 )
185 *state = NJOBS;
186 else if( strncmp(linestr, "RESOURCES", 9) == 0 )
187 *state = NRESOURCES;
188 else if( strncmp(linestr, "PRECEDENCE", 4) == 0 )
189 *state = PRECEDENCES;
190 else if( strncmp(linestr, "REQUESTS", 4) == 0 )
191 *state = JOBS;
192 else if( strncmp(linestr, "RESOURCEAVAILABILITIES", 10) == 0 )
193 *state = RESOURCENAMES;
194}
195
196/** parese number of resources */
197static
199 SCIP* scip, /**< SCIP data structure */
200 int lineno, /**< current line number of input file */
201 char* linestr, /**< current line */
202 STATE* state, /**< pointer to current reading state */
203 SCIP_RCPSPDATA* rcpspdata /**< pointer to resources constrained project scheduling data */
204 )
205{
206 SCIP_Real nresources;
207 char* endptr;
208 char* number;
209
210 assert(linestr != NULL);
211 assert(state != NULL);
212
213 if( strncmp(linestr, "RESOURCES", 4) == 0 )
214 return SCIP_OKAY;
215
216 /* truncate the line via ':' and ignore the first part */
217 (void)SCIPstrtok(linestr, ":", &endptr);
218 number = SCIPstrtok(NULL, ":", &endptr);
219
220 if( !SCIPstrToRealValue(number, &nresources, &endptr) )
221 {
222 parseError(scip, lineno, "expexted number of resources", linestr, state);
223 return SCIP_OKAY;
224 }
225
226 rcpspdata->nresources = (int)(nresources + 0.5);
227
228 SCIP_CALL( SCIPallocBufferArray(scip, &rcpspdata->capacities, nresources) );
229 SCIP_CALL( SCIPallocBufferArray(scip, &rcpspdata->resourcenames, nresources) );
230
231 *state = NEXT;
232
233 return SCIP_OKAY;
234}
235
236/** parse number of jobs */
237static
239 SCIP* scip, /**< SCIP data structure */
240 int lineno, /**< current line number of input file */
241 char* linestr, /**< current line */
242 STATE* state, /**< pointer to current reading state */
243 SCIP_RCPSPDATA* rcpspdata /**< pointer to resources constrained project scheduling data */
244 )
245{
246 SCIP_Real njobs;
247 char* endptr;
248 char* number;
249
250 assert(linestr != NULL);
251 assert(state != NULL);
252
253 /* truncate the line via ':' and ignore the first part */
254 (void)SCIPstrtok(linestr, ":", &endptr);
255 number = SCIPstrtok(NULL, ":", &endptr);
256
257 if( !SCIPstrToRealValue(number, &njobs, &endptr) )
258 {
259 parseError(scip, lineno, "expexted number of jobs", linestr, state);
260 return SCIP_OKAY;
261 }
262
263 rcpspdata->njobs = (int)(njobs + 0.5);
264
265 SCIP_CALL( SCIPallocBufferArray(scip, &rcpspdata->jobnames, njobs) );
266 SCIP_CALL( SCIPallocBufferArray(scip, &rcpspdata->durations, njobs) );
267 SCIP_CALL( SCIPallocBufferArray(scip, &rcpspdata->demands, njobs) );
268
269 *state = NEXT;
270
271 return SCIP_OKAY;
272}
273
274/** pares resource capacities */
275static
277 SCIP* scip, /**< SCIP data structure */
278 char* linestr, /**< current line */
279 STATE* state, /**< pointer to current reading state */
280 SCIP_RCPSPDATA* rcpspdata /**< pointer to resources constrained project scheduling data */
281 )
282{
283 char* name;
284 char* endptr;
285 int r;
286
287 assert(linestr != NULL);
288 assert(state != NULL);
289
290 if( strncmp(linestr, "RESOURCEAVAILABILITIES", 10) == 0 )
291 return SCIP_OKAY;
292
293 /* pares resource names */
294 name = SCIPstrtok(linestr, "R", &endptr);
295 r = 0;
296
297 do
298 {
299 while(isspace(*name))
300 name++;
301
302 SCIP_CALL( SCIPduplicateBufferArray(scip, &rcpspdata->resourcenames[r], name, strlen(name) + 1) ); /*lint !e866*/
303 r++;
304 }
305 while( (name = SCIPstrtok(NULL, "R", &endptr)) != NULL );
306
307 *state = RESOURCECAPACITIES;
308
309 return SCIP_OKAY;
310}
311
312/** parse resource capacities */
313static
315 SCIP* scip, /**< SCIP data structure */
316 char* linestr, /**< current line */
317 STATE* state, /**< pointer to current reading state */
318 SCIP_RCPSPDATA* rcpspdata /**< pointer to resources constrained project scheduling data */
319 )
320{
321 SCIP_Real value;
322 int r;
323
324 assert(linestr != NULL);
325 assert(state != NULL);
326
327 /* parse resources capacities */
328 for( r = 0; r < rcpspdata->nresources; ++r )
329 {
330 if( SCIPstrToRealValue(linestr, &value, &linestr) )
331 rcpspdata->capacities[r] = (int)(value + 0.5);
332 }
333
334 *state = END;
335
336 return SCIP_OKAY;
337}
338
339/** parese job informations */
340static
342 SCIP* scip, /**< SCIP data structure */
343 char* linestr, /**< current line */
344 STATE* state, /**< pointer to current reading state */
345 SCIP_RCPSPDATA* rcpspdata /**< pointer to resources constrained project scheduling data */
346 )
347{
348 char jobname[SCIP_MAXSTRLEN];
349 int value;
350 int jobid;
351 int r;
352
353 assert(linestr != NULL);
354 assert(state != NULL);
355
356 /* skip lines which are not of interest */
357 if ( (!strncmp(linestr, "REQUESTS", 4) ) || ( !strncmp(linestr, "jobnr", 3) ) || ( !strncmp(linestr, "-", 1) ) )
358 {
359 *state = JOBS;
360 return SCIP_OKAY;
361 }
362
363 /* parse job id */
364 if( !SCIPstrToIntValue(linestr, &value, &linestr) )
365 return SCIP_READERROR;
366
367 jobid = value - 1;
368
369 /* construct job name */
370 (void)SCIPsnprintf(jobname, SCIP_MAXSTRLEN, "%d" , jobid) ;
371
372 /* copy job name */
373 SCIP_CALL( SCIPduplicateBufferArray(scip, &rcpspdata->jobnames[jobid], jobname, strlen(jobname) + 1) ); /*lint !e866*/
374
375 /* skip next value */
376 if( !SCIPstrToIntValue(linestr, &value, &linestr) )
377 return SCIP_READERROR;
378
379 /* parse duration */
380 if( !SCIPstrToIntValue(linestr, &value, &linestr) )
381 return SCIP_READERROR;
382
383 rcpspdata->durations[jobid] = value;
384
385 SCIP_CALL( SCIPallocBufferArray(scip, &rcpspdata->demands[jobid], rcpspdata->nresources) ); /*lint !e866*/
386
387 /* parse demands */
388 for( r = 0; r < rcpspdata->nresources; ++r )
389 {
390 if( !SCIPstrToIntValue(linestr, &value, &linestr) )
391 return SCIP_READERROR;
392
393 rcpspdata->demands[jobid][r] = value;
394 }
395
396 /* check if we paresed the last job */
397 if( jobid == rcpspdata->njobs - 1 )
398 *state = NEXT;
399
400 return SCIP_OKAY;
401}
402
403/** get precedence relationship */
404static
406 SCIP* scip, /**< SCIP data structure */
407 char* s, /**< current line */
408 STATE* state, /**< pointer to current reading state */
409 SCIP_RCPSPDATA* rcpspdata /**< pointer to resources constrained project scheduling data */
410 )
411{
412 int nsuccessors;
413 int value;
414 int pred;
415 int p;
416
417 assert(s != NULL);
418 assert(state != NULL);
419
420 if( ( !strncmp(s, "PRECEDENCES", 3) ) || ( !strncmp(s, "jobnr", 4) ) )
421 {
422 *state = PRECEDENCES;
423 return SCIP_OKAY;
424 }
425
426 /* create precedence graph if does not exist yet */
427 if( rcpspdata->precedencegraph == NULL )
428 {
429 SCIP_CALL( SCIPcreateDigraph(scip, &rcpspdata->precedencegraph, rcpspdata->njobs) );
430 }
431
432 /* parse predecessor */
433 if( !SCIPstrToIntValue(s, &value, &s) )
434 return SCIP_READERROR;
435
436 pred = value - 1;
437
438 /* skip integer value */
439 if( !SCIPstrToIntValue(s, &value, &s) )
440 return SCIP_READERROR;
441
442 /* parse number of successors */
443 if( !SCIPstrToIntValue(s, &nsuccessors, &s) )
444 return SCIP_READERROR;
445
446 /* parse successors */
447 for( p = 0; p < nsuccessors; ++p )
448 {
449 int succ;
450
451 if( !SCIPstrToIntValue(s, &value, &s) )
452 return SCIP_READERROR;
453
454 succ = value - 1;
455
456 /* add precedence to digraph */
457 SCIP_CALL( SCIPdigraphAddArc(rcpspdata->precedencegraph, pred, succ, (void*)(size_t)INT_MAX) );
458 }
459
460 if(pred == rcpspdata->njobs-1)
461 *state = NEXT;
462
463 return SCIP_OKAY;
464}
465
466/** compute trivial upper bound for makespan */
467static
469 int* durations, /**< array of durations */
470 int njobs, /**< number og jobs */
471 SCIP_DIGRAPH* precedencegraph /**< direct graph to store the precedence conditions */
472 )
473{
474 int ub;
475 int j;
476
477 ub = 0;
478
479 for( j = 0; j < njobs; ++j )
480 {
481 void** distances;
482 int nsuccessors;
483 int duration;
484 int i;
485
486 nsuccessors = SCIPdigraphGetNSuccessors(precedencegraph, j);
487 distances = SCIPdigraphGetSuccessorsData(precedencegraph, j);
488
489 duration = durations[j];
490
491 for( i = 0; i < nsuccessors; ++i )
492 {
493 int distance;
494
495 distance = (int)(size_t)distances[i];
496
497 if( distance != INT_MAX )
498 duration = MAX(duration, distance);
499 }
500
501 ub += duration;
502 }
503
504 return ub;
505}
506
507/** read file */
508static
510 SCIP* scip, /**< SCIP data structure */
511 const char* filename, /**< name of input file */
512 SCIP_RCPSPDATA* rcpspdata /**< pointer to resources constrained project scheduling data */
513 )
514{
515 SCIP_FILE* fp;
516 char buf[SM_MAX_LINELEN];
517 int lineno = 0;
518 char* s;
519 STATE state = NEXT;
520
521 assert(filename != NULL);
522
523 if( NULL == (fp = SCIPfopen(filename, "r")) )
524 {
525 perror(filename);
526 return SCIP_READERROR;
527 }
528
529 /* parse file line by line */
530 while( state != END && state != ERROR && (NULL != SCIPfgets(buf, (int) sizeof(buf), fp)) )
531 {
532 /* count line number */
533 lineno++;
534
535 if( NULL != (s = strpbrk(buf, "*\r\n")) )
536 *s = '\0';
537 else
538 {
539 parseError(scip, lineno, "line truncated", NULL, &state);
540 break;
541 }
542 s = buf;
543
544 /* remove white space */
545 while(isspace(*s))
546 s++;
547
548 /* skip empty lines */
549 if (*s == '\0')
550 continue;
551
552 if( state == NEXT )
553 {
554 checkForNewSection(s, &state);
555 }
556
557 SCIPdebugMessage("input line: <%s>\n", s);
558 switch( state )
559 {
560 case ERROR:
561 break;
562
563 case NEXT:
564 break;
565
566 case NJOBS:
567 SCIP_CALL( getNJobs(scip, lineno, s, &state, rcpspdata) );
568 break;
569
570 case JOBS:
571 SCIP_CALL( getJobs(scip, s, &state, rcpspdata) );
572 break;
573
574
575 case NRESOURCES:
576 SCIP_CALL( getNResources(scip, lineno, s, &state, rcpspdata) );
577 break;
578
579 case RESOURCENAMES:
580 SCIP_CALL( getResourcesNames(scip, s, &state, rcpspdata) );
581 break;
582
584 SCIP_CALL( getResourcesCapacities(scip, s, &state, rcpspdata) );
585 break;
586
587 case PRECEDENCES:
588 SCIP_CALL( getPrecedence(scip, s, &state, rcpspdata) );
589 break;
590
591 case END:
592 parseError(scip, lineno, "additional characters after END", NULL, &state);
593 break;
594
595 default:
596 SCIPerrorMessage("invalid reading state\n");
597 SCIPABORT();
598 }
599 }
600 SCIPfclose(fp);
601
602 if( state != END && state != ERROR )
603 parseError(scip, lineno, "unexpected EOF", NULL, &state);
604
605 if( state == ERROR )
606 return SCIP_READERROR;
607 else
608 return SCIP_OKAY;
609}
610
611/*
612 * Callback methods of reader
613 */
614
615/** copy method for reader plugins (called when SCIP copies plugins) */
616static
618{ /*lint --e{715}*/
619 assert(scip != NULL);
620 assert(reader != NULL);
621 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
622
623 /* call inclusion method of reader handler */
625
626 return SCIP_OKAY;
627}
628
629/** problem reading method of reader */
630static
632{ /*lint --e{715}*/
633 SCIP_RCPSPDATA rcpspdata;
634 char* predfilename;
635 int j;
636
637 /* initialize resources constrained project scheduling data */
638 rcpspdata.precedencegraph = NULL;
639 rcpspdata.jobnames = NULL;
640 rcpspdata.durations = NULL;
641 rcpspdata.demands = NULL;
642 rcpspdata.capacities = NULL;
643 rcpspdata.njobs = 0;
644 rcpspdata.nresources = 0;
645
646 /* read file */
647 SCIP_CALL( readFile(scip, filename, &rcpspdata) );
648
649 /* output rcpspdata to check it */
650 SCIPdebug( outputRcpspData(scip, &rcpspdata) );
651
652 SCIP_CALL( SCIPgetStringParam(scip, "reading/"READER_NAME"/filename", &predfilename) );
653
654 if( strncmp(predfilename, "-", 1) != 0 )
655 {
656 FILE* file;
657
658 file = fopen(predfilename, "w");
659
660 if( file == NULL )
661 {
662 SCIPerrorMessage("cannot create file <%s> for writing\n", predfilename);
663 SCIPprintSysError(predfilename);
665 }
666
667 SCIPdigraphPrintGml(rcpspdata.precedencegraph, file);
668
669 fclose(file);
670 }
671
672 /* create problem */
673 SCIP_CALL( SCIPcreateSchedulingProblem(scip, filename, rcpspdata.jobnames, rcpspdata.resourcenames, rcpspdata.demands,
674 rcpspdata.precedencegraph, rcpspdata.durations, rcpspdata.capacities, rcpspdata.njobs, rcpspdata.nresources, TRUE) );
675
676 (*result) = SCIP_SUCCESS;
677
678 /* free buffer arrays */
679 if( rcpspdata.njobs > 0 )
680 {
681 for( j = 0; j < rcpspdata.njobs; ++j )
682 {
683 SCIPfreeBufferArray(scip, &(rcpspdata.jobnames[j]));
684 SCIPfreeBufferArray(scip, &(rcpspdata.demands[j]));
685 }
686
687 SCIPfreeBufferArray(scip, &rcpspdata.jobnames);
688 SCIPfreeBufferArray(scip, &rcpspdata.durations);
689 SCIPfreeBufferArray(scip, &rcpspdata.demands);
690 }
691
692 if( rcpspdata.nresources > 0 )
693 {
694 int r;
695
696 for( r = 0; r < rcpspdata.nresources; ++r )
697 SCIPfreeBufferArray(scip, &rcpspdata.resourcenames[r]);
698
699 SCIPfreeBufferArray(scip, &rcpspdata.resourcenames);
700 SCIPfreeBufferArray(scip, &rcpspdata.capacities);
701 }
702
703 if( rcpspdata.precedencegraph != NULL )
704 {
705 SCIPdigraphFree(&rcpspdata.precedencegraph);
706 }
707
708 return SCIP_OKAY;
709}
710
711/*
712 * reader specific interface methods
713 */
714
715/** includes the sch file reader in SCIP */
717 SCIP* scip /**< SCIP data structure */
718 )
719{
720 SCIP_READERDATA* readerdata;
721 SCIP_READER* reader;
722
723 /* create sch reader data */
724 readerdata = NULL;
725
726 /* include sch reader */
728 assert(reader != NULL);
729
730 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopySm) );
731 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadSm) );
732
733 /* add reader parameters */
735 "reading/"READER_NAME"/mipmodel", "create MIP model?",
736 NULL, FALSE, FALSE, NULL, NULL) );
737
739 "reading/"READER_NAME"/filename",
740 "file name of precedence graph output file (in GML format), or - if no output should be created",
742
743 return SCIP_OKAY;
744}
745
746/** creates a cumulative scheduling problem */
748 SCIP* scip, /**< SCIP data structure */
749 const char* problemname, /**< problem name */
750 const char** jobnames, /**< job names, or NULL */
751 const char** resourcenames, /**< resource names, or NULL */
752 int** demands, /**< demand matrix resource job demand */
753 SCIP_DIGRAPH* precedencegraph, /**< direct graph to store the precedence conditions */
754 int* durations, /**< array to store the processing for each job */
755 int* capacities, /**< array to store the different capacities */
756 int njobs, /**< number of jobs to be parsed */
757 int nresources, /**< number of capacities to be parsed */
758 SCIP_Bool initialize /**< initialize list scheduling heuristic */
759 )
760{
761 SCIP_VAR** jobs;
762 SCIP_VAR** vars;
763 SCIP_VAR* var;
764
765 SCIP_CONS* cons;
766
767 char name[SCIP_MAXSTRLEN];
768
769 int* consdurations;
770 int* consdemands;
771
772 int nvars;
773 int ubmakespan;
774 int i;
775 int j;
776 int r;
777
778 assert( scip != NULL );
779 assert( njobs >= 0 );
780
781 SCIPdebugMessage( "start method SCIPcreateSchedulingSMProblem\n");
782
783 /* create SCIP data structure */
784 SCIP_CALL( SCIPcreateProb(scip, problemname, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
785
786 /* compute a feasible upper bound on the makespan */
787 ubmakespan = computeUbmakespan(durations, njobs, precedencegraph);
788
789 /* allocate buffer for jobs and precedence constraints */
790 SCIP_CALL( SCIPallocBufferArray(scip, &jobs, njobs) );
791
792 /* create an activity constraint for each activity */
793 for( j = 0; j < njobs - 1; ++j ) /* but not for last job which is the makespan (-1) */
794 {
795 /* construct variable name */
796 if( jobnames != NULL )
797 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "start_%s", jobnames[j]);
798 else
799 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "start_%d", j);
800
801 /* create integer starting variable */
802 SCIP_CALL( SCIPcreateVar(scip, &var, name, 0.0, (SCIP_Real)ubmakespan, 0.0, SCIP_VARTYPE_INTEGER,
803 TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
804
805 SCIP_CALL( SCIPaddVar(scip, var) );
807 jobs[j] = var;
808 SCIP_CALL( SCIPreleaseVar(scip, &var) );
809 }
810
811 /* create makespan variable */
812 SCIP_CALL( SCIPcreateVar(scip, &var, "makespan", 0.0, (SCIP_Real)ubmakespan, 1.0, SCIP_VARTYPE_INTEGER,
813 TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
814
815 SCIP_CALL( SCIPaddVar(scip, var) );
817
818 jobs[njobs-1] = var;
819 SCIP_CALL( SCIPreleaseVar(scip, &var) );
820
821 /* precedence constraints */
822 for( j = 0; j < njobs - 1; ++j )
823 {
824 SCIP_VAR* predvar;
825 int nsuccessors;
826
827 nsuccessors = SCIPdigraphGetNSuccessors(precedencegraph, j);
828
829 predvar = jobs[j];
830 assert(predvar != NULL);
831
832 if( nsuccessors > 0 )
833 {
834 int* successors;
835 void** distances;
836
837 successors = SCIPdigraphGetSuccessors(precedencegraph, j);
838 distances = SCIPdigraphGetSuccessorsData(precedencegraph, j);
839
840 for( i = 0; i < nsuccessors; ++i )
841 {
842 SCIP_VAR* succvar;
843 int distance;
844
845 succvar = jobs[successors[i]];
846 assert(succvar != NULL);
847
848 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "precedences_(%d,%d)", j, successors[i]);
849
850 distance = (int)(size_t)distances[i];
851
852 if( distance == INT_MAX )
853 distance = durations[j];
854
855 SCIP_CALL( SCIPcreateConsVarbound(scip, &cons, name, predvar, succvar, -1.0,
856 -SCIPinfinity(scip), (SCIP_Real) -distance,
858 SCIP_CALL( SCIPaddCons(scip, cons) );
859 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
860 }
861 }
862 else
863 {
864 /* add precedence constraints for those jobs without successor */
865 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "precedences_(%d,%d)", j, njobs);
866
867 SCIP_CALL( SCIPcreateConsVarbound(scip, &cons, name, predvar, jobs[njobs-1], -1.0,
868 -SCIPinfinity(scip), (SCIP_Real) -durations[j],
870 SCIP_CALL( SCIPaddCons(scip, cons) );
871 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
872 }
873 }
874
875 SCIP_CALL( SCIPallocBufferArray(scip, &vars, njobs) );
876 SCIP_CALL( SCIPallocBufferArray(scip, &consdemands, njobs) );
877 SCIP_CALL( SCIPallocBufferArray(scip, &consdurations, njobs) );
878
879 /* create resource constraints */
880 for( r = 0; r < nresources; ++r )
881 {
882 nvars = 0;
883 for( j = 0; j < njobs; ++j ) /* also makespan constraint! */
884 {
885 if( demands[j][r] > 0 )
886 {
887 vars[nvars] = jobs[j];
888 consdemands[nvars] = demands[j][r];
889 consdurations[nvars] = durations[j];
890 nvars++;
891 }
892 }
893
894 if( nvars > 0 )
895 {
896 /* construct constraint name */
897 if( resourcenames != NULL )
898 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "R%s", resourcenames[r]);
899 else
900 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "R%d", r);
901
903 nvars, vars, consdurations, consdemands, capacities[r],
905 SCIP_CALL( SCIPaddCons(scip, cons) );
906 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
907 }
908 }
909
910 /* initialize the problem specific heuristic */
911 if( initialize )
912 {
913 SCIP_CALL( SCIPinitializeHeurListScheduling(scip, precedencegraph, jobs,
914 durations, demands, capacities, njobs, nresources) );
915 }
916
917 /* free buffer array */
918 SCIPfreeBufferArray(scip, &consdurations);
919 SCIPfreeBufferArray(scip, &consdemands);
922
923 return SCIP_OKAY;
924}
static long * number
SCIP_Real * r
Definition: circlepacking.c:59
constraint handler for cumulative constraints
Constraint handler for linear constraints in their most general form, .
Constraint handler for variable bound constraints .
#define NULL
Definition: def.h:267
#define SCIP_MAXSTRLEN
Definition: def.h:288
#define SCIP_Bool
Definition: def.h:91
#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 SCIPABORT()
Definition: def.h:346
#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 SCIPcreateConsVarbound(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *var, SCIP_VAR *vbdvar, SCIP_Real vbdcoef, 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 SCIPcreateConsCumulative(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, 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)
void ** SCIPdigraphGetSuccessorsData(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:7837
int SCIPdigraphGetNSuccessors(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:7804
void SCIPdigraphPrintGml(SCIP_DIGRAPH *digraph, FILE *file)
Definition: misc.c:8585
SCIP_RETCODE SCIPdigraphAddArc(SCIP_DIGRAPH *digraph, int startnode, int endnode, void *data)
Definition: misc.c:7662
void SCIPdigraphFree(SCIP_DIGRAPH **digraph)
Definition: misc.c:7568
void SCIPdigraphPrint(SCIP_DIGRAPH *digraph, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: misc.c:8550
int * SCIPdigraphGetSuccessors(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:7819
SCIP_RETCODE SCIPcreateDigraph(SCIP *scip, SCIP_DIGRAPH **digraph, int nnodes)
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
Definition: scip_prob.c:117
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
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip_message.c:88
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 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 SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:557
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
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 SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8715
SCIP_Bool SCIPstrToIntValue(const char *str, int *value, char **endptr)
Definition: misc.c:10946
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:10977
void SCIPprintSysError(const char *message)
Definition: misc.c:10769
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:10818
SCIP_RETCODE SCIPinitializeHeurListScheduling(SCIP *scip, SCIP_DIGRAPH *precedencegraph, SCIP_VAR **vars, int *durations, int **resourcedemands, int *capacities, int njobs, int nresources)
scheduling specific primal heuristic which is based on bidirectional serial generation scheme.
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:43
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebug(x)
Definition: pub_message.h:93
#define SCIPdebugMessage
Definition: pub_message.h:96
reading_states
Definition: reader_sm.c:67
@ ERROR
Definition: reader_sm.c:68
@ PRECEDENCES
Definition: reader_sm.c:75
@ RESOURCECAPACITIES
Definition: reader_sm.c:74
@ JOBS
Definition: reader_sm.c:71
@ RESOURCENAMES
Definition: reader_sm.c:73
@ NEXT
Definition: reader_sm.c:69
@ NJOBS
Definition: reader_sm.c:70
@ END
Definition: reader_sm.c:76
@ NRESOURCES
Definition: reader_sm.c:72
static void checkForNewSection(char *linestr, STATE *state)
Definition: reader_sm.c:176
static void parseError(SCIP *scip, int lineno, const char *msg, const char *erritem, STATE *state)
Definition: reader_sm.c:151
#define DEFAULT_FILENAME
Definition: reader_sm.c:59
SCIP_RETCODE SCIPcreateSchedulingProblem(SCIP *scip, const char *problemname, const char **jobnames, const char **resourcenames, int **demands, SCIP_DIGRAPH *precedencegraph, int *durations, int *capacities, int njobs, int nresources, SCIP_Bool initialize)
Definition: reader_sm.c:747
SCIP_RETCODE SCIPincludeReaderSm(SCIP *scip)
Definition: reader_sm.c:716
static int computeUbmakespan(int *durations, int njobs, SCIP_DIGRAPH *precedencegraph)
Definition: reader_sm.c:468
struct SCIP_RcpspData SCIP_RCPSPDATA
Definition: reader_sm.c:93
static SCIP_RETCODE getResourcesNames(SCIP *scip, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:276
#define READER_DESC
Definition: reader_sm.c:50
static SCIP_RETCODE getNJobs(SCIP *scip, int lineno, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:238
static SCIP_RETCODE getNResources(SCIP *scip, int lineno, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:198
static SCIP_RETCODE getPrecedence(SCIP *scip, char *s, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:405
static SCIP_RETCODE readFile(SCIP *scip, const char *filename, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:509
#define READER_EXTENSION
Definition: reader_sm.c:51
static SCIP_RETCODE getResourcesCapacities(SCIP *scip, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:314
static SCIP_DECL_READERREAD(readerReadSm)
Definition: reader_sm.c:631
enum reading_states STATE
Definition: reader_sm.c:78
#define READER_NAME
Definition: reader_sm.c:49
static SCIP_RETCODE getJobs(SCIP *scip, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:341
#define SM_MAX_LINELEN
Definition: reader_sm.c:65
static SCIP_DECL_READERCOPY(readerCopySm)
Definition: reader_sm.c:617
scheduling problem file reader for RCPSP format
@ SCIP_VERBLEVEL_MINIMAL
Definition: type_message.h:54
struct SCIP_ReaderData SCIP_READERDATA
Definition: type_reader.h:53
@ SCIP_SUCCESS
Definition: type_result.h:58
@ SCIP_FILECREATEERROR
Definition: type_retcode.h:48
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_VARTYPE_INTEGER
Definition: type_var.h:63