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 
45 #include "scip/cons_cumulative.h"
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,
77 };
78 typedef enum reading_states STATE;
79 
80 
81 /** data structure for resources constrained project scheduling problems */
82 struct 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 };
93 typedef 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 */
102 static
103 void 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 */
150 static
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 */
175 static
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 */
197 static
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 */
237 static
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 */
275 static
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 */
313 static
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 */
340 static
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 */
404 static
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 */
467 static
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 */
508 static
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 
583  case RESOURCECAPACITIES:
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) */
616 static
617 SCIP_DECL_READERCOPY(readerCopySm)
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 */
630 static
631 SCIP_DECL_READERREAD(readerReadSm)
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);
664  return SCIP_FILECREATEERROR;
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) );
806  SCIP_CALL( SCIPmarkDoNotMultaggrVar(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) );
816  SCIP_CALL( SCIPmarkDoNotMultaggrVar(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 
902  SCIP_CALL( SCIPcreateConsCumulative(scip, &cons, name,
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);
920  SCIPfreeBufferArray(scip, &vars);
921  SCIPfreeBufferArray(scip, &jobs);
922 
923  return SCIP_OKAY;
924 }
static void checkForNewSection(char *linestr, STATE *state)
Definition: reader_sm.c:176
void ** SCIPdigraphGetSuccessorsData(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:7837
SCIP_RETCODE SCIPgetStringParam(SCIP *scip, const char *name, char **value)
Definition: scip_param.c:345
Definition: reader_sm.c:71
#define NULL
Definition: def.h:267
static SCIP_RETCODE getJobs(SCIP *scip, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:341
constraint handler for cumulative constraints
Constraint handler for variable bound constraints .
#define SCIP_MAXSTRLEN
Definition: def.h:288
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
static SCIP_RETCODE getNJobs(SCIP *scip, int lineno, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:238
int * SCIPdigraphGetSuccessors(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:7819
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:557
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1250
#define FALSE
Definition: def.h:94
#define READER_DESC
Definition: reader_sm.c:50
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
#define TRUE
Definition: def.h:93
#define SCIPdebug(x)
Definition: pub_message.h:93
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
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_Bool SCIPstrToIntValue(const char *str, int *value, char **endptr)
Definition: misc.c:10946
#define SCIPdebugMessage
Definition: pub_message.h:96
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip_message.c:88
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
static int computeUbmakespan(int *durations, int njobs, SCIP_DIGRAPH *precedencegraph)
Definition: reader_sm.c:468
static SCIP_RETCODE getPrecedence(SCIP *scip, char *s, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:405
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
SCIP_RETCODE SCIPcreateDigraph(SCIP *scip, SCIP_DIGRAPH **digraph, int nnodes)
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_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:153
static void parseError(SCIP *scip, int lineno, const char *msg, const char *erritem, STATE *state)
Definition: reader_sm.c:151
static SCIP_RETCODE getNResources(SCIP *scip, int lineno, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:198
static SCIP_DECL_READERREAD(readerReadSm)
Definition: reader_sm.c:631
static SCIP_RETCODE getResourcesCapacities(SCIP *scip, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:314
#define SCIPerrorMessage
Definition: pub_message.h:64
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
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)
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:43
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:200
SCIP_RETCODE SCIPincludeReaderSm(SCIP *scip)
Definition: reader_sm.c:716
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8717
void SCIPdigraphPrint(SCIP_DIGRAPH *digraph, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: misc.c:8550
#define SCIP_CALL(x)
Definition: def.h:380
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
SCIP_RETCODE SCIPdigraphAddArc(SCIP_DIGRAPH *digraph, int startnode, int endnode, void *data)
Definition: misc.c:7662
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
struct SCIP_ReaderData SCIP_READERDATA
Definition: type_reader.h:53
int SCIPdigraphGetNSuccessors(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:7804
#define SCIP_Bool
Definition: def.h:91
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 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
void SCIPprintSysError(const char *message)
Definition: misc.c:10769
static SCIP_RETCODE readFile(SCIP *scip, const char *filename, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:509
static SCIP_DECL_READERCOPY(readerCopySm)
Definition: reader_sm.c:617
struct SCIP_RcpspData SCIP_RCPSPDATA
Definition: reader_sm.c:93
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:10977
Definition: reader_sm.c:69
enum reading_states STATE
Definition: reader_sm.c:78
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
Definition: reader_sm.c:76
#define SM_MAX_LINELEN
Definition: reader_sm.c:65
Constraint handler for linear constraints in their most general form, .
static long * number
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
scheduling problem file reader for RCPSP format
SCIP_Real * r
Definition: circlepacking.c:59
#define MAX(x, y)
Definition: def.h:239
#define READER_EXTENSION
Definition: reader_sm.c:51
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
reading_states
Definition: reader_sm.c:67
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1174
#define DEFAULT_FILENAME
Definition: reader_sm.c:59
SCIP_RETCODE SCIPinitializeHeurListScheduling(SCIP *scip, SCIP_DIGRAPH *precedencegraph, SCIP_VAR **vars, int *durations, int **resourcedemands, int *capacities, int njobs, int nresources)
#define SCIP_Real
Definition: def.h:173
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
#define READER_NAME
Definition: reader_sm.c:49
static SCIP_RETCODE getResourcesNames(SCIP *scip, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
Definition: reader_sm.c:276
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:232
void SCIPdigraphFree(SCIP_DIGRAPH **digraph)
Definition: misc.c:7568
#define SCIPABORT()
Definition: def.h:352
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:10818
void SCIPdigraphPrintGml(SCIP_DIGRAPH *digraph, FILE *file)
Definition: misc.c:8585
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
scheduling specific primal heuristic which is based on bidirectional serial generation scheme...