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