Ejemplo n.º 1
0
int con_branching()
{
    CONSTRAINT *row0,*row1;
    double     old_lowerb = lowerb;


#ifdef STAMP
    std::cout << "  >>>>>>>>>>>>> constraint branching " << std::endl;
    if(branchs==0) write_sol(fsolution);
#endif

    if( upperb < ceil(lowerb-ZERO)+ZERO ) return(1);
////    constraint_branching(nbetter,better,&row0,&row1);
    constraint_branching(nsupport,support,&row0,&row1);
    if( upperb < ceil(lowerb-ZERO)+ZERO ) return(1);
    if(row0==NULL && row1==NULL)return(-1);
    if(row0==NULL || row1==NULL)return(0);


/***
 to do not use the branch-cuts
***/
////    return(-1);



    branchs++;
#ifdef STAMP
    std::cout << "branching " << branchs << " on constraint" << std::endl;
#endif


/* making the left child */

    row0->stat = LP_BA;
    add_rows(1,&row0);
    lowerb = solve_lp(0);
    get_solution();
    get_base();
    write_prob();
    deletelastrow();
    row0->stat = FIX_LB;

/* making the left child */


    row1->stat = LP_BA;
    add_rows(1,&row1);
    lowerb = solve_lp(0);
    get_solution();
    get_base();
    write_prob();
    deletelastrow();
    row1->stat = FIX_LB;

    lowerb = old_lowerb;
    return(1);
}
Ejemplo n.º 2
0
void SDP::debug_prob(char* path)
{
    struct blockmatrix* Cptr = (struct blockmatrix*)C_;
    struct blockmatrix& C = *Cptr;
    struct constraintmatrix* constraints = (struct constraintmatrix*)constraints_;
    write_prob(path,7,2,C,b_,constraints);
}
Ejemplo n.º 3
0
int var_branching()
{
    VARIABLE *col;
    double   old_lowerb = lowerb;

#ifdef STAMP
    std::cout << "  >>>>>>>>>>>>> var branching " << std::endl;
    if(branchs==0) write_sol(fsolution);
#endif

    if( upperb-ZERO < ceil(lowerb-ZERO) )
        return(1);
    col = variable_branching(BETTERLP);
    if( upperb-ZERO < ceil(lowerb-ZERO) )
        return(1);
    if(col==NULL)
        return(0);
#ifdef STAMP
    std::cout << branchs << " on variable " << col->index << "=" << col->val << std::endl;
#endif
    branchs++;
/* making the left child */

    if( ceil( solve_child_col( col , (double)0 , 1)-ZERO) < upperb-ZERO ) {
        col->stat = FIX_LB;
        write_prob();
    }

/* making the left child */

    if( ceil( solve_child_col( col , (double)1 , 1)-ZERO) < upperb-ZERO ) {
        col->stat = FIX_UB;
        write_prob();
    }
    lowerb = old_lowerb;
    return(1);
}
Ejemplo n.º 4
0
int load_branch_tree()
{
    FILE     *pfile;

    mar = 1;
    mac = ncols;
    tree = NULL;

    pfile = fopen(fbranch,"w");
    if(pfile==NULL){          
          std::cout << "ERROR: not possible to write on " << fbranch << std::endl;
          CSPexit(EXIT_ERROR); //exit(1);
    }
    fclose(pfile);

    write_prob();
    return(0);
}
//Main Function
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
    //Input Args
    double *f, *blin = NULL, *lb = NULL, *ub = NULL, *y0 = NULL;
    
    //Return Args
    double *x, *pval, *dval, *exitflag, *iter, *pinf, *dinf, *realgap, *xzgap;
    
    //Options (most get defaults written in)
    int maxiter = 1500;  
    
    //Internal Vars
    size_t ndec = 0, nlincon = 0, lincon_nz = 0, total_dim = 0, ncones = 0; 
    size_t i, j;
    const char *onames[2] = {"pval","dval"};
    const char *fnames[5] = {"iter","pinf","dinf","realgap","xzgap"};    
    double evaltime;
    int status = -1, nb = 0, linoffset = 0, indlb = 1, indub = 1, nLB = 0, nUB = 0;
    mwIndex *jc;
    
    //CSDP Problem Data
    struct blockmatrix C;
    double *b, *y, *xx, objconstant = 0.0;
    struct constraintmatrix *constraints;
    struct blockmatrix X, Z;
    struct sparseblock *blockptr;
    struct paramstruc params;

    //Version Return
    if(nrhs < 1) {
        if(nlhs < 1)
            printSolverInfo();
        else
            plhs[0] = mxCreateString(CSDP_VERSION);
        return;
    }        
    
    //Check Inputs
    checkInputs(prhs,nrhs); 
    
    //Get pointers to Input variables
	f = mxGetPr(pF); ndec = mxGetNumberOfElements(pF);
    if(!mxIsEmpty(pA)) {
        blin = mxGetPr(pB);
        nlincon = mxGetM(pA);
        jc = mxGetJc(pA);
        lincon_nz = jc[ndec];        
    }
    if(nrhs > eLB && !mxIsEmpty(pLB)) {
        lb = mxGetPr(pLB); 
        //Ensure we have at least one finite bound
        for(i=0,j=0;i<ndec;i++)
            if(mxIsInf(lb[i]))
                j++;
        if(j==ndec)
            lb = NULL;
    }
    if(nrhs > eUB && !mxIsEmpty(pUB)) {
        ub = mxGetPr(pUB);
        //Ensure we have at least one finite bound
        for(i=0,j=0;i<ndec;i++)
            if(mxIsInf(ub[i]))
                j++;
        if(j==ndec)
            ub = NULL;
    }
    if(nrhs > eSDP && !mxIsEmpty(pSDP)) {
        if(mxIsCell(pSDP))
            ncones = mxGetNumberOfElements(pSDP);
        else
            ncones = 1;
    }
    if(nrhs > eY0 && !mxIsEmpty(pY0))
        y0 = mxGetPr(pY0);
    
    //Create Outputs
    plhs[0] = mxCreateDoubleMatrix(ndec,1, mxREAL);
    plhs[1] = mxCreateStructMatrix(1,1,2,onames);
    mxSetField(plhs[1],0,onames[0],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[1],0,onames[1],mxCreateDoubleMatrix(1,1, mxREAL));
    plhs[2] = mxCreateDoubleMatrix(1,1, mxREAL);   
    x = mxGetPr(plhs[0]); 
    pval = mxGetPr(mxGetField(plhs[1],0,onames[0]));
    dval = mxGetPr(mxGetField(plhs[1],0,onames[1]));
    exitflag = mxGetPr(plhs[2]);    
    //Info Output    
    plhs[3] = mxCreateStructMatrix(1,1,5,fnames);
    mxSetField(plhs[3],0,fnames[0],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[1],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[2],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[3],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[4],mxCreateDoubleMatrix(1,1, mxREAL));
    iter = mxGetPr(mxGetField(plhs[3],0,fnames[0]));
    pinf = mxGetPr(mxGetField(plhs[3],0,fnames[1]));
    dinf = mxGetPr(mxGetField(plhs[3],0,fnames[2]));
    realgap = mxGetPr(mxGetField(plhs[3],0,fnames[3]));
    xzgap = mxGetPr(mxGetField(plhs[3],0,fnames[4]));
    
    //Set Defaults
    citer = 0;
    maxtime = 1000;
    printLevel = 0;
    
    //Allocate Initial Storage for the Problem
    b = (double*)malloc((ndec+1)*sizeof(double));       //objective vector
    //C matrices [LB UB LIN SD]
    nb = (int)ncones+(int)(nlincon>0)+(int)(lb!=NULL)+(int)(ub!=NULL);
    #ifdef DEBUG
        mexPrintf("Number of blocks (including bounds, linear and sdcones): %d\n",nb);
    #endif            
    C.nblocks   = nb;
    C.blocks    = (struct blockrec*)malloc((nb+1)*sizeof(struct blockrec)); //+1 due to fortran index
    if(C.blocks == NULL)
        mexErrMsgTxt("Error allocating memory for C matrices");
    //Constraints (i.e. 1 per decision variable)
    constraints = (struct constraintmatrix*)malloc((ndec+1)*sizeof(struct constraintmatrix)); //+1 due to fortran index
    if(constraints == NULL) {
        free(C.blocks);
        mexErrMsgTxt("Error allocating memory for A matrices");
    }
    for(i=1;i<=ndec;i++)
        constraints[i].blocks=NULL; //initially set as NULL
    
    //Copy in and negate objective vector
    for(i=0;i<ndec;i++)
        b[i+1] = -f[i];
    
    //Create Bounds if Present
    if(lb || ub)
        linoffset += addBounds(C,lb,ub,ndec,&nLB,&nUB);
    
    //Create Linear Cone (diagonal) if present
    if(nlincon) {
        //Initialize C
        C.blocks[linoffset+1].blockcategory = DIAG;
        C.blocks[linoffset+1].blocksize = (int)nlincon;
        C.blocks[linoffset+1].data.vec = (double*)malloc((nlincon+1)*sizeof(double));
        if(C.blocks[linoffset+1].data.vec == NULL)
            mexErrMsgTxt("Error allocating memory for LP C diagonal");
        #ifdef DEBUG
            mexPrintf("LP C[%d] Vector size: %d\n",linoffset+1,nlincon);
        #endif        
        //Copy Elements
        for(i=0;i<nlincon;i++) {
            C.blocks[linoffset+1].data.vec[i+1] = -blin[i];
            #ifdef DEBUG
                mexPrintf("  C vec[%d] = %f\n",i+1,-blin[i]);
            #endif
        }
        linoffset++;
    }
    
    #ifdef DEBUG
        mexPrintf("\nBlock offset after bounds + linear con: %d\n\n",linoffset);
    #endif
    
    //Setup Semidefinite C matrices (note all full matrices, dense, in order from 1)
    for(i=1;i<=ncones;i++) {
        //Single Cone
        if(ncones == 1 && !mxIsCell(pSDP))
            total_dim += addCMatrix(C,pSDP,(int)i+linoffset);
        //Multiple Cones
        else 
            total_dim += addCMatrix(C,mxGetCell(pSDP,i-1),(int)i+linoffset);     
    }    
    //Add Linear Dims
    total_dim += nLB+nUB+nlincon;
    
    #ifdef DEBUG
        mexPrintf("\nTotal dimension of all cones: %d\n\n",total_dim);
    #endif
    
    //Setup Each Constraint (for each decision var) (in order from 1)
    indlb = 1; indub = 1;
    for(i=1;i<=ndec;i++) { 
        //For each Semidefinte A matrix (sparse triu, in reverse order, i.e. [SD, LP, UB, LB])
        for(j=ncones;j>0;j--) {
            //Create an A matrix            
            blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock));
            if(blockptr==NULL) {
                sprintf(msgbuf,"Error allocating memory for Semidefinite A[%d,%d]",i,j+linoffset);
                mexErrMsgTxt(msgbuf);
            }            
            //Single Cone
            if(ncones == 1 && !mxIsCell(pSDP)) 
                addAMatrix(blockptr,pSDP,(int)i,(int)j+linoffset); 
            //Multiple Cones
            else 
                addAMatrix(blockptr,mxGetCell(pSDP,j-1),(int)i,(int)j+linoffset);
            
            //Insert A matrix into constraint list
            blockptr->next=constraints[i].blocks;
            constraints[i].blocks=blockptr;
        }  
        
        //Linear Inequality Constraints
        if(nlincon) {
            //Create an A matrix
             blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock));
            if(blockptr==NULL) {
                sprintf(msgbuf,"Error allocating memory for LP A[%d]",i);
                mexErrMsgTxt(msgbuf);
            }
            //Insert LP A entries
            j = 1 + (int)(nUB > 0) + (int)(nLB > 0);
            insertLPVector(blockptr, pA, (int)i, (int)j);             
            //Insert A matrix into constraint list
            blockptr->next=constraints[i].blocks;
            constraints[i].blocks=blockptr;
        }
        
        //Upper Bounds
        if(nUB) {
            //Create an A matrix
            blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock));
            if(blockptr==NULL) {
                sprintf(msgbuf,"Error allocating memory for UB A[%d]",i);
                mexErrMsgTxt(msgbuf);
            }            
            //Insert Bound A matrix entries
            if(nLB > 0)
                indub += insertBound(blockptr,ub,nUB,(int)i,2,indub,1.0); //block 2 ([LB,UB,..] 1.0 for ub)
            else
                indub += insertBound(blockptr,ub,nUB,(int)i,1,indub,1.0); //block 1 (first block, 1.0 for ub)
            //Insert A matrix into constraint list
            blockptr->next=constraints[i].blocks;
            constraints[i].blocks=blockptr;
        }
        
        //Lower Bounds
        if(nLB) {
            //Create an A matrix
            blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock));
            if(blockptr==NULL) {
                sprintf(msgbuf,"Error allocating memory for LB A[%d]",i);
                mexErrMsgTxt(msgbuf);
            }            
            //Insert Bound A matrix entries
            indlb += insertBound(blockptr,lb,nLB,(int)i,1,indlb,-1.0); //block 1 (always first block, -1.0 for lb)
            //Insert A matrix into constraint list
            blockptr->next=constraints[i].blocks;
            constraints[i].blocks=blockptr;
        }
    }

