Exemple #1
0
void decodePlanarCode(unsigned short* code) {
    /* complexity of method to determine inverse isn't that good, but will have to satisfy for now
     */
    int i, j, codePosition;
    int edgeCounter = 0;
    EDGE *inverse;

    nv = code[0];
    codePosition = 1;

    for (i = 0; i < nv; i++) {
        degree[i] = 0;
        neighbourhood[i] = SINGLETON(code[codePosition] - 1);
        firstedge[i] = edges + edgeCounter;
        edges[edgeCounter].start = i;
        edges[edgeCounter].end = code[codePosition] - 1;
        edges[edgeCounter].vertices = UNION(SINGLETON(i), SINGLETON(code[codePosition] - 1));
        edges[edgeCounter].next = edges + edgeCounter + 1;
        if (code[codePosition] - 1 < i) {
            inverse = edgeMatrix[code[codePosition] - 1][i];
            edges[edgeCounter].inverse = inverse;
            inverse->inverse = edges + edgeCounter;
        } else {
            edgeMatrix[i][code[codePosition] - 1] = edges + edgeCounter;
            edges[edgeCounter].inverse = NULL;
        }
        edgeCounter++;
        codePosition++;
        for (j = 1; code[codePosition]; j++, codePosition++) {
            if (j == MAXVAL) {
                fprintf(stderr, "MAXVAL too small: %d\n", MAXVAL);
                exit(0);
            }
            ADD(neighbourhood[i], code[codePosition] - 1);
            edges[edgeCounter].start = i;
            edges[edgeCounter].end = code[codePosition] - 1;
            edges[edgeCounter].vertices = UNION(SINGLETON(i), SINGLETON(code[codePosition] - 1));
            edges[edgeCounter].prev = edges + edgeCounter - 1;
            edges[edgeCounter].next = edges + edgeCounter + 1;
            if (code[codePosition] - 1 < i) {
                inverse = edgeMatrix[code[codePosition] - 1][i];
                edges[edgeCounter].inverse = inverse;
                inverse->inverse = edges + edgeCounter;
            } else {
                edgeMatrix[i][code[codePosition] - 1] = edges + edgeCounter;
                edges[edgeCounter].inverse = NULL;
            }
            edgeCounter++;
        }
        firstedge[i]->prev = edges + edgeCounter - 1;
        edges[edgeCounter - 1].next = firstedge[i];
        degree[i] = j;

        codePosition++; /* read the closing 0 */
    }

    ne = edgeCounter;

    makeDual();

    // nv - ne/2 + nf = 2
}
Exemple #2
0
PLANE_GRAPH *decodePlanarCode(unsigned short* code, PG_INPUT_OPTIONS *options) {
    int i, j, codePosition, nv, maxn;
    int edgeCounter = 0;
    PG_EDGE *inverse;

    nv = code[0];
    codePosition = 1;
    
    if(options->maxn <= 0){
        maxn = nv*options->maxnFactor;
    } else {
        maxn = options->maxn;
    }
    
    PLANE_GRAPH *pg = newPlaneGraph(maxn, options->maxe);
    pg->nv = nv;

    for (i = 0; i < nv; i++) {
        pg->degree[i] = 0;
        pg->firstedge[i] = pg->edges + edgeCounter;
        pg->edges[edgeCounter].start = i;
        pg->edges[edgeCounter].end = code[codePosition] - 1;
        pg->edges[edgeCounter].next = pg->edges + edgeCounter + 1;
        if (code[codePosition] - 1 < i) {
            inverse = findEdge(pg, code[codePosition] - 1, i);
            pg->edges[edgeCounter].inverse = inverse;
            inverse->inverse = pg->edges + edgeCounter;
        } else {
            pg->edges[edgeCounter].inverse = NULL;
        }
        edgeCounter++;
        codePosition++;
        for (j = 1; code[codePosition]; j++, codePosition++) {
            pg->edges[edgeCounter].start = i;
            pg->edges[edgeCounter].end = code[codePosition] - 1;
            pg->edges[edgeCounter].prev = pg->edges + edgeCounter - 1;
            pg->edges[edgeCounter].next = pg->edges + edgeCounter + 1;
            if (code[codePosition] - 1 < i) {
                inverse = findEdge(pg, code[codePosition] - 1, i);
                pg->edges[edgeCounter].inverse = inverse;
                inverse->inverse = pg->edges + edgeCounter;
            } else {
                pg->edges[edgeCounter].inverse = NULL;
            }
            edgeCounter++;
        }
        pg->firstedge[i]->prev = pg->edges + edgeCounter - 1;
        pg->edges[edgeCounter - 1].next = pg->firstedge[i];
        pg->degree[i] = j;

        codePosition++; /* read the closing 0 */
    }

    pg->ne = edgeCounter;

    if(options->computeDual){
        makeDual(pg);
    }
    
    return pg;
}
Exemple #3
0
/** Extract sub block number <code>n</code> from <code>problem</code>.
 * The constructor creates a representation of block number <code>n</code>
 * as described in <code>problem</code>.
 * The constructor will also connect the newly created block to a remote
 * object solver instance.
 * @param problem  The problem from which the block is to be extracted.
 * @param n        Index of the block to be extracted.
 * @param argc     Argument for IloCplex constructor.
 * @param argv     Argument for IloCplex constructor.
 * @param machines List of machines to which to connect. If the code is
 *                 compiled for the TCP/IP transport then the block will
 *                 be connected to <code>machines[n]</code>.
 */
