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