Exemplo n.º 1
0
void
DDSIP_PrintStateUB (int heur)
{
    double wall_secs, cpu_secs;
    int    wall_hrs, wall_mins, cpu_hrs, cpu_mins;

    printf ("*%6d  %6d        ", DDSIP_bb->curnode, DDSIP_bb->nonode);
    fprintf (DDSIP_outfile, "*%6d  %6d        ", DDSIP_bb->curnode, DDSIP_bb->nonode);

    if (DDSIP_bb->DDSIP_step == eev)
    {
        printf ("   exp. value sol ");
        fprintf (DDSIP_outfile, "   exp. value sol ");
    }
    else if (DDSIP_bb->DDSIP_step == adv)
    {
        fprintf (DDSIP_outfile, "   start point    ");
    }
    else
    {
        printf ("     Heuristic %2d ", heur);
        fprintf (DDSIP_outfile, "     Heuristic %2d ", heur);
    }

    // DDSIP_bb->heurval contains the objective value of the heuristic solution
    // DDSIP_bb->skip indicates whether the evaluation of an heuristic solution was skip for some reason
    printf ("  %-16.12g", DDSIP_bb->heurval);
    fprintf (DDSIP_outfile, "  %-16.12g", DDSIP_bb->heurval);

    if (fabs (DDSIP_bb->bestvalue) < DDSIP_infty)
    {
        printf ("  %-16.12g", DDSIP_bb->bestvalue);
        fprintf (DDSIP_outfile, "  %-16.12g", DDSIP_bb->bestvalue);
    }
    else
    {
        printf ("                  ");
        fprintf (DDSIP_outfile, "                  ");
    }

    printf ("                                               ");
    fprintf (DDSIP_outfile,"                                               ");

    DDSIP_translate_time (DDSIP_GetCpuTime(),&cpu_hrs,&cpu_mins,&cpu_secs);
    time (&DDSIP_bb->cur_time);
    DDSIP_translate_time (difftime(DDSIP_bb->cur_time,DDSIP_bb->start_time),&wall_hrs,&wall_mins,&wall_secs);
    printf ("  %3dh %02d:%02.0f  %3dh %02d:%02.0f\n", wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs);
    fprintf (DDSIP_outfile,"  %3dh %02d:%02.0f  %3dh %02d:%02.0f\n", wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs);
}
Exemplo n.º 2
0
void
DDSIP_PrintState (int noiter)
{
    //  char    state[DDSIP_max_str_ln];
    double wall_secs, cpu_secs;
    int    wall_hrs, wall_mins, cpu_hrs, cpu_mins, print_violations = 1;
    double rgap, factor;
    //best<>0 ?

    if (!DDSIP_Equal (fabs (DDSIP_bb->bestvalue), 0.0))
        rgap = 100. * (DDSIP_bb->bestvalue - DDSIP_bb->bestbound) / fabs (DDSIP_bb->bestvalue);
    else
        rgap = 100. * (DDSIP_bb->bestvalue - DDSIP_bb->bestbound) / (fabs (DDSIP_bb->bestvalue) + DDSIP_param->accuracy);

    rgap = DDSIP_Dmin (rgap, 100.0);
    factor = (DDSIP_bb->bestvalue < 0.)? 1.-1.e-12 :  1.+1.e-12;

    // A headline is printed every 20th call
    if (!((noiter) % (DDSIP_param->logfreq * 20)) || (DDSIP_param->cb && !(noiter % DDSIP_Imax(DDSIP_param->cb,10)) && DDSIP_param->outlev > 1))
    {
        printf ("\n   Node   Nodes    Left  Objective         Heuristic");
        fprintf (DDSIP_outfile, "\n   Node   Nodes    Left  Objective         Heuristic");
        printf ("         Best Value        Bound             Viol./Dispersion        Gap   Wall Time    CPU Time   Father Depth\n");
        fprintf (DDSIP_outfile, "         Best Value        Bound             Viol./Dispersion        Gap   Wall Time    CPU Time   Father Depth\n");
    }

    if (!DDSIP_bb->violations && fabs(DDSIP_bb->bestvalue - DDSIP_node[DDSIP_bb->curnode]->bound)/(fabs(DDSIP_bb->bestvalue) + 3.e-16) < 5.e-16)
    {
        printf ("*%6d  %6d  %6d", DDSIP_bb->curnode, DDSIP_bb->nonode, DDSIP_bb->nofront);
        fprintf (DDSIP_outfile, "*%6d  %6d  %6d", DDSIP_bb->curnode, DDSIP_bb->nonode, DDSIP_bb->nofront);
    }
    else
    {
        printf (" %6d  %6d  %6d", DDSIP_bb->curnode, DDSIP_bb->nonode, DDSIP_bb->nofront);
        fprintf (DDSIP_outfile, " %6d  %6d  %6d", DDSIP_bb->curnode, DDSIP_bb->nonode, DDSIP_bb->nofront);
    }

    //bound=inf
    if (DDSIP_node[DDSIP_bb->curnode]->bound >= DDSIP_infty)
    {
        printf ("       infeasible ");
        fprintf (DDSIP_outfile, "       infeasible ");
        print_violations  = 0;
    }
    else if (DDSIP_node[DDSIP_bb->curnode]->bound > DDSIP_bb->bestvalue*factor)
    {
        printf ("       cutoff     ");
        fprintf (DDSIP_outfile, "       cutoff     ");
        print_violations  = 0;
    }
    else if (DDSIP_node[DDSIP_bb->curnode]->bound < DDSIP_infty)
    {
        printf ("  %-16.12g", DDSIP_node[DDSIP_bb->curnode]->bound);
        fprintf (DDSIP_outfile, "  %-16.12g", DDSIP_node[DDSIP_bb->curnode]->bound);
    }
    //bound=-inf
    else
    {
        printf ("        unbounded ");
        fprintf (DDSIP_outfile, "        unbounded ");
    }

    // DDSIP_bb->heurval contains the objective value of the heuristic solution
    // DDSIP_bb->skip indicates whether the evaluation of an heuristic solution was skipped for some reason
    if (fabs (DDSIP_bb->heurval) < DDSIP_infty)
    {
        printf ("  %-16.12g", DDSIP_bb->heurval);
        fprintf (DDSIP_outfile, "  %-16.12g", DDSIP_bb->heurval);
    }
    else
    {
        if (DDSIP_bb->skip >= 100)
        {
            // Print the number of the scenario which caused the stop
            printf ("         %4d-stop", DDSIP_bb->skip - 100 + 1);
            fprintf (DDSIP_outfile, "         %4d-stop", DDSIP_bb->skip - 100 + 1);
        }
        else if (DDSIP_bb->skip == 2 || DDSIP_bb->skip == 1 ||  DDSIP_bb->skip == 3)
        {
            printf ("                  ");
            fprintf (DDSIP_outfile, "                  ");
        }
        else if (DDSIP_bb->skip == 4)
        {
            printf ("     multiple     ");
            fprintf (DDSIP_outfile, "     multiple     ");
        }
        else
        {
            printf ("   infeasible     ");
            fprintf (DDSIP_outfile, "   infeasible     ");
        }
    }

    if (fabs (DDSIP_bb->bestvalue) < DDSIP_infty)
    {
        printf ("  %-16.12g", DDSIP_bb->bestvalue);
        fprintf (DDSIP_outfile, "  %-16.12g", DDSIP_bb->bestvalue);
    }
    else
    {
        printf ("                  ");
        fprintf (DDSIP_outfile, "                  ");
    }

    if (fabs (DDSIP_bb->bestbound - DDSIP_infty) < DDSIP_param->accuracy)
    {
        printf ("        infeasible");
        fprintf (DDSIP_outfile, "        infeasible");
    }
    else
    {
        printf ("  %-16.12g", DDSIP_bb->bestbound);
        fprintf (DDSIP_outfile, "  %-16.12g", DDSIP_bb->bestbound);
    }

    if (!print_violations || fabs (DDSIP_bb->bestbound - DDSIP_infty) < DDSIP_param->accuracy || fabs(DDSIP_node[DDSIP_bb->curnode]->dispnorm) >= DDSIP_infty)
    {
        printf ("                  ");
        fprintf (DDSIP_outfile, "                  ");
    }
    else
    {
        //number of violations of nonanticipativity
        printf ("  %4d",DDSIP_bb->violations);
        fprintf (DDSIP_outfile, "  %4d",DDSIP_bb->violations);
        //max dispersion of the variables
        printf ("  %-10.5g",DDSIP_node[DDSIP_bb->curnode]->dispnorm);
        fprintf (DDSIP_outfile, "  %-10.5g",DDSIP_node[DDSIP_bb->curnode]->dispnorm);
    }

    if (DDSIP_bb->bestvalue < DDSIP_infty && fabs (DDSIP_bb->bestbound) < DDSIP_infty)
    {
        printf (" %9.4g%%", rgap);
        fprintf (DDSIP_outfile, " %9.4g%%", rgap);
    }
    else
    {
        printf ("           ");
        fprintf (DDSIP_outfile, "           ");
    }

    DDSIP_translate_time (DDSIP_GetCpuTime(),&cpu_hrs,&cpu_mins,&cpu_secs);
    time (&DDSIP_bb->cur_time);
    DDSIP_translate_time (difftime(DDSIP_bb->cur_time,DDSIP_bb->start_time),&wall_hrs,&wall_mins,&wall_secs);
    printf ("  %3dh %02d:%02.0f  %3dh %02d:%02.0f %8d %5d\n", wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs,DDSIP_node[DDSIP_bb->curnode]->father,DDSIP_node[DDSIP_bb->curnode]->depth);
    fprintf (DDSIP_outfile,"  %3dh %02d:%02.0f  %3dh %02d:%02.0f %8d %5d\n" ,wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs,DDSIP_node[DDSIP_bb->curnode]->father,DDSIP_node[DDSIP_bb->curnode]->depth);
}
Exemplo n.º 3
0
//==========================================================================
int
main (int argc, char * argv[])
{
    // Temporary variables
    struct stat filestat;

    char astring[DDSIP_ln_fname];

    int status = 0, cont, boundstat, comb, i;

    // guarantee minimal stacksize limit
    const rlim_t kStackSize = 128 * 1024 * 1024;   // min stack size = 128 MB
    struct rlimit rl;
    int result;
    unsigned long cur_limit;

    result = getrlimit(RLIMIT_STACK, &rl);
    if (result == 0)
    {
        cur_limit = rl.rlim_cur;
        printf ("original stacksize limit %lu\n", cur_limit);
        if (rl.rlim_cur < kStackSize)
        {
            rl.rlim_cur = kStackSize;
            result = setrlimit(RLIMIT_STACK, &rl);
            if (result != 0)
            {
                fprintf(stderr, "setrlimit returned result = %d\n", result);
            }
            result = getrlimit(RLIMIT_STACK, &rl);
            if (result == 0)
            {
                cur_limit = rl.rlim_cur;
                printf ("changed  stacksize limit %lu\n", cur_limit);
            }
        }
    }

    i = argc;
    //

    // Welcome
    printf ("#######################################################################################\n");
    printf ("#########  D D S I P -- Dual Decomposition In Stochastic Integer Programming  #########\n");
    printf ("#########  %-66s #########\n", DDSIP_version);
    printf ("For copyright, license agreements, help, comments, requests, ... ");
    printf ("see\n\thttp://www.uni-duisburg-essen.de/~hn215go/ddsip.shtml\n");
    printf ("\thttp://www.www.github.com/RalfGollmer/ddsip\n");
    /*    printf ("  Copyright (C) to University of Duisburg-Essen \n\n"); */
    /*    printf("  This program is free software; you can redistribute it and/or\n"); */
    /*    printf ("  modify it under the terms of the GNU General Public License\n"); */
    /*    printf("  as published by the Free Software Foundation; either version 2\n"); */
    /*    printf ("  of the License, or (at your option) any later version.\n\n"); */
    /*    printf ("  This program is distributed in the hope that it will be useful,\n"); */
    /*    printf("  but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); */
    /*    printf ("  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"); */
    /*    printf ("  GNU General Public License for more details.\n\n"); */
    /*    printf ("  You should have received a copy of the GNU General Public License\n"); */
    /*    printf("  along with this program; if not, write to the Free Software\n"); */
    /*    printf ("  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n"); */
    /*    printf ("==============================================================================\n\n"); */

    // These four structures shall carry the whole problem data
    DDSIP_param = NULL;
    DDSIP_bb = NULL;
    DDSIP_data = NULL;
    DDSIP_node = NULL;

    // In DDSIP some signals are handled seperatly
    DDSIP_RegisterSignalHandlers ();

    // Create output directory if it doesn't already exist
    if (stat (DDSIP_outdir, &filestat) == -1)
    {
        sprintf (astring, "mkdir %s\n", DDSIP_outdir);
        i = system (astring);
        printf ("Creating subdirectory %s ...\n", DDSIP_outdir);
    }
    // remove possibly existing output file
    sprintf (astring, "rm -f %s\n", DDSIP_outfname);
    i = system (astring);
    // Open output file
    if ((DDSIP_outfile = fopen (DDSIP_outfname, "a")) == NULL)
    {
        fprintf (stderr, "ERROR: Cannot open '%s'. \n", DDSIP_outfname);
        status = 107;
        goto TERMINATE;
    }

    setbuf (DDSIP_outfile, 0);
    fprintf (DDSIP_outfile, "%s\n", argv[0]);
    fprintf (DDSIP_outfile, "-----------------------------------------------------------\n");
    fprintf (DDSIP_outfile, "current system time: ");
    fflush (DDSIP_outfile);
#ifndef _WIN32
    i = system ("date");
    // Print time to output file
    sprintf (astring, "date >> %s\n", DDSIP_outfname);
    i = system (astring);
    fprintf (DDSIP_outfile, "host            : ");
    sprintf (astring, "hostname >> %s; cat /proc/cpuinfo | sed '/processor.*: 0/,/^$/!d' |grep -E 'vendor|cpu |model|stepping|MHz|cache |cores' >> %s\n", DDSIP_outfname, DDSIP_outfname);
    for (i = 0; i < 100; i++)
        exp(1.11*(-i-2));
    i = system (astring);
#else
    sprintf (astring, "date /T >> %s & time /T >> %s\n", DDSIP_outfname,DDSIP_outfname);
    i = system (astring);
#endif

    fprintf (DDSIP_outfile, "\nDDSIP  %s\n", DDSIP_version);
    fprintf (DDSIP_outfile, "-----------------------------------------------------------\n");

    // Open cplex environment
    DDSIP_env = CPXopenCPLEX (&status);
    if (DDSIP_env == NULL)
    {
        fprintf (stderr, "ERROR: Failed to open cplex environment, CPLEX error code %d.\n",status);
        fprintf (DDSIP_outfile, "ERROR: Failed to open cplex environment, CPLEX error code %d.\n",status);
        return status;
    }
    sprintf (astring, "%s", CPXversion (DDSIP_env));
    printf ("CPLEX version is %s\n", astring);
    fprintf (DDSIP_outfile, "CPLEX version is %s\n\n", astring);

    // Allocate the structures to hold the information on the problem
    DDSIP_param = (para_t *) DDSIP_Alloc (sizeof (para_t), 1, "param(Main)");
    DDSIP_bb    = (bb_t *)   DDSIP_Alloc (sizeof (bb_t),   1, "bb(Main)");
    DDSIP_data  = (data_t *) DDSIP_Alloc (sizeof (data_t), 1, "data(Main)");

    // Read model (lp) file
    if ((status = DDSIP_ReadModel ()))
        goto TERMINATE;

    // Read specification file
    if ((status = DDSIP_ReadSpec ()))
        goto TERMINATE;

    // Set specified CPLEX parameters
    if ((status = DDSIP_InitCpxPara ()))
        goto TERMINATE;

    // if a Benders annotation file is given, read it
    if (DDSIP_param->annotationFile)
    {
        status = CPXreadcopyannotations (DDSIP_env, DDSIP_lp, DDSIP_param->annotationFile);
        if ( status ) {
           fprintf (stderr, "ERROR: Failed to read and copy the annotation data from file %s.\n", DDSIP_param->annotationFile);
           fprintf (DDSIP_outfile, "ERROR: Failed to read and copy the annotation data from file %s.\n", DDSIP_param->annotationFile);
           goto TERMINATE;
        }
    }

    // data->cost contains: stoch. costs for all scenarios, followed by the original costs
    DDSIP_data->cost =
        (double *) DDSIP_Alloc (sizeof (double),
                                DDSIP_param->scenarios * DDSIP_param->stoccost + DDSIP_data->novar, "cost (ReadData)");
    // Store original objective coefficients
    status = CPXgetobj (DDSIP_env, DDSIP_lp, DDSIP_data->cost + DDSIP_param->scenarios * DDSIP_param->stoccost, 0, DDSIP_data->novar - 1);
    if (status)
    {
        fprintf (stderr, "ERROR: Failed to get objective coefficients\n");
        fprintf (DDSIP_outfile, "ERROR: Failed to get objective coefficients\n");
        goto TERMINATE;
    }

    DDSIP_bb->moreoutfile = NULL;
    if (DDSIP_param->outlev)
    {
        // Open debug output file
        if ((DDSIP_bb->moreoutfile = fopen (DDSIP_moreoutfname, "a")) == NULL)
        {
            fprintf (stderr, "ERROR: Cannot open '%s'. \n", DDSIP_moreoutfname);
            fprintf (DDSIP_outfile, "ERROR: Cannot open '%s'. \n", DDSIP_moreoutfname);
            status = 109;
            goto TERMINATE;
        }
        if (DDSIP_param->outlev > 10)
        {
            // Buffer size = 0
            setbuf (stdout, 0);
            if (DDSIP_param->outlev > 20)
                setbuf (DDSIP_bb->moreoutfile, 0);
        }
#ifndef _WIN32
        // Print time to output file
        sprintf (astring, "date > %s\n", DDSIP_moreoutfname);
        i = system (astring);
#else
        sprintf (astring, "date /T > %s & time /T >> %s\n", DDSIP_moreoutfname,DDSIP_moreoutfname);
        i = system (astring);
#endif
        fprintf (DDSIP_bb->moreoutfile, "--------------------------------------------------------------");
        fprintf (DDSIP_bb->moreoutfile, "---------\nThis is an additional output file of DDSIP. The ");
        fprintf (DDSIP_bb->moreoutfile, "actual amount of output\nis controlled by the parameter ");
        fprintf (DDSIP_bb->moreoutfile, "OUTLEV in the specification file.\n---------");
        fprintf (DDSIP_bb->moreoutfile, "--------------------------------------------------------------\n\n");
    }

    DDSIP_node = (node_t **) DDSIP_Alloc (sizeof (node_t *), DDSIP_param->nodelim + 3, "node(Main)");
    DDSIP_node[0] = (node_t *) DDSIP_Alloc (sizeof (node_t), 1, "node[0](Main)");
    DDSIP_node[0]->first_sol = (double **) DDSIP_Alloc (sizeof (double *), DDSIP_param->scenarios, "node[0]->first_sol(Main)");
    DDSIP_node[0]->cursubsol = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->cursubsol(Main)");
    DDSIP_node[0]->subbound = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->subbound(Main)");
    if (DDSIP_param->cb)
    {
        DDSIP_node[0]->scenBoundsNoLag = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->scenBoundsNoLag(Main)");
        DDSIP_node[0]->BoundNoLag = -DDSIP_infty;

    }
    DDSIP_node[0]->mipstatus = (int *) DDSIP_Alloc (sizeof (int), DDSIP_param->scenarios, "node[0]->mipstatus(Main)");
    DDSIP_node[0]->ref_scenobj = (double *) DDSIP_Alloc (sizeof (double), DDSIP_param->scenarios, "node[0]->ref_scenobj(Main)");

    // Prepare first and second stage variables
    if ((status = DDSIP_InitStages ()))
    {
        fprintf (stderr, "ERROR: Failed to initialize stages\n");
        fprintf (DDSIP_outfile, "ERROR: Failed to initialize stages\n");
        goto TERMINATE;
    }

    // Read data file(s)
    if ((status = DDSIP_ReadData ()))
        goto TERMINATE;

    // Read order file if specified
    if (DDSIP_param->cpxorder)
    {
        status = CPXsetintparam (DDSIP_env, CPX_PARAM_MIPORDIND, 1);
        if (status)
        {
            fprintf (stderr, "ERROR: Failed to set cplex parameter CPX_PARAM_MIPORDIND.\n");
            return status;
        }
        if (DDSIP_ReadCPLEXOrder ())
            goto TERMINATE;
    }

    // Detect first and second stage constraints
    if ((status = DDSIP_DetectStageRows ()))
    {
        fprintf (stderr, "ERROR: Failed detection of row stages (BbInit)\n");
        fprintf (DDSIP_outfile, "ERROR: Failed detection of row stages (BbInit)\n");
        goto TERMINATE;
    }

    DDSIP_bb->DDSIP_step =  solve;

#ifdef CONIC_BUNDLE
    if (DDSIP_param->cb)
    {
        status = DDSIP_NonAnt ();
        if (status)
            goto TERMINATE;
    }
#endif

    if (DDSIP_param->outlev)
    {
        printf ("\t Total initialization time: %4.2f seconds.\n", DDSIP_GetCpuTime ());
        fprintf (DDSIP_bb->moreoutfile, " Total initialization time: %4.2f seconds.\n", DDSIP_GetCpuTime ());
    }
#ifndef _WIN32
    sprintf (astring, "grep 'MHz' /proc/cpuinfo|sort -r|head -1 >> %s\n", DDSIP_outfname);
    i = system (astring);
#endif

    // at the start there is no solution
    status = CPXsetintparam (DDSIP_env, CPX_PARAM_ADVIND, 0);
    if (status)
    {
        fprintf (stderr, "ERROR: Failed to set cplex parameter CPX_PARAM_ADVIND.\n");
        fprintf (DDSIP_outfile, "ERROR: Failed to set cplex parameter CPX_PARAM_ADVIND.\n");
        return status;
    }

#ifndef NEOS
    // Write deterministic equivalent (only expectation-based cases)
    if (DDSIP_param->write_detequ)
        DDSIP_DetEqu ();
#endif
    if (DDSIP_param->riskmod < 0)
    {
        fprintf (stderr, " pure risk models are disabled for now, exiting.\n");
        fprintf (DDSIP_outfile, " pure risk models are disabled for now, exiting.\n");
        goto TERMINATE;
    }
    if (DDSIP_param->stoccost && DDSIP_param->riskmod)
    {
        fprintf (DDSIP_outfile, "XXX Error: Risk optimization not implemented for stochastic cost coefficients.\n");
        fprintf (stderr, "XXX Error: Risk optimization not implemented for stochastic cost coefficients.\n");
        goto TERMINATE;
    }

    // Read advanced starting info
    if (DDSIP_param->advstart)
    {
        DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = adv;

        if ((status = DDSIP_AdvStart ()))
            goto TERMINATE;

        // Solution provided?
        if (DDSIP_param->advstart == 2)
        {
            DDSIP_bb->curnode = 0;
            DDSIP_bb->sug[DDSIP_param->nodelim + 2] = (struct sug_l *)DDSIP_Alloc (sizeof (sug_t), 1, "sug[0](Advanced start solution)");
            (DDSIP_bb->sug[DDSIP_param->nodelim + 2])->firstval =
                (double *) DDSIP_Alloc (sizeof (double), DDSIP_bb->firstvar, "sug[0]->firstval(adv start)");
            for (i = 0; i < (DDSIP_bb->firstvar); i++)
                (DDSIP_bb->sug[DDSIP_param->nodelim + 2]->firstval)[i] = DDSIP_bb->adv_sol[i];
            (DDSIP_bb->sug[DDSIP_param->nodelim + 2])->next = NULL;
            if ((status = DDSIP_UpperBound (DDSIP_param->scenarios, 0)) && status < 100000)
                goto TERMINATE;
        }
        // Only weak consistency check:
        if ((DDSIP_node[0]->bound) > DDSIP_bb->bestvalue)
        {
            status = 121;
            goto TERMINATE;
        }
        fprintf (DDSIP_outfile, "-----------------------------------------------------------\n\n");
    }
    // Solve EV and EEV if specified
    if (DDSIP_param->expected)
    {
        DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = eev;

        // status = 1 -> ExpValProb infeasible
        if ((status = DDSIP_ExpValProb ()) == 1)
        {
            if (DDSIP_param->outlev)
                fprintf (DDSIP_bb->moreoutfile, "    exp. val. prob: INFEASIBLE\n");
            fprintf (DDSIP_outfile, "    exp. val. prob: INFEASIBLE\n");
        }

        if (!status)
        {
            DDSIP_bb->curnode = 0;
            DDSIP_bb->sug[DDSIP_param->nodelim + 2] = (struct sug_l *)DDSIP_Alloc (sizeof (sug_t), 1, "sug[0](Advanced start solution)");
            DDSIP_bb->sug[DDSIP_param->nodelim + 2]->firstval =
                (double *) DDSIP_Alloc (sizeof (double), DDSIP_bb->firstvar, "sug[i]->firstval(Heuristic)");
            for (i = 0; i < DDSIP_bb->firstvar; i++)
                (DDSIP_bb->sug[DDSIP_param->nodelim + 2]->firstval)[i] = DDSIP_bb->adv_sol[i];
            DDSIP_bb->sug[DDSIP_param->nodelim + 2]->next = NULL;
            if ((status = DDSIP_UpperBound (DDSIP_param->scenarios, 0)) && status < 100000)
                goto TERMINATE;
        }

        if (fabs (DDSIP_bb->expbest) < DDSIP_infty)
        {
            if (DDSIP_param->outlev)
                printf ("\t\t EEV:  %13.7f\n", DDSIP_bb->expbest);
            fprintf (DDSIP_outfile, "-EEV:     %13.7f\n", DDSIP_bb->expbest);
        }
        else
        {
            if (DDSIP_param->outlev)
                printf ("\t\t EEV:  No solution found.\n");
            fprintf (DDSIP_outfile, "-EEV:     No solution found.\n");
        }
    }				// END if (EV)
    // stop here if NODELIM is zero
     if (!(DDSIP_param->nodelim))
         goto TERMINATE;
    // Print cplex log to debugfile
    if (DDSIP_param->outlev > 51)
    {
#ifdef CPLEX_12_8
       if ((status = CPXsetlogfilename (DDSIP_env, DDSIP_moreoutfname, "a")))
           goto TERMINATE;
#else
       if ((status = CPXsetlogfile (DDSIP_env, DDSIP_bb->moreoutfile)))
           goto TERMINATE;
#endif
    }

    // No of DDSIP iterations
    DDSIP_bb->noiter = 0;
    // cont = 1 if no stop criteria is fullfilled
    cont = 1;
    // comb tells in case of a combined heuristic, which one to apply (3 = RoundNear)
    comb = 3;

    if (DDSIP_param->outlev)
        printf ("Starting branch-and-bound algorithm.\n");
    fprintf (DDSIP_outfile, "----------------------------------------------------------------------------------------\n");

    while (cont)
    {
        // the cuts from the root node are contained in every following node model, there is no need to check their violation
        // for the scenario solutions. But the rounding heuristics could violate a cut, so keep them.
#ifdef CONIC_BUNDLE
#ifdef DEBUG
////////////////////////////////////////////
if (DDSIP_bb->curnode && DDSIP_param->outlev)
{ 
if((DDSIP_node[DDSIP_bb->curnode-1])->step == dual)
  fprintf(DDSIP_bb->moreoutfile, "######## last node %d step=dual, leaf= %d,  dualdescitcnt = %d, DDSIP_bb->cutoff= %d\n",DDSIP_bb->curnode-1,(DDSIP_node[DDSIP_bb->curnode-1])->leaf,DDSIP_bb->dualdescitcnt,DDSIP_bb->cutoff);
}
////////////////////////////////////////////
#endif

        if (DDSIP_param->outlev > 20 && DDSIP_bb->curnode && DDSIP_node[DDSIP_node[DDSIP_bb->curnode]->father]->cbReturn32)
            fprintf (DDSIP_bb->moreoutfile, "########## DDSIP_node[%d >father]->cbReturn32 = 1\n", DDSIP_bb->curnode);
        // Dual method
        if ((!DDSIP_bb->curnode || !DDSIP_node[DDSIP_node[DDSIP_bb->curnode]->father]->cbReturn32) &&
            ((DDSIP_param->cb > 0 && (!(DDSIP_bb->noiter % abs(DDSIP_param->cb))) && (abs(DDSIP_param->riskmod) != 4 || DDSIP_bb->noiter)) ||
             (DDSIP_param->cb < 0 && (((DDSIP_node[DDSIP_bb->curnode]->depth <= DDSIP_param->cb_depth) && abs(DDSIP_param->riskmod) != 4) ||
                                      (abs(DDSIP_param->riskmod) == 5 && DDSIP_node[DDSIP_bb->curnode]->depth == 8) ||
                                      (DDSIP_bb->noiter > DDSIP_param->cbBreakIters && 
                                        ((!(DDSIP_bb->noiter % abs(DDSIP_param->cb))) ||
                                         (!((DDSIP_bb->noiter+1) % -DDSIP_param->cb)) ||
                                         (DDSIP_bb->noiter%200 > 199 - DDSIP_param->cbContinuous) ||
                                         (DDSIP_bb->noiter < DDSIP_param->cbContinuous + DDSIP_param->cbBreakIters) ||
                                         ((DDSIP_bb->noiter  >= 2*DDSIP_param->cbBreakIters) && (DDSIP_bb->noiter < DDSIP_param->cbContinuous + 2*DDSIP_param->cbBreakIters)) ||
                                         ((DDSIP_bb->cutoff > 6) &&
                                             (((DDSIP_bb->no_reduced_front < 51) && (DDSIP_bb->noiter % -DDSIP_param->cb) < DDSIP_param->cbContinuous)
                                             || (((DDSIP_node[DDSIP_bb->curnode-1])->step == dual) && (DDSIP_node[DDSIP_bb->curnode-1])->leaf /*&& (DDSIP_bb->dualdescitcnt < 11)*/)
                                             )
                                         )
                                       )
                                     ) ||
                                     (abs(DDSIP_param->riskmod) != 5 && DDSIP_bb->noiter <= DDSIP_param->cbBreakIters && DDSIP_bb->noiter > DDSIP_param->cbBreakIters*.5 &&
                                          (CBFORALL || (DDSIP_node[DDSIP_bb->curnode]->numInheritedSols > (DDSIP_Imin(DDSIP_param->scenarios/20,2)+(DDSIP_param->scenarios+1)/2))))
                                   )
                )
            )
           )
        {
            DDSIP_bb->DDSIP_step = DDSIP_node[DDSIP_bb->curnode]->step = dual;
            if ((status = DDSIP_DualOpt ()))
            {
                if (!DDSIP_bb->curnode)
                    goto TERMINATE;
                else
                {
                    DDSIP_bb->skip = 1;
                    DDSIP_node[DDSIP_bb->curnode]->bound = DDSIP_infty;
                }
            }
        }
        else
        {
            DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = solve;
            // status=1 means there was no solution found to a scenario problem
            if ((status = DDSIP_LowerBound ()))
                goto TERMINATE;
        }
#else
        DDSIP_node[DDSIP_bb->curnode]->step = DDSIP_bb->DDSIP_step = solve;
        // status=1 means there was no solution found to a subproblem
        if ((status = LowerBound ()))
            goto TERMINATE;
#endif

        if (!DDSIP_bb->skip || DDSIP_bb->skip == -1)
        {
            double old_bound;
            int cntr, maxCntr;

            DDSIP_bb->cutAdded = 0;
            DDSIP_EvaluateScenarioSolutions (&comb);
            cntr = 0;
            if (DDSIP_node[DDSIP_bb->curnode]->step != dual)
                maxCntr = DDSIP_param->numberReinits;
            else
                maxCntr = 0;
            old_bound = DDSIP_node[DDSIP_bb->curnode]->bound;
            boundstat = DDSIP_Bound ();
            if (!DDSIP_bb->curnode)
            {
                int cnt, j;
                double lhs;
                cutpool_t *currentCut;
                DDSIP_PrintState (DDSIP_bb->noiter);
                if (DDSIP_bb->cutAdded && DDSIP_param->outlev)
                {
                    fprintf (DDSIP_outfile, " %6d%101d cuts\n", DDSIP_bb->curnode, DDSIP_bb->cutAdded);
                }
                while ((DDSIP_bb->cutAdded || DDSIP_node[0]->step == dual) && cntr < maxCntr)
                {
                    old_bound = DDSIP_node[0]->bound;
                    // Free the solutions from former LowerBound
                    for (i = 0; i < DDSIP_param->scenarios; i++)
                    {
                        if (((DDSIP_node[0])->first_sol)[i])
                        {
                            if (DDSIP_node[0]->step == solve)
                            {
                                currentCut = DDSIP_bb->cutpool;
                                while (currentCut)
                                {
                                    lhs = 0.;
                                    for (j = 0; j < DDSIP_bb->firstvar; j++)
                                    {
                                        lhs += (DDSIP_node[0])->first_sol[i][j] * currentCut->matval[j];
                                    }
                                    if (lhs < currentCut->rhs - 1.e-7)
                                    {
#ifdef DEBUG
                                        if (DDSIP_param->outlev > 50)
                                            fprintf (DDSIP_bb->moreoutfile, "scen %d solution violates cut %d.\n", i+1, currentCut->number);
#endif
                                        if ((cnt = (int) ((((DDSIP_node[0])->first_sol)[i])[DDSIP_bb->firstvar] - 0.9)))
                                        for (j = i + 1; cnt && j < DDSIP_param->scenarios; j++)
                                        {
                                            {
                                                if (((DDSIP_node[0])->first_sol)[j]
                                                  && ((DDSIP_node[0])->first_sol)[i] == ((DDSIP_node[0])->first_sol)[j])
                                                {
                                                    ((DDSIP_node[0])->first_sol)[j] = NULL;
                                                    cnt--;
                                                }
                                            }
                                        }
                                        DDSIP_Free ((void **) &(((DDSIP_node[0])->first_sol)[i]));
                                        break;
                                    }
                                    currentCut = currentCut->prev;
                                }
                            }
                            else
                            {
                               if ((cnt = (int) ((((DDSIP_node[0])->first_sol)[i])[DDSIP_bb->firstvar] - 0.9)))
                               for (j = i + 1; cnt && j < DDSIP_param->scenarios; j++)
                               {
                                   {
                                       if (((DDSIP_node[0])->first_sol)[j]
                                         && ((DDSIP_node[0])->first_sol)[i] == ((DDSIP_node[0])->first_sol)[j])
                                       {
                                           ((DDSIP_node[0])->first_sol)[j] = NULL;
                                           cnt--;
                                       }
                                   }
                               }
                               DDSIP_Free ((void **) &(((DDSIP_node[0])->first_sol)[i]));
                            }
                        }
                    }
                    DDSIP_node[0]->step = DDSIP_bb->DDSIP_step = solve;
                    // status=1 means there was no solution found to a scenario problem
                    if ((status = DDSIP_LowerBound ()))
                        goto TERMINATE;
                    DDSIP_bb->cutAdded = 0;
                    DDSIP_EvaluateScenarioSolutions (&comb);
                    cntr++;
                    DDSIP_bb->bestbound = DDSIP_node[0]->bound;
                    DDSIP_bb->noiter++;
                    DDSIP_PrintState (1);
                    if (DDSIP_bb->cutAdded && DDSIP_param->outlev)
                    {
                        fprintf (DDSIP_outfile, " %6d %82d. reinit: %8d cuts\n", 0, cntr, DDSIP_bb->cutAdded);
                    }
                    if ((DDSIP_node[0]->bound - old_bound)/(fabs(old_bound) + 1e-16) < 1.e-7 ||
                        (DDSIP_bb->bestvalue - DDSIP_node[0]->bound)/(fabs(DDSIP_bb->bestvalue) + 1e-16) < 0.5*DDSIP_param->relgap)
                        break;
                }
                if (DDSIP_param->deleteRedundantCuts)
                    DDSIP_CheckRedundancy(1);
            }
            else
            {
                // Print a line of output at the first, the last and each `ith' node
                if (!DDSIP_bb->noiter || (!((DDSIP_bb->noiter + 1) % DDSIP_param->logfreq)) || (DDSIP_param->outlev && (DDSIP_node[DDSIP_bb->curnode])->step == dual))
                        DDSIP_PrintState (DDSIP_bb->noiter);
                if (DDSIP_bb->cutAdded && DDSIP_param->outlev > 1)
                {
                    fprintf (DDSIP_outfile, " %6d%101d cuts\n", DDSIP_bb->curnode, DDSIP_bb->cutAdded);
                }
            }
        }
        else
        {
            boundstat = DDSIP_Bound ();
            // Print a line of output at the first, the last and each `ith' node
            if (!DDSIP_bb->noiter || (!((DDSIP_bb->noiter + 1) % DDSIP_param->logfreq)) || (DDSIP_param->outlev && (DDSIP_node[DDSIP_bb->curnode])->step == dual))
                DDSIP_PrintState (DDSIP_bb->noiter);
        }
        if (!DDSIP_bb->curnode)
             DDSIP_bb->cutCntr0 = DDSIP_bb->cutNumber;
        else if (DDSIP_param->alwaysBendersCuts)
        {
            if (DDSIP_bb->curnode == 24)
            {
                if (DDSIP_bb->cutCntr0 == DDSIP_bb->cutNumber)
                {
                    if (DDSIP_param->outlev > 20)
                        fprintf (DDSIP_bb->moreoutfile, "### setting alwaysBendersCuts to 0\n");
                    DDSIP_param->alwaysBendersCuts = 0;
                }
                else
                    DDSIP_bb->cutCntr0 = DDSIP_bb->cutNumber;
            }
            else if (DDSIP_bb->curnode == 49)
            {
                if (DDSIP_bb->cutCntr0 == DDSIP_bb->cutNumber)
                {
                    if (DDSIP_param->outlev > 20)
                        fprintf (DDSIP_bb->moreoutfile, "### setting alwaysBendersCuts to 0\n");
                    DDSIP_param->alwaysBendersCuts = 0;
                }
                else
                    DDSIP_bb->cutCntr0 = DDSIP_bb->cutNumber;
            }
            else if (DDSIP_bb->curnode == 99)
            {
                if (DDSIP_bb->cutCntr0 == DDSIP_bb->cutNumber)
                {
                    if (DDSIP_param->outlev > 20)
                        fprintf (DDSIP_bb->moreoutfile, "### setting alwaysBendersCuts to 0\n");
                    DDSIP_param->alwaysBendersCuts = 0;
                }
            }
        }

        // DDSIP_bb->skip > 0 indicates that UpperBound calls have been skipped
        // DDSIP_bb->heurval contains the objective value of the heuristic solution
        // Reset to initial values
        DDSIP_bb->heurval = DDSIP_infty;
        DDSIP_bb->skip = 0;

        cont = DDSIP_Continue (&DDSIP_bb->noiter, &boundstat);
        if (!cont)
        {
            status = boundstat;
            goto TERMINATE;
        }

        if ((status = DDSIP_Branch ()))
            goto TERMINATE;

        if (DDSIP_param->deleteRedundantCuts && !(DDSIP_bb->curnode % 10))
            DDSIP_CheckRedundancy(1);
    }

    // Termination
TERMINATE:


    DDSIP_PrintErrorMsg (status);

    printf ("\nOutput files in directory `%s'.\n", DDSIP_outdir);

    // Free up problem as allocated above
    //
    if (DDSIP_node != NULL)
    {
        DDSIP_FreeFrontNodes ();
        for (i = 0; i < DDSIP_bb->nonode; i++)
            DDSIP_Free ((void **) &(DDSIP_node[i]));
        DDSIP_Free ((void **) &(DDSIP_node));
    }

    if (DDSIP_data != NULL)
    {
        DDSIP_FreeData ();
        DDSIP_Free ((void **) &(DDSIP_data));
    }

    // Free up the problem as allocated by CPXcreateprob, if necessary
    if (DDSIP_lp != NULL)
    {
        status = CPXfreeprob (DDSIP_env, &DDSIP_lp);
        if (status)
            fprintf (stderr, "ERROR: CPXfreeprob failed, error code %d\n", status);
    }
    // Free up the CPLEX environment
    if (DDSIP_env != NULL)
    {
        status = CPXcloseCPLEX (&DDSIP_env);
        if (status)
        {
            char errmsg[1024];
            fprintf (stderr, "ERROR: Failed to close CPLEX environment.\n");
            CPXgeterrorstring (DDSIP_env, status, errmsg);
            fprintf (stderr, "%s\n", errmsg);
        }
    }

    if (DDSIP_bb != NULL)
    {
        DDSIP_FreeBb ();
        DDSIP_Free ((void **) &(DDSIP_bb));
    }

    if (DDSIP_param->outlev)
        printf ("Terminating DDSIP.\n");

    if (DDSIP_param != NULL)
    {
        DDSIP_FreeParam ();
        DDSIP_Free ((void **) &(DDSIP_param));
    }

    fprintf (DDSIP_outfile, "Current system time: ");
#ifndef _WIN32
    i = system ("date");
    // Print time to output file
    sprintf (astring, "date >> %s\n", DDSIP_outfname);
    i = system (astring);
#else
    sprintf (astring, "date /T >> %s & time /T >> %s\n", DDSIP_outfname,DDSIP_outfname);
    i = system (astring);
#endif

    if (DDSIP_outfile != NULL)
        fclose (DDSIP_outfile);

    return 0;
}
Exemplo n.º 4
0
//==========================================================================
// This function solves the expected value problem
int
DDSIP_ExpValProb (void)
{
    int status, j, mipstatus, nodes_1st = -1;
    int wall_hrs, wall_mins,cpu_hrs, cpu_mins;
    double objval, bobjval, time_start, time_end, wall_secs, cpu_secs, gap;

    char fname[DDSIP_ln_fname];

    double *mipx = (double *) DDSIP_Alloc (sizeof (double), (DDSIP_bb->firstvar + DDSIP_bb->secvar),
                                           "mipx(ExpValProb)");

    printf ("Solving expected value problem\n");
    if (DDSIP_param->outlev)
        fprintf (DDSIP_bb->moreoutfile, "Solving expected value problem...\n");

    status = DDSIP_ChgProb (-1, 0);
    if (status)
    {
        fprintf (stderr, "ERROR: Failed to change problem \n");
        goto TERMINATE;
    }

    if (DDSIP_param->files > 1)
    {
        sprintf (fname, "%s/ev%s", DDSIP_outdir, DDSIP_param->coretype);
        status = CPXwriteprob (DDSIP_env, DDSIP_lp, fname, NULL);
        if (status)
        {
            fprintf (stderr, "ERROR: Failed to write problem\n");
            goto TERMINATE;
        }
    }
    // New cplex parameters
    if (DDSIP_param->cpxnoeev)
    {
        status = DDSIP_SetCpxPara (DDSIP_param->cpxnoeev, DDSIP_param->cpxeevisdbl, DDSIP_param->cpxeevwhich, DDSIP_param->cpxeevwhat);
        if (status)
        {
            fprintf (stderr, "ERROR: Failed to set CPLEX parameters (ExpValProb) \n");
            goto TERMINATE;
        }
    }

    time_start = DDSIP_GetCpuTime ();
    mipstatus = CPXmipopt (DDSIP_env, DDSIP_lp);

    // Reset cplex parameters
    if (DDSIP_param->cpxnoeev)
    {
        status = DDSIP_SetCpxPara (DDSIP_param->cpxno, DDSIP_param->cpxisdbl, DDSIP_param->cpxwhich, DDSIP_param->cpxwhat);
        if (status)
        {
            fprintf (stderr, "ERROR: Failed to reset CPLEX parameters (ExpValProb) \n");
            goto TERMINATE;
        }
    }

    if (DDSIP_Error (mipstatus))
    {
        fprintf (stderr, "ERROR: Failed to optimize EXP\n");
        status = mipstatus;
        goto TERMINATE;
    }
    //  Error ? (blatant infeasible, scenario problem limit)
    if (DDSIP_Infeasible (mipstatus))
    {
        status = 1;
        goto TERMINATE;
    }
    // No solution found ? (integer infeasible, some limit (node, time))
    mipstatus = CPXgetstat (DDSIP_env, DDSIP_lp);
    if (DDSIP_NoSolution (mipstatus))
    {
        status = 1;
        goto TERMINATE;
    }

    status = CPXgetx (DDSIP_env, DDSIP_lp, mipx, 0, DDSIP_bb->firstvar + DDSIP_bb->secvar - 1);
    if (status)
    {
        fprintf (stderr, "ERROR: Failed to get solution \n");
        goto TERMINATE;
    }
// output of result
    if (DDSIP_param->outlev)
    {
        status = CPXgetobjval (DDSIP_env, DDSIP_lp, &objval);
        if (status)
        {
            fprintf (stderr, "ERROR*: Failed to get best objective value \n");
            fprintf (DDSIP_outfile, "ERROR*: Failed to get best objective value \n");
            if (DDSIP_param->outlev)
                fprintf (DDSIP_bb->moreoutfile, "ERROR*: Failed to get best objective value \n");
            goto TERMINATE;
        }
        if (mipstatus == CPXMIP_OPTIMAL)
        {
            bobjval = objval;
        }
        else
        {
            status = CPXgetbestobjval (DDSIP_env, DDSIP_lp, &bobjval);
            if (status)
            {
                fprintf (stderr, "ERROR: Failed to get value of best remaining node\n");
                fprintf (DDSIP_outfile, "ERROR: Failed to get value of best remaining node\n");
                if (DDSIP_param->outlev)
                    fprintf (DDSIP_bb->moreoutfile, "ERROR: Failed to get value of best remaining node\n");
                goto TERMINATE;
            }
        }
        gap = 100.0*(objval-bobjval)/(fabs(objval)+1e-4);
        nodes_1st = CPXgetnodecnt (DDSIP_env,DDSIP_lp);
        time_end = DDSIP_GetCpuTime ();
        time_start = time_end-time_start;
        time (&DDSIP_bb->cur_time);
        DDSIP_translate_time (difftime(DDSIP_bb->cur_time,DDSIP_bb->start_time),&wall_hrs,&wall_mins,&wall_secs);
        DDSIP_translate_time (time_end,&cpu_hrs,&cpu_mins,&cpu_secs);
        if (mipstatus == CPXMIP_OPTIMAL)
            fprintf (DDSIP_bb->moreoutfile,
                 "    exp. val. prob:  Best=%-20.14g\tBound=%-20.14g (%9.4g%%)     \t %3dh %02d:%02.0f / %3dh %02d:%05.2f (%6.2fs n: %4d)",
                 objval, bobjval, gap,
                 wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs, time_start, nodes_1st);
        else if (mipstatus == CPXMIP_OPTIMAL_TOL)
            fprintf (DDSIP_bb->moreoutfile,
                 "    exp. val. prob:  Best=%-20.14g\tBound=%-20.14g (%9.4g%%) tol.\t %3dh %02d:%02.0f / %3dh %02d:%05.2f (%6.2fs n: %4d)",
                 objval, bobjval, gap,
                 wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs, time_start, nodes_1st);
        else if (mipstatus == CPXMIP_TIME_LIM_FEAS)
            fprintf (DDSIP_bb->moreoutfile,
                 "    exp. val. prob:  Best=%-20.14g\tBound=%-20.14g (%9.4g%%) TIME\t %3dh %02d:%02.0f / %3dh %02d:%05.2f (%6.2fs n: %4d)",
                 objval, bobjval, gap,
                 wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs, time_start, nodes_1st);
        else
            fprintf (DDSIP_bb->moreoutfile,
                 "    exp. val. prob:  Best=%-20.14g\tBound=%-20.14g (%9.4g%%) %-4d\t %3dh %02d:%02.0f / %3dh %02d:%05.2f (%6.2fs n: %4d)",
                 objval, bobjval, gap, mipstatus,
                 wall_hrs,wall_mins,wall_secs,cpu_hrs,cpu_mins,cpu_secs, time_start, nodes_1st);
    }
    // Returns sometimes rubbish, don't know why..
    if (!DDSIP_bb->adv_sol)
        DDSIP_bb->adv_sol = (double *) DDSIP_Alloc (sizeof (double), DDSIP_bb->firstvar, "DDSIP_bb->adv_sol(sipread)");
    for (j = 0; j < DDSIP_bb->firstvar; j++)
    {
        // Numerical errors ?
        if (DDSIP_Equal (mipx[DDSIP_bb->firstindex[j]], 0.0))
            mipx[DDSIP_bb->firstindex[j]] = 0.0;
        DDSIP_bb->adv_sol[j] = mipx[DDSIP_bb->firstindex[j]];
    }

TERMINATE:

    DDSIP_Free ((void **) &(mipx));
    return status;
}
Exemplo n.º 5
0
void
DDSIP_DetEqu ()
{
    CPXLPptr det_equ;

    int status, scen, i, j, k, nzcnt_row, ranged = 0;
    char probname[] = "sipout/det_equ.lp.gz";
    double *scaled_obj_coef = NULL;
    char *sense = NULL, *sense_sorted = NULL;
    char **scen_spec_rowname = NULL;
    char **scen_spec_colname = NULL;
    char **rowname = NULL, *rownamestore = NULL;
    char **colname = NULL, *colnamestore = NULL;
    int rowstorespace, rowsurplus;
    int colstorespace, colsurplus;
    char *string1 = NULL, *string2 = NULL;
    double *lb = NULL, *lb_sorted = NULL;
    double *ub = NULL, *ub_sorted = NULL;
    double *rng = NULL, *rng_sorted = NULL;
    char *vartype = NULL, *vartype_sorted = NULL;
    int *colindex_sorted = NULL, *colindex_revers = NULL;
    double *value = NULL;
    double *det_equ_rhs = NULL;
    double *base_rhs = NULL;
    int nzcnt=0, *rmatbeg=NULL, *rmatind=NULL, *rmatbeg_stage=NULL, *rmatind_stage=NULL, *rowindex=NULL;
    double *rmatval=NULL, *rmatval_stage=NULL;
    double time_start, time_end;
    time_start = DDSIP_GetCpuTime ();
    k = abs(DDSIP_param->riskmod);
    if (k > 2 && k != 4)
    {
        fprintf (stderr,
             "\nNot building deterministic equivalent, not available for risk model %d\n",DDSIP_param->riskmod);
        fprintf (DDSIP_outfile,
             "\nNot building deterministic equivalent, not available for risk model %d\n",DDSIP_param->riskmod);
        return;
    }
    if (DDSIP_data->seccon)
        det_equ_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_Imax(DDSIP_Imax(DDSIP_data->seccon, DDSIP_param->scenarios), DDSIP_data->firstcon),"det_equ_rhs(DetEqu)");
    else
    {
        fprintf (stderr,"XXX ERROR: no second stage contraints, got DDSIP_data->seccon=%d.\n",DDSIP_data->seccon);
        return;
    }

    fprintf (stderr,
             "\nBuilding deterministic equivalent.\nWorks only for expectation-based models.\n");

    colstorespace = DDSIP_data->novar * 255;
    rowstorespace = DDSIP_data->nocon * 255;
    if (!(sense = (char *) DDSIP_Alloc (sizeof (char), DDSIP_data->nocon, "sense(DetEqu)")) ||
        !(sense_sorted = (char *) DDSIP_Alloc (sizeof (char), DDSIP_Imax(DDSIP_param->scenarios, DDSIP_Imax(DDSIP_data->firstcon,DDSIP_data->seccon)), "sense_sorted(DetEqu)")) ||
        !(base_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_data->nocon,"base_rhs(DetEqu)")) ||
        !(scaled_obj_coef = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar, DDSIP_data->secvar), "base_rhs(DetEqu)")) ||
        !(colname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_data->novar,"base_rhs(DetEqu)")) ||
        !(scen_spec_colname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "scen_spec_colname(DetEqu)")) ||
        !(colnamestore = (char *) DDSIP_Alloc (sizeof (char), colstorespace, "colnamestore(DetEqu)")) ||
        !(rowname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_data->nocon, "rowname(DetrEqu)")) ||
        !(scen_spec_rowname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_Imax(DDSIP_param->scenarios, DDSIP_Imax(DDSIP_data->firstcon,DDSIP_data->seccon)), "scen_spec_rowname(DetEqu)")) ||
        !(rownamestore = (char *) DDSIP_Alloc (sizeof (char), rowstorespace, "rownamestore(DetEqu)")) ||
        !(lb = (double *) DDSIP_Alloc (sizeof (double), DDSIP_data->novar, "lb(DetEqu)")) ||
        !(lb_sorted = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "lb_sorted(DetEqu)")) ||
        !(ub = (double *) DDSIP_Alloc (sizeof (double), DDSIP_data->novar, "ub(DetEqu)")) ||
        !(ub_sorted = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "ub_sorted(DetEqu)")) ||
        !(vartype = (char *) DDSIP_Alloc (sizeof (char), DDSIP_data->novar, "vartype(DetEqu)")) ||
        !(vartype_sorted = (char *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "vartype_sorted(DetEqu)")) ||
        !(colindex_sorted = (int *) DDSIP_Alloc (sizeof (int), DDSIP_data->novar, "colindex_sorted(DetEqu)")) ||
        !(rowindex = (int *) DDSIP_Alloc (sizeof (int), DDSIP_Imax(DDSIP_data->firstcon, DDSIP_data->seccon), "rowindex(DetEqu)")))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }

    // get problem data
    /*____________________________________________________________________________________*/
    if((status = CPXgetcolname (DDSIP_env, DDSIP_lp, colname, colnamestore,
                            colstorespace, &colsurplus, 0, DDSIP_data->novar - 1)) ||
       (status = CPXgetrowname (DDSIP_env, DDSIP_lp, rowname, rownamestore,
                            rowstorespace, &rowsurplus, 0, DDSIP_data->nocon - 1)) ||
       (status = CPXgetsense (DDSIP_env, DDSIP_lp, sense, 0, DDSIP_data->nocon - 1)) ||
       (status = CPXgetrhs (DDSIP_env, DDSIP_lp, base_rhs, 0, DDSIP_data->nocon - 1)) ||
       (status = CPXgetlb (DDSIP_env, DDSIP_lp, lb, 0, DDSIP_data->novar - 1)) ||
       (status = CPXgetub (DDSIP_env, DDSIP_lp, ub, 0, DDSIP_data->novar - 1)) ||
       (status = CPXgetctype (DDSIP_env, DDSIP_lp, vartype, 0, DDSIP_data->novar - 1)))
    {
        fprintf (stderr, "Coud not get problem data, returned %d\n", status);
        goto FREE;
    }
    // check whether there are ranged rows
    for (j=0; j<DDSIP_data->nocon; j++)
    {
        if (sense[j] == 'R')
        {
            ranged = 1;
	    break;
        }
    } 
    if (ranged)
    {
        if (!(rng = (double *) DDSIP_Alloc (sizeof (double), DDSIP_data->nocon, "rng(DetEqu)")) ||
            !(rng_sorted = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstcon,DDSIP_data->seccon), "rng_sorted(DetEqu)")))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        if ((status = CPXgetrngval (DDSIP_env, DDSIP_lp, rng, 0, DDSIP_data->nocon-1)))
        {
            fprintf (stderr, "Coud not get problem ranges, returned %d\n", status);
            goto FREE;
        }
    }
    /*____________________________________________________________________________________*/

    // create empty problem
    det_equ = CPXcreateprob (DDSIP_env, &status, probname);
    if (status)
    {
        fprintf (stderr, "CPXcreateprob returned %d\n", status);
        goto FREE;
    }
    // add (original) first-stage variables
    for (j = 0; j < DDSIP_data->firstvar; j++)
    {
        vartype_sorted[j]   = vartype[DDSIP_bb->firstindex[j]];
        lb_sorted[j]        = lb[DDSIP_bb->firstindex[j]];
        ub_sorted[j]        = ub[DDSIP_bb->firstindex[j]];
        if (DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
            scaled_obj_coef[j]  = DDSIP_data->obj_coef[DDSIP_bb->firstindex[j]];
        scen_spec_colname[j]= colname[DDSIP_bb->firstindex[j]];
    }
    if ((status = CPXnewcols (DDSIP_env, det_equ, DDSIP_data->firstvar, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
    {
        fprintf (stderr, "CPXnewcols returned %d for first-stage variables\n", status);
        goto FREE;
    }
    // add (original) second-stage variables for all scenarios
    for (j = 0; j < DDSIP_data->secvar; j++)
    {
        vartype_sorted[j] = vartype[DDSIP_bb->secondindex[j]];
        lb_sorted[j]      = lb[DDSIP_bb->secondindex[j]];
        ub_sorted[j]      = ub[DDSIP_bb->secondindex[j]];
    }
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        for (j = 0; j < DDSIP_data->secvar; j++)
        {
            if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
            {
                fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                goto FREE;
            }
            // append scenario index to colname
            string1 = colname[DDSIP_bb->secondindex[j]];
            sprintf (string2, "%sSC%.3d", string1, scen+1);
            scen_spec_colname[j] = string2;
            if (DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
                scaled_obj_coef[j] = DDSIP_data->prob[scen] * DDSIP_data->obj_coef[DDSIP_bb->secondindex[j]];
        }
        if ((status = CPXnewcols (DDSIP_env, det_equ, DDSIP_data->secvar, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
        {
            fprintf (stderr, "CPXnewcols returned %d for second-stage variables of scenario %d\n", status, scen+1);
            goto FREE;
        }
        for (j = 0; j < DDSIP_data->secvar; j++)
            DDSIP_Free ((void **) &(scen_spec_colname[j]));
    }
    // add second-stage variable for objective value of the scenarios
    if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }
    scen_spec_colname[0] = string2;
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        vartype_sorted[0] = 'C';
        lb_sorted[0]      = -DDSIP_infty;
        ub_sorted[0]      =  DDSIP_infty;
        sprintf (string2, "DDSIPobj_SC%.3d", scen+1);
        if (!DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
            scaled_obj_coef[0] = DDSIP_data->prob[scen];
        else
            scaled_obj_coef[0] = 0.;
        if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
        {
            fprintf (stderr, "CPXnewcols returned %d for second-stage variable  DDSIPobj_SC%.3d\n", status, scen+1);
            goto FREE;
        }
    }
    // add the additional variables needed for risk models ///////////////////////////////////////
    if (DDSIP_param->riskmod)
    {
        switch (abs(DDSIP_param->riskmod))
        {
          case 1:  // Expected excess
             // one continuous second-stage variable for each scenario
             for (scen = 0; scen < DDSIP_param->scenarios; scen++)
             {
                vartype_sorted[0] = 'C';
                lb_sorted[0]      = 0.;
                ub_sorted[0]      = DDSIP_infty;
                sprintf (string2, "DDSIP_expexc_SC%.3d", scen+1);
                if (DDSIP_param->riskmod > 0)
                    scaled_obj_coef[0] = DDSIP_param->riskweight*DDSIP_data->prob[scen];
                else if (DDSIP_param->riskmod < 0)
                    scaled_obj_coef[0] = DDSIP_data->prob[scen];
                else
                    scaled_obj_coef[0] = 0.;
                if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                                lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
                {
                    fprintf (stderr, "CPXnewcols returned %d for second-stage variable  %s\n", status, string2);
                    goto FREE;
                }
             }  
             break;
          case 2:  // Excess Probability
             // one binary second-stage variable for each scenario
             for (scen = 0; scen < DDSIP_param->scenarios; scen++)
             {
                vartype_sorted[0] = 'B';
                lb_sorted[0]      = 0.;
                ub_sorted[0]      = 1.;
                sprintf (string2, "DDSIP_excprob_SC%.3d", scen+1);
                if (DDSIP_param->riskmod > 0)
                    scaled_obj_coef[0] = DDSIP_param->riskweight*DDSIP_data->prob[scen];
                else if (DDSIP_param->riskmod < 0)
                    scaled_obj_coef[0] = DDSIP_data->prob[scen];
                else
                    scaled_obj_coef[0] = 0.;
                if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                                lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
                {
                    fprintf (stderr, "CPXnewcols returned %d for second-stage variable  %s\n", status, string2);
                    goto FREE;
                }
             }  
             break;
          case 4:  // Worst Case Costs
             // one continuous first-stage variable
                vartype_sorted[0] = 'C';
                lb_sorted[0]      = -DDSIP_infty;
                ub_sorted[0]      =  DDSIP_infty;
                if (DDSIP_param->prefix)
                {
                    if (!(strlen(DDSIP_param->prefix)))
                    {
                        fprintf (stderr," *** ERROR: The prefix for the first stage variables has to have a positive length.\n");
                        exit (1);
                    }
                    sprintf (string2, "%sDDSIP_n_aux01",DDSIP_param->prefix);
                }
                else
                {
                    if (!(strlen(DDSIP_param->postfix)))
                    {
                        fprintf (stderr," *** ERROR: The postfix for the first stage variables has to have a positive length.\n");
                        exit (1);
                    }
                    sprintf (string2, "DDSIP_worstc_%s",DDSIP_param->postfix);
                }
                if (DDSIP_param->riskmod > 0)
                    scaled_obj_coef[0] = DDSIP_param->riskweight;
                else if (DDSIP_param->riskmod < 0)
                    scaled_obj_coef[0] = 1.;
                else
                    scaled_obj_coef[0] = 0.;
                if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                                lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
                {
                    fprintf (stderr, "CPXnewcols returned %d for second-stage variable  %s\n", status, string2);
                    goto FREE;
                }
        }
    }
    DDSIP_Free ((void **) &(scen_spec_colname[0]));
        
    ///////enter stochastic cost coefficients in case of deteqType 1 //////////////////////////////
    if (DDSIP_param->stoccost && DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
    {
        for (j = 0; j < DDSIP_param->stoccost; j++)
        {
            scaled_obj_coef[j] = 0.0;
            if ((colindex_sorted[j] = DDSIP_bb->firstindex_reverse[DDSIP_data->costind[j]]))
                 colindex_sorted[j] = DDSIP_data->firstvar + DDSIP_bb->secondindex_reverse[DDSIP_data->costind[j]];
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    scaled_obj_coef[j] = DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
                else
                    scaled_obj_coef[j] += DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
            }
            status = CPXchgobj (DDSIP_env, det_equ, DDSIP_param->stoccost, colindex_sorted, scaled_obj_coef);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu: %s\n", errmsg);
            }
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    colindex_sorted[j] += DDSIP_data->secvar;
            }
        }
    }
    //
    // free arrays needeed only for columns
    DDSIP_Free ((void **) &(vartype));
    DDSIP_Free ((void **) &(colname));
    DDSIP_Free ((void **) &(colnamestore));
    DDSIP_Free ((void **) &(lb));
    DDSIP_Free ((void **) &(ub));
    DDSIP_Free ((void **) &(vartype_sorted));
    DDSIP_Free ((void **) &(lb_sorted));
    DDSIP_Free ((void **) &(ub_sorted));
    DDSIP_Free ((void **) &(scaled_obj_coef));
    //
    // get problem matrix coefficients
    // query the length needed for storage of coefficients
    CPXgetrows(DDSIP_env, DDSIP_lp, &nzcnt, rmatbeg, rmatind, rmatval, 0, &rowsurplus, 0, DDSIP_data->nocon-1);
    nzcnt = -rowsurplus;
    if (!(rmatbeg = (int *) DDSIP_Alloc (sizeof (int), DDSIP_data->nocon, "rmatbeg(DetEqu)")) ||
        !(rmatind = (int *) DDSIP_Alloc (sizeof (int), DDSIP_Imax(nzcnt, DDSIP_param->stocmat), "rmatind(DetEqu)")) ||
        !(rmatval = (double *) DDSIP_Alloc (sizeof (double), nzcnt, "rmatval(DetEqu)")))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }
    CPXgetrows(DDSIP_env, DDSIP_lp, &nzcnt, rmatbeg, rmatind, rmatval, nzcnt, &rowsurplus, 0, DDSIP_data->nocon-1);

    printf(" got %d elements of the matrix\n", nzcnt);

    k = DDSIP_Imax(nzcnt + DDSIP_param->stocmat, DDSIP_param->scenarios*(DDSIP_data->novar+1));
    if (!(rmatbeg_stage = (int *) DDSIP_Alloc (sizeof (int), DDSIP_Imax(DDSIP_param->scenarios, DDSIP_Imax(DDSIP_data->firstcon, DDSIP_data->seccon)), "rmatbeg_stage(DetEqu)")) ||
        !(rmatind_stage = (int *) DDSIP_Alloc (sizeof (int), k, "rmatind_stage(DetEqu)")) ||
        !(rmatval_stage = (double *) DDSIP_Alloc (sizeof (double), k, "rmatval_stage(DetEqu)")))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }

    // add first-stage constraints
    k = 0;
    for (j = 0; j < DDSIP_data->firstcon; j++)
    {
        sense_sorted[j] = sense[DDSIP_bb->firstrowind[j]];
        det_equ_rhs[j] = base_rhs[DDSIP_bb->firstrowind[j]];
        scen_spec_rowname[j] = rowname[DDSIP_bb->firstrowind[j]];
	rmatbeg_stage[j] = k;
	if (DDSIP_bb->firstrowind[j] == DDSIP_data->nocon -1)
            nzcnt_row = nzcnt - rmatbeg[DDSIP_data->nocon -1];
        else
            nzcnt_row = rmatbeg[DDSIP_bb->firstrowind[j]+1] - rmatbeg[DDSIP_bb->firstrowind[j]];
	for (i = 0; i < nzcnt_row; i++)
        {
            rmatind_stage[k + i] = DDSIP_bb->firstindex_reverse[rmatind[rmatbeg[DDSIP_bb->firstrowind[j]] + i]];
            rmatval_stage[k + i] = rmatval[rmatbeg[DDSIP_bb->firstrowind[j]] + i];
        }
	k += nzcnt_row;
    }
    if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_data->firstcon, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
    {
        fprintf (stderr, "CPXaddrows returned %d for first-stage constraints\n", status);
        goto FREE;
    }
    if (ranged)
    {
        for (j = 0; j < DDSIP_data->firstcon; j++)
        {
            rng_sorted[j] = rng[DDSIP_bb->firstrowind[j]];
            rowindex[j]   = j;
        }
        if((status = CPXchgrngval(DDSIP_env, det_equ, DDSIP_data->firstcon, rowindex, rng_sorted)))
        {
            fprintf (stderr, "CPXchgrngval returned %d for first-stage constraints\n", status);
            goto FREE;
        }
    }

    // add second-stage constraints
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        k = 0;
        for (j = 0; j < DDSIP_data->seccon; j++)
        {
            sense_sorted[j] = sense[DDSIP_bb->secondrowind[j]];
            det_equ_rhs[j] = base_rhs[DDSIP_bb->secondrowind[j]];
            if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
            {
                fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                goto FREE;
            }
            // append scenario index to colname
            string1 = rowname[DDSIP_bb->secondrowind[j]];
            sprintf (string2, "%sSC%.3d", string1, scen+1);
            scen_spec_rowname[j] = string2;
            rmatbeg_stage[j] = k;
            if (DDSIP_bb->secondrowind[j] == DDSIP_data->nocon -1)
                nzcnt_row = nzcnt - rmatbeg[DDSIP_data->nocon -1];
            else
            {
                nzcnt_row = rmatbeg[DDSIP_bb->secondrowind[j]+1] - rmatbeg[DDSIP_bb->secondrowind[j]];

            }
            for (i = 0; i < nzcnt_row; i++)
            {
                if (DDSIP_bb->firstindex_reverse[rmatind[rmatbeg[DDSIP_bb->secondrowind[j]] + i]] < 0)
                    rmatind_stage[k + i] = DDSIP_data->firstvar + scen*DDSIP_data->secvar + DDSIP_bb->secondindex_reverse[rmatind[rmatbeg[DDSIP_bb->secondrowind[j]] + i]];
                else
                    rmatind_stage[k + i] = DDSIP_bb->firstindex_reverse[rmatind[rmatbeg[DDSIP_bb->secondrowind[j]] + i]];
                rmatval_stage[k + i] = rmatval[rmatbeg[DDSIP_bb->secondrowind[j]] + i];
            }
            k += nzcnt_row;
        }
        ///////enter stochastic rhs entries//////////////////////////////////////////////////////
        for (j=0; j< DDSIP_param->stocrhs; j++)
        {
            det_equ_rhs[DDSIP_bb->secondrowind_reverse[DDSIP_data->rhsind[j]]] = DDSIP_data->rhs[scen * DDSIP_param->stocrhs + j];
        }

        if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_data->seccon, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
        {
            fprintf (stderr, "CPXaddrows returned %d for second-stage constraints scenario %d\n", status, scen+1);
            goto FREE;
        }
        for (j = 0; j < DDSIP_data->seccon; j++)
            DDSIP_Free ((void **) &(scen_spec_rowname[j]));
        if (ranged)
        {
            for (j = 0; j < DDSIP_data->seccon; j++)
            {
                rng_sorted[j] = rng[DDSIP_bb->secondrowind[j]];
                rowindex[j]   = DDSIP_data->firstcon + scen * DDSIP_data->seccon + j;
            }
            if ((status = CPXchgrngval(DDSIP_env, det_equ, DDSIP_data->seccon, rowindex, rng_sorted)))
            {
                fprintf (stderr, "CPXchgrngval returned %d for first-stage constraints\n", status);
                goto FREE;
            }
        }
    }
    ///////enter stochastic matrix entries//////////////////////////////////////////////////////
    if (DDSIP_param->stocmat)
    {

        if (!(value = (double *) calloc (DDSIP_param->stocmat, sizeof (double))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        for (j = 0; j < DDSIP_param->stocmat; j++)
        {
            if ((colindex_sorted[j] = DDSIP_bb->firstindex_reverse[DDSIP_data->matcol[j]]))
                 colindex_sorted[j] = DDSIP_data->firstvar + DDSIP_bb->secondindex_reverse[DDSIP_data->matcol[j]];
            rmatind[j] = DDSIP_data->firstcon + DDSIP_bb->secondrowind_reverse[DDSIP_data->matrow[j]];
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                value[j] = DDSIP_data->matval[scen * DDSIP_param->stocmat + j];
            }
            status = CPXchgcoeflist (DDSIP_env, det_equ, DDSIP_param->stocmat, rmatind, colindex_sorted, value);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu chgcoeflist returned %d: %s\n", status, errmsg);
            }
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                rmatind[j] += DDSIP_data->seccon;
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    colindex_sorted[j] += DDSIP_data->secvar;
            }
        }
        DDSIP_Free ((void **) &(value));
    }

    // add second-stage equations for the objective values of the scenarios
    k = 0;
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        sense_sorted[scen] = 'E';
        det_equ_rhs[scen] = 0.;
        if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        sprintf (string2, "DDSIP_o_SC%.3d", scen+1);
        scen_spec_rowname[scen] = string2;
        rmatbeg_stage[scen] = k;
        nzcnt_row = DDSIP_data->novar + 1;
        for (i = 0; i < DDSIP_data->novar; i++)
        {
            if (DDSIP_bb->firstindex_reverse[i] < 0)
            {
                rmatind_stage[k + i] = DDSIP_data->firstvar + scen*DDSIP_data->secvar + DDSIP_bb->secondindex_reverse[i];
            }
            else
            {
                rmatind_stage[k + i] = DDSIP_bb->firstindex_reverse[i];
            }
            rmatval_stage[k + i] = DDSIP_data->obj_coef[i];
        }
        rmatind_stage[k + DDSIP_data->novar] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen;
        rmatval_stage[k + DDSIP_data->novar] = -1.;
        k += nzcnt_row;
    }
    if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
    {
        fprintf (stderr, "CPXaddrows returned %d for second-stage objective constraints\n", status);
        goto FREE;
    }
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        DDSIP_Free ((void **) &(scen_spec_rowname[scen]));
    }
    ///////enter stochastic cost coefficients in the objective equations //////////////////////////////
    if (DDSIP_param->stoccost)
    {
        if (!(value = (double *) calloc (DDSIP_param->stoccost, sizeof (double))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if ((colindex_sorted[j] = DDSIP_bb->firstindex_reverse[DDSIP_data->costind[j]]) < 0)
                     colindex_sorted[j] = DDSIP_data->firstvar + scen * DDSIP_data->secvar +DDSIP_bb->secondindex_reverse[DDSIP_data->costind[j]];
                rmatind[j] = DDSIP_data->firstcon + DDSIP_param->scenarios*DDSIP_data->seccon + scen;
                value[j] = DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
            }
            status = CPXchgcoeflist (DDSIP_env, det_equ, DDSIP_param->stoccost, rmatind, colindex_sorted, value);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu chgcoeflist returned %d: %s\n", status, errmsg);
            }
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                rmatind[j] += DDSIP_data->seccon;
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    colindex_sorted[j] += DDSIP_data->secvar;
            }
        }
        DDSIP_Free ((void **) &(value));
    }
    // add second-stage equations for the risk models //////////////////////////////////
    switch (abs(DDSIP_param->riskmod))
    {
      case 1:  // Expected excess
         k = 0;
         for (scen = 0; scen < DDSIP_param->scenarios; scen++)
         {
             sense_sorted[scen] = 'L';
             det_equ_rhs[scen]  = DDSIP_param->risktarget;
             if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
             {
                 fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                 goto FREE;
             }
             sprintf (string2, "DDSIP_exp_excess_SC%.3d", scen+1);
             scen_spec_rowname[scen] = string2;
             rmatbeg_stage[scen] = k;
             nzcnt_row = 2;
             rmatind_stage[k]     = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen; 
             rmatval_stage[k]     = 1.;
             rmatind_stage[k + 1] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + DDSIP_param->scenarios + scen; 
             rmatval_stage[k + 1] = -1.;
             k += nzcnt_row;
         }
         if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
         {
             fprintf (stderr, "CPXaddrows returned %d for second-stage risk constraints\n", status);
             goto FREE;
         }
         break;
      case 2:  // Excess probability
         k = 0;
         for (scen = 0; scen < DDSIP_param->scenarios; scen++)
         {
             sense_sorted[scen] = 'L';
             det_equ_rhs[scen]  = DDSIP_param->risktarget;
             if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
             {
                 fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                 goto FREE;
             }
             sprintf (string2, "DDSIP_excess_prob_SC%.3d", scen+1);
             scen_spec_rowname[scen] = string2;
             rmatbeg_stage[scen] = k;
             nzcnt_row = 2;
             rmatind_stage[k]     = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen; 
             rmatval_stage[k]     = 1.;
             rmatind_stage[k + 1] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + DDSIP_param->scenarios + scen; 
             rmatval_stage[k + 1] = -DDSIP_param->riskM;
             k += nzcnt_row;
         }
         if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
         {
             fprintf (stderr, "CPXaddrows returned %d for second-stage risk constraints\n", status);
             goto FREE;
         }
         break;
      case 4:  // Worst case cost
         k = 0;
         for (scen = 0; scen < DDSIP_param->scenarios; scen++)
         {
             sense_sorted[scen] = 'L';
             det_equ_rhs[scen]  = 0.;
             if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
             {
                 fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                 goto FREE;
             }
             sprintf (string2, "DDSIP_worst_case_SC%.3d", scen+1);
             scen_spec_rowname[scen] = string2;
             rmatbeg_stage[scen] = k;
             nzcnt_row = 2;
             rmatind_stage[k]     = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen; 
             rmatval_stage[k]     = 1.;
             rmatind_stage[k + 1] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + DDSIP_param->scenarios; 
             rmatval_stage[k + 1] = -1.;
             k += nzcnt_row;
         }
         if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
         {
             fprintf (stderr, "CPXaddrows returned %d for second-stage risk constraints\n", status);
             goto FREE;
         }
         break;
    }
    for (j = 0; j < DDSIP_param->scenarios; j++)
        DDSIP_Free ((void **) &(scen_spec_rowname[j]));

    time_end = DDSIP_GetCpuTime ();
    fprintf (DDSIP_outfile, " %6.2f sec  for building deterministic equivalent\n",time_end-time_start);

    status = CPXwriteprob (DDSIP_env, det_equ, probname, NULL);
    if (status)
    {
        fprintf (DDSIP_outfile, " *** Deterministic equivalent not written successfully, status = %d\n", status);
        printf  (" *** Deterministic equivalent not written successfully, status = %d\n", status);
    }
    else
    {
        fprintf (DDSIP_outfile, " *** Deterministic equivalent %s written successfully\n", probname);
        printf  (" *** Deterministic equivalent %s written successfully\n", probname);
    }
    status = CPXfreeprob (DDSIP_env, &det_equ);
    time_start = DDSIP_GetCpuTime ();
    fprintf (DDSIP_outfile, " %6.2f sec  for writing deterministic equivalent\n",time_start-time_end);