BendersOpt::Block::Block(Problem const *problem, IloInt n, int argc, char const *const *argv,
                         std::vector<char const *> const &machines)
   : env(), number(n), vars(0), rows(0), cplex(0), cb(0)
{
   IloNumVarArray problemVars = problem->getVariables();
   IloRangeArray problemRanges = problem->getRows();

   // Create a map that maps variables in the original model to their
   // respective index in problemVars.
   std::map<IloNumVar,IloInt,ExtractableLess<IloNumVar> > origIdxMap;
   for (IloInt j = 0; j < problemVars.getSize(); ++j)
      origIdxMap.insert(std::map<IloNumVar,IloInt,ExtractableLess<IloNumVar> >::value_type(problemVars[j], j));

   // Copy non-fixed variables from original problem into primal problem.
   IloExpr primalObj(env);
   IloNumVarArray primalVars(env);
   IloRangeArray primalRows(env);
   IdxMap idxMap; // Index of original variable in block's primal model
   RowSet rowSet;
   for (IloInt j = 0; j < problemVars.getSize(); ++j) {
      IloNumVar x = problemVars[j];
      if ( problem->getBlock(x) == number ) {
         // Create column in block LP with exactly the same data.
         if ( x.getType() != IloNumVar::Float ) {
            std::stringstream s;
            s << "Cannot create non-continuous block variable " << x;
            std::cerr << s.str() << std::endl;
            throw s.str();
         }
         IloNumVar v(env, x.getLB(), x.getUB(), x.getType(), x.getName());
         // Normalize objective function to 'minimize'
         double coef = problem->getObjCoef(x);
         if ( problem->getObjSense() != IloObjective::Minimize )
            coef *= -1.0;
         primalObj += coef * v;
            
         // Record the index that the copied variable has in the
         // block model.
         idxMap.insert(IdxMap::value_type(x, primalVars.getSize()));
         primalVars.add(v);
            
         // Mark the rows that are intersected by this column
         // so that we can collect them later.
         RowSet const &intersected = problem->getIntersectedRows(x);
         for (RowSet::const_iterator it = intersected.begin();
              it != intersected.end(); ++it)
            rowSet.insert(*it);
      }
      else
         idxMap.insert(IdxMap::value_type(x, -1));
   }

   // Now copy all rows that intersect block variables.
   for (IloInt i = 0; i < problemRanges.getSize(); ++i) {
      IloRange r = problemRanges[i];
      if ( rowSet.find(r) == rowSet.end() )
         continue;

      // Create a copy of the row, normalizing it to '<='
      double factor = 1.0;
      if ( r.getLB() > -IloInfinity )
         factor = -1.0;
      IloRange primalR(env,
                       factor < 0 ? -r.getUB() : r.getLB(),
                       factor < 0 ? -r.getLB() : r.getUB(), r.getName());
      IloExpr lhs(env);
      for (IloExpr::LinearIterator it = r.getLinearIterator(); it.ok(); ++it)
      {
         IloNumVar v = it.getVar();
         double const val = factor * it.getCoef();
         if ( problem->getBlock(v) != number ) {
            // This column is not explicitly in this block. This means
            // that it is a column that will be fixed by the master.
            // We collect all such columns so that we can adjust the
            // dual objective function according to concrete fixings.
            // Store information about variables in this block that
            // will be fixed by master solves.
            fixed.push_back(FixData(primalRows.getSize(), origIdxMap[v], -val));
         }
         else {
            // The column is an ordinary in this block. Just copy it.
            lhs += primalVars[idxMap[v]] * val;
         }
      }
      primalR.setExpr(lhs);
      primalRows.add(primalR);
      lhs.end();
   }

   // Create the dual of the primal model we just created.
   // Note that makeDual _always_ returns a 'maximize' objective.
   IloObjective objective(env, primalObj, IloObjective::Minimize);
      
   makeDual(objective, primalVars, primalRows,
            &obj, &vars, &rows);
   objective.end();
   primalRows.endElements();
   primalRows.end();
   primalVars.endElements();
   primalVars.end();
   primalObj.end();
   // Create a model.
   IloModel model(env);
   model.add(obj);
   model.add(vars);
   model.add(rows);
   for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it)
      objMap.insert(ObjMap::value_type(it.getVar(), it.getCoef()));

   // Finally create the IloCplex instance that will solve
   // the problems associated with this block.
   char const **transargv = new char const *[argc + 3];
   for (int i = 0; i < argc; ++i)
      transargv[i] = argv[i];