//     //Set y0
//     if (y0)
//         for (i=0;i<ndec;i++) {
//             DSDP_ERR( DSDPSetY0(dsdp,(int)i+1,y0[i]), "Error setting Y0");            
//         }
//     
    
    //Get CSDP Default Options
    initparams(&params,&printLevel); 
    //Set OPTI default printLevel (none)
    printLevel = 0;
    
    //Get User Options (overwrites defaults above)
    if(nrhs > eOPTS && !mxIsEmpty(pOPTS)) {
        //OPTI Options
        GetIntegerOption(pOPTS,"maxiter",&params.maxiter);
        GetDoubleOption(pOPTS,"maxtime",&maxtime);
        GetIntegerOption(pOPTS,"display",&printLevel);
        GetDoubleOption(pOPTS,"objconstant",&objconstant);
        //CSDP Options
        GetDoubleOption(pOPTS,"axtol",&params.axtol);
        GetDoubleOption(pOPTS,"atytol",&params.atytol);
        GetDoubleOption(pOPTS,"objtol",&params.objtol);
        GetDoubleOption(pOPTS,"pinftol",&params.pinftol);
        GetDoubleOption(pOPTS,"dinftol",&params.dinftol);
        GetDoubleOption(pOPTS,"minstepfrac",&params.minstepfrac);
        GetDoubleOption(pOPTS,"maxstepfrac",&params.maxstepfrac);
        GetDoubleOption(pOPTS,"minstepp",&params.minstepp);
        GetDoubleOption(pOPTS,"minstepd",&params.minstepd);
        GetIntegerOption(pOPTS,"usexzgap",&params.usexzgap);
        GetIntegerOption(pOPTS,"tweakgap",&params.tweakgap); 
        GetIntegerOption(pOPTS,"affine",&params.affine);
        GetDoubleOption(pOPTS,"perturbobj",&params.perturbobj);
        //Optionally write problem to a SDPA sparse file
        if(mxGetField(pOPTS,0,"writeprob") && !mxIsEmpty(mxGetField(pOPTS,0,"writeprob")) && mxIsChar(mxGetField(pOPTS,0,"writeprob"))) {
            mxGetString(mxGetField(pOPTS,0,"writeprob"),msgbuf,1024);
            write_prob(msgbuf,(int)total_dim,(int)ndec,C,b,constraints);
        }
    }

    //Print Header
    if(printLevel) {
        mexPrintf("\n------------------------------------------------------------------\n");
        mexPrintf(" This is CSDP v%s\n",CSDP_VERSION); 
        mexPrintf(" Author: Brian Borchers\n MEX Interface J. Currie 2013\n\n");
        mexPrintf(" Problem Properties:\n");
        mexPrintf(" # Decision Variables:        %4d\n",ndec);   
        mexPrintf(" # Linear Inequalities:       %4d ",nlincon);
        if(nlincon)
            mexPrintf("[%d nz]\n",lincon_nz);
        else
            mexPrintf("\n");   
        mexPrintf(" # Semidefinite Cones:        %4d\n",ncones);

        mexPrintf("------------------------------------------------------------------\n");
    }
    
    //Start timer
    start = clock();
    //Find Initial Solution
    initsoln((int)total_dim,(int)ndec,C,b,constraints,&X,&y,&Z);
    //Solve the problem
    status=easy_sdp((int)total_dim,(int)ndec,C,b,constraints,objconstant,params,&X,&y,&Z,pval,dval,pinf,dinf,realgap,xzgap);
    //Stop Timer
    end = clock();
    evaltime = ((double)(end-start))/CLOCKS_PER_SEC;
    
    //Copy and negate solution
    for(i=0;i<ndec;i++)
        x[i] = -y[i+1];
    //Assign other MATLAB outputs
    *iter = (double)citer-1;    
    *exitflag = (double)status;
     
    //Print Header
    if(printLevel){            
        //Detail termination reason
        switch(status)
        {
            //Success
            case 0:	
                mexPrintf("\n *** CSDP CONVERGED ***\n");  break;
            //Infeasible
            case 1:
                mexPrintf("\n *** TERMINATION: Primal Infeasible ***\n");  break;
            case 2:
                mexPrintf("\n *** TERMINATION: Dual Infeasible ***\n");  break;
            //Partial Success
            case 3:
                mexPrintf("\n *** TERMINATION: PARTIAL SUCESS ***\n *** A Solution is found but full accuracy was not achieved ***\n"); break;
            //Error
            case 4:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Maximum Iterations Reached ***\n"); break;
            case CSDP_MAX_TIME:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Maximum Time Reached ***\n"); break;
            case 5:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Stuck at edge of primal feasibility ***\n"); break;
            case 6:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Stuck at edge of dual infeasibility ***\n"); break;
            case 7:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Lack of progress ***\n"); break;
            case 8:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: X, Z, or O was singular ***\n"); break;
            case 9:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Detected NaN or Inf values ***\n"); break;
            case 10:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Easy-SDP General Failure ***\n"); break;
            case 11:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Failed C Check - Check Symmetry! ***\n"); break;
            case 12:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Failed Constraints Check ***\n"); break;
            case CSDP_USER_TERMINATION:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: User Exited ***\n"); break;            
            //Here is ok too?
            default:
                mexPrintf("\n *** CSDP FINISHED ***\n"); break;
        }

        if(status==0 || status==3)
        	mexPrintf("\n Final Primal Objective:  %2.5g\n Final Dual Objective:    %2.5g\n In %5d iterations\n    %5.2f seconds\n",*pval,*dval,citer-1,evaltime);

        mexPrintf("------------------------------------------------------------------\n\n");
    }  
    
    //Optionally write solution to a SDPA sparse file
    if(nrhs > eOPTS && !mxIsEmpty(pOPTS) && mxGetField(pOPTS,0,"writesol") && !mxIsEmpty(mxGetField(pOPTS,0,"writesol")) && mxIsChar(mxGetField(pOPTS,0,"writesol"))) {
        mxGetString(mxGetField(pOPTS,0,"writesol"),msgbuf,1024);
        write_sol(msgbuf,(int)total_dim,(int)ndec,X,y,Z);
    }
    
    //Optionally retrieve X
    if(nlhs > 4) {
        plhs[4] = mxCreateCellMatrix(X.nblocks,1);
        for(i=0;i<X.nblocks;i++) {            
            //Set Block Values
            if(X.blocks[i+1].blockcategory == DIAG) {
                mxSetCell(plhs[4],i,mxCreateDoubleMatrix(X.blocks[i+1].blocksize,1,mxREAL)); //create vector
                xx = mxGetPr(mxGetCell(plhs[4],i));
                for(j=0;j<X.blocks[i+1].blocksize;j++)
                    xx[j] = X.blocks[i+1].data.vec[j+1]; 
            }
            else {
                mxSetCell(plhs[4],i,mxCreateDoubleMatrix(X.blocks[i+1].blocksize,X.blocks[i+1].blocksize,mxREAL)); //create matrix
                xx = mxGetPr(mxGetCell(plhs[4],i));
                for(j=0;j<(X.blocks[i+1].blocksize*X.blocks[i+1].blocksize);j++)
                    xx[j] = X.blocks[i+1].data.mat[j];           
            }
        }        
    }

    //Free CSDP Problem (including all allocated memory)
    free_prob((int)total_dim,(int)ndec,C,b,constraints,X,y,Z);
}