2

Я решил использовать lp, используя библиотеку CPLEX для вызова (в VS2010). Lp является следующим:Как изменить lp на mip при использовании библиотеки CPLEX, вызываемой для вызова

Maximize 
    obj: x1 + 2 x2 + 3 x3 
    Subject To 
    c1: - x1 + x2 + x3 <= 20 
    c2: x1 - 3 x2 + x3 <= 30 
    Bounds 
    0 <= x1 <= 40 
    End 

Код приведен ниже. Теперь я хотел бы сделать это MIP (дополнительные ограничения целостности для x). Я попытался сделать это, изменив status = CPXlpopt (env, lp); на status = CPXmipopt (env, lp);. Это не работает, и я получаю сообщение об ошибке 3003: not a mixed-integer problem. Кто-нибудь знает, чего я здесь не хватает?

int main() 
{ 
    /* Declare and allocate space for the variables and arrays where we 
     will store the optimization results including the status, objective 
     value, variable values, dual values, row slacks and variable 
     reduced costs. */ 

    int  solstat; 
    double objval; 
    double *x = NULL; 
    double *pi = NULL; 
    double *slack = NULL; 
    double *dj = NULL; 


    CPXENVptr  env = NULL; 
    CPXLPptr  lp = NULL; 
    int   status = 0; 
    int   i, j; 
    int   cur_numrows, cur_numcols; 

    /* Initialize the CPLEX environment */ 

    env = CPXopenCPLEX (&status); 

    /* Turn on output to the screen */ 
    status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON); 

    /* Turn on data checking */ 
    status = CPXsetintparam (env, CPX_PARAM_DATACHECK, CPX_ON); 

    /* Create the problem. */ 
    lp = CPXcreateprob (env, &status, "lpex1"); 

    /* Now populate the problem with the data. */ 
    #define NUMROWS 2 
    #define NUMCOLS 3 
    #define NUMNZ  6 

    /* To populate by column, we first create the rows, and then add the columns. */ 

    int  status = 0; 
    double obj[NUMCOLS]; 
    double lb[NUMCOLS]; 
    double ub[NUMCOLS]; 
    char  *colname[NUMCOLS]; 
    int  matbeg[NUMCOLS]; 
    int  matind[NUMNZ]; 
    double matval[NUMNZ]; 
    double rhs[NUMROWS]; 
    char  sense[NUMROWS]; 
    char  *rowname[NUMROWS]; 

    CPXchgobjsen (env, lp, CPX_MAX); /* Problem is maximization */ 

    /* Now create the new rows. First, populate the arrays. */ 

    rowname[0] = "c1"; 
    sense[0] = 'L'; 
    rhs[0]  = 20.0; 

    rowname[1] = "c2"; 
    sense[1] = 'L'; 
    rhs[1]  = 30.0; 

    status = CPXnewrows (env, lp, NUMROWS, rhs, sense, NULL, rowname); 
    if (status) goto TERMINATE; 

    /* Now add the new columns. First, populate the arrays. */ 

     obj[0] = 1.0;  obj[1] = 2.0;   obj[2] = 3.0; 

    matbeg[0] = 0;  matbeg[1] = 2;   matbeg[2] = 4; 

    matind[0] = 0;  matind[2] = 0;   matind[4] = 0; 
    matval[0] = -1.0; matval[2] = 1.0;  matval[4] = 1.0; 

    matind[1] = 1;  matind[3] = 1;   matind[5] = 1; 
    matval[1] = 1.0; matval[3] = -3.0;  matval[5] = 1.0; 

    lb[0] = 0.0;  lb[1] = 0.0;   lb[2] = 0.0; 
    ub[0] = 40.0;  ub[1] = CPX_INFBOUND; ub[2] = CPX_INFBOUND; 

    colname[0] = "x1"; colname[1] = "x2";  colname[2] = "x3"; 

    status = CPXaddcols (env, lp, NUMCOLS, NUMNZ, obj, matbeg, matind, matval, lb, ub, colname); 


    /* Optimize the problem and obtain solution. */ 

    status = CPXlpopt (env, lp); 

    cur_numrows = CPXgetnumrows (env, lp); 
    cur_numcols = CPXgetnumcols (env, lp); 

    x = (double *) malloc (cur_numcols * sizeof(double)); 
    slack = (double *) malloc (cur_numrows * sizeof(double)); 
    dj = (double *) malloc (cur_numcols * sizeof(double)); 
    pi = (double *) malloc (cur_numrows * sizeof(double)); 

    status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj); 

    /* Write the output to the screen. */ 

    printf ("\nSolution status = %d\n", solstat); 
    printf ("Solution value = %f\n\n", objval); 

    for (i = 0; i < cur_numrows; i++) { 
     printf ("Row %d: Slack = %10f Pi = %10f\n", i, slack[i], pi[i]); 
    } 

    for (j = 0; j < cur_numcols; j++) { 
     printf ("Column %d: Value = %10f Reduced cost = %10f\n", 
       j, x[j], dj[j]); 
    } 

    /* Finally, write a copy of the problem to a file. */ 

    status = CPXwriteprob (env, lp, "lpex1.lp", NULL); 

    /* Free up the solution */ 

    ... (additional code to free up the solution)... 

    return(status) 
} 

ответ

1

В вашем коде вы не объявляете какие-либо переменные решения целыми. Вот почему cplex жалуется, когда вы пытаетесь решить свою проблему с помощью MIP-решателя. Вы выполняете моделирование по столбцам, а CPXaddcols не имеет параметра для типа переменной, но вы можете использовать CPXcopyctype или CPXchgctype. Поскольку вы ограничиваете свои переменные решения большими, чем 1, вы ищете тип переменной «I» вместо «B» для двоичного кода.

char  *ctype; 
    ctype = (char *) malloc(cur_numcols * sizeof(char); 

    for (j = 0; j < cur_numcols; j++) { 
     ctype[j] = 'I'; 
    } 

    status = CPXcopyctype(env, lp, ctype); 
    /* verify status */ 

    status = CPXmipopt (env, lp); 
    /* verify status */ 

 Смежные вопросы

  • Нет связанных вопросов^_^