#if defined(USE_MPI)
   char extra[128];
   sprintf (extra, "-remoterank=%d", static_cast<int>(number + 1));
   transargv[argc++] = extra;
   (void)machines;
#elif defined(USE_PROCESS)
   char extra[128];
   sprintf (extra, "-logfile=block%04d.log", static_cast<int>(number));
   transargv[argc++] = extra;
   (void)machines;
#elif defined(USE_TCPIP)
   transargv[argc++] = machines[number];
#endif
   cplex = IloCplex(model, TRANSPORT, argc, transargv);
   delete[] transargv;

   // Suppress output from this block's solver.
   cplex.setOut(env.getNullStream());
   cplex.setWarning(env.getNullStream());
}
Exemple #4
0
PLANE_GRAPH *getDualGraph(PLANE_GRAPH *pg){
    int i;
    
    if(!pg->dualComputed){
        makeDual(pg);
    }
    
    PLANE_GRAPH *dual = newPlaneGraph(pg->nf, pg->ne);
    
    if(dual==NULL){
        fprintf(stderr, "Insufficient memory to create dual.\n");
        return NULL;
    }
    
    for(i = 0; i < pg->ne; i++){
        pg->edges[i].index = i;
    }
    
    dual->nv = pg->nf;
    dual->ne = pg->ne;
    dual->nf = pg->nv;
    
    for(i = 0; i < pg->ne; i++){
        dual->edges[i].start = pg->edges[i].rightface;
        dual->edges[i].end = pg->edges[i].inverse->rightface;
        dual->edges[i].rightface = pg->edges[i].end;
        
        dual->edges[i].inverse = dual->edges + pg->edges[i].inverse->index;
        dual->edges[i].next = dual->edges + pg->edges[i].inverse->prev->index;
        dual->edges[i].prev = dual->edges + pg->edges[i].next->inverse->index;
    }
    
    for(i = 0; i < pg->nf; i++){
        dual->degree[i] = pg->faceSize[i];
        dual->firstedge[i] = dual->edges + pg->facestart[i]->index;
    }
    
    dual->maxf = pg->nv;
    
    dual->facestart = (PG_EDGE **)malloc(sizeof(PG_EDGE *)*(dual->maxf));
        
    if(dual->facestart == NULL){
        dual->maxf = 0;
        return dual;
    }

    dual->faceSize = (int *)malloc(sizeof(int)*(dual->maxf));

    if(dual->faceSize == NULL){
        dual->maxf = 0;
        free(dual->facestart);
        return dual;
    }
    
    for(i = 0; i < pg->nv; i++){
        dual->faceSize[i] = pg->degree[i];
        dual->facestart[i] = dual->edges + pg->firstedge[i]->inverse->index;
    }
    
    dual->dualComputed = TRUE;
    
    return dual;
}