2

CPLEX 호출 가능 라이브러리를 사용하여 lp를 해결했습니다 (VS2010에서). lp는 다음과 같습니다.CPLEX 호출 라이브러리를 사용할 때 lp를 mip으로 변경하는 방법

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보다 크므로 2 진수의 경우 'B'대신 'I'변수 유형을 찾고 있습니다.

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 */