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-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
    66 ERROR = 0,
    74 END
    75};
    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
    804 SCIP_CALL( SCIPaddVar(scip, var) );
    806 jobs[j] = var;
    807 SCIP_CALL( SCIPreleaseVar(scip, &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
    814 SCIP_CALL( SCIPaddVar(scip, var) );
    816
    817 jobs[njobs-1] = var;
    818 SCIP_CALL( SCIPreleaseVar(scip, &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
    874 SCIP_CALL( SCIPallocBufferArray(scip, &vars, njobs) );
    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
    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: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,...)
    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: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 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:700
    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: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
    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: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
    #define DEFAULT_FILENAME
    Definition: reader_sm.c:57
    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
    #define READER_DESC
    Definition: reader_sm.c:48
    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
    #define READER_EXTENSION
    Definition: reader_sm.c:49
    static SCIP_RETCODE getResourcesCapacities(SCIP *scip, char *linestr, STATE *state, SCIP_RCPSPDATA *rcpspdata)
    Definition: reader_sm.c:312
    static SCIP_DECL_READERREAD(readerReadSm)
    Definition: reader_sm.c:630
    enum reading_states STATE
    Definition: reader_sm.c:76
    #define READER_NAME
    Definition: reader_sm.c:47
    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
    static SCIP_DECL_READERCOPY(readerCopySm)
    Definition: reader_sm.c:615
    scheduling problem file reader for RCPSP format
    @ SCIP_VERBLEVEL_MINIMAL
    Definition: type_message.h:59
    struct SCIP_ReaderData SCIP_READERDATA
    Definition: type_reader.h:54
    @ 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
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARTYPE_INTEGER
    Definition: type_var.h:65