FREE:
    DDSIP_Free ((void **) &(sense));
    DDSIP_Free ((void **) &(sense_sorted));
    DDSIP_Free ((void **) &(vartype));
    DDSIP_Free ((void **) &(rowname));
    DDSIP_Free ((void **) &(rownamestore));
    DDSIP_Free ((void **) &(colname));
    DDSIP_Free ((void **) &(colnamestore));
    DDSIP_Free ((void **) &(det_equ_rhs));
    DDSIP_Free ((void **) &(base_rhs));
    DDSIP_Free ((void **) &(lb));
    DDSIP_Free ((void **) &(ub));
    DDSIP_Free ((void **) &(vartype_sorted));
    DDSIP_Free ((void **) &(lb_sorted));
    DDSIP_Free ((void **) &(ub_sorted));
    DDSIP_Free ((void **) &(scaled_obj_coef));
    DDSIP_Free ((void **) &(colindex_sorted));
    DDSIP_Free ((void **) &(colindex_revers));
    DDSIP_Free ((void **) &(scen_spec_rowname));
    DDSIP_Free ((void **) &(scen_spec_colname));
    DDSIP_Free ((void **) &(rmatbeg));
    DDSIP_Free ((void **) &(rmatind));
    DDSIP_Free ((void **) &(rmatval));
    DDSIP_Free ((void **) &(rmatbeg_stage));
    DDSIP_Free ((void **) &(rmatind_stage));
    DDSIP_Free ((void **) &(rmatval_stage));
    DDSIP_Free ((void **) &(rowindex));
    if (ranged)
    {
        DDSIP_Free ((void **) &(rng));
        DDSIP_Free ((void **) &(rng_sorted));
    }
    return;
}