int main(void) { int r_bufid = 0, s_bufid = 0; cg_prob *p; int num_cuts = 0; double elapsed; struct timeval tout = {15, 0}; p = (cg_prob *) calloc(1, sizeof(cg_prob)); cg_initialize(p, 0); /*------------------------------------------------------------------------*\ * The main loop -- executes continuously until the program exits \*------------------------------------------------------------------------*/ while (TRUE){ /* Wait until a message arrives */ do{ r_bufid = treceive_msg(ANYONE, ANYTHING, &tout); if (!r_bufid){ if (pstat(p->tree_manager) != PROCESS_OK){ printf("TM has died -- CG exiting\n\n"); exit(-401); } } }while (!r_bufid); if (cg_process_message(p, r_bufid) == USER_ERROR) p->msgtag = USER_ERROR; /* If there is still something in the queue, process it */ do{ r_bufid = nreceive_msg(ANYONE, ANYTHING); if (r_bufid > 0) if (cg_process_message(p, r_bufid) == USER_ERROR) p->msgtag = USER_ERROR; }while (r_bufid != 0); /*--------------------------------------------------------------------- * Now the message queue is empty. If the last message was NOT some * kind of LP_SOLUTION then we can't generate solutions now. * Otherwise, generate solutions! *---------------------------------------------------------------------*/ if (p->msgtag == LP_SOLUTION_NONZEROS || p->msgtag == LP_SOLUTION_USER || p->msgtag == LP_SOLUTION_FRACTIONS){ if (p->par.do_findcuts) if ((termcode = find_cuts_u(p, NULL, &num_cuts)) < 0) printf("Warning: User error detected in cut generator\n\n"); /*-- send signal back to the LP that the cut generator is done -----*/ s_bufid = init_send(DataInPlace); send_int_array(&num_cuts, 1); elapsed = used_time(&p->tt); send_dbl_array(&elapsed, 1); send_int_array(&p->cur_sol.xindex, 1); send_int_array(&p->cur_sol.xiter_num, 1); send_msg(p->cur_sol.lp, NO_MORE_CUTS); freebuf(s_bufid); FREE(p->cur_sol.xind); FREE(p->cur_sol.xval); } } return(0); }
node_desc *create_explicit_node_desc(lp_prob *p) { LPdata *lp_data = p->lp_data; int m = lp_data->m, n = lp_data->n; int bvarnum = p->base.varnum; var_desc **extravars = lp_data->vars + bvarnum; int extravarnum = n - bvarnum; int bcutnum = p->base.cutnum; row_data *rows = lp_data->rows; int extrarownum = m - bcutnum; int cutindsize; node_desc *desc = (node_desc *) calloc(1, sizeof(node_desc)); /* Will need these anyway for basis */ int *rstat = (int *) malloc(m * ISIZE); int *cstat = (int *) malloc(n * ISIZE); int *erstat = (extrarownum == 0) ? NULL : (int *) malloc(extrarownum*ISIZE); int *ecstat = (extravarnum == 0) ? NULL : (int *) malloc(extravarnum*ISIZE); int *ulist, *clist; /* this later uses tmp.i1 */ int cutcnt, i, j; #ifndef COMPILE_IN_LP int s_bufid, r_bufid; #endif get_basis(lp_data, cstat, rstat); if (extrarownum > 0) memcpy(erstat, rstat + bcutnum, extrarownum * ISIZE); if (extravarnum > 0) memcpy(ecstat, cstat + bvarnum, extravarnum * ISIZE); /* To start with, send the non-indexed cuts (only those which will be saved) to the treemanager and ask for names */ for (cutcnt = cutindsize = 0, i = bcutnum; i < m; i++){ if ((rows[i].cut->branch & CUT_BRANCHED_ON) || !rows[i].free || (rows[i].free && rstat[i] != SLACK_BASIC)){ cutindsize++; if (rows[i].cut->name < 0) cutcnt++; } } if (cutcnt > 0){ #ifdef COMPILE_IN_LP row_data *tmp_rows = (row_data *) malloc(cutcnt*sizeof(row_data)); for (j = 0, i = bcutnum; j < cutcnt; i++){ if (rows[i].cut->name < 0 && (!rows[i].free || (rows[i].free && rstat[i] != SLACK_BASIC))) tmp_rows[j++] = rows[i]; } unpack_cut_set(p->tm, 0, cutcnt, tmp_rows); FREE(tmp_rows); #else s_bufid = init_send(DataInPlace); send_int_array(&cutcnt, 1); for (i = bcutnum; i < m; i++){ if (rows[i].cut->name < 0 && (!rows[i].free || (rows[i].free && rstat[i] != SLACK_BASIC))) pack_cut(rows[i].cut); } send_msg(p->tree_manager, LP__CUT_NAMES_REQUESTED); freebuf(s_bufid); #endif } /* create the uind list and the extravars basis description */ desc->uind.type = EXPLICIT_LIST; desc->uind.added = 0; desc->uind.size = extravarnum; desc->basis.extravars.type = EXPLICIT_LIST; desc->basis.extravars.size = extravarnum; desc->basis.extravars.list = NULL; if (extravarnum > 0){ desc->uind.list = ulist = (int *) malloc(extravarnum * ISIZE); desc->basis.extravars.stat = ecstat; for (i = extravarnum - 1; i >= 0; i--) ulist[i] = extravars[i]->userind; if (lp_data->ordering == COLIND_ORDERED) qsortucb_ii(ulist, ecstat, extravarnum); }else{ desc->uind.list = NULL; desc->basis.extravars.stat = NULL; } /* create the basevars basis description */ desc->basis.basevars.type = EXPLICIT_LIST; desc->basis.basevars.size = bvarnum; desc->basis.basevars.list = NULL; if (bvarnum) desc->basis.basevars.stat = cstat; else FREE(cstat); /* create the not_fixed list */ desc->nf_status = lp_data->nf_status; if (desc->nf_status == NF_CHECK_AFTER_LAST || desc->nf_status == NF_CHECK_UNTIL_LAST){ desc->not_fixed.type = EXPLICIT_LIST; desc->not_fixed.added = 0; if ((desc->not_fixed.size = lp_data->not_fixed_num) > 0){ desc->not_fixed.list = (int *) malloc(desc->not_fixed.size * ISIZE); memcpy(desc->not_fixed.list, lp_data->not_fixed, lp_data->not_fixed_num * ISIZE); }else{ desc->not_fixed.list = NULL; } } #ifndef COMPILE_IN_LP /* At this point we will need the missing names */ if (cutcnt > 0){ static struct timeval tout = {15, 0}; int *names = lp_data->tmp.i1; /* m */ double start = wall_clock(NULL); do{ r_bufid = treceive_msg(p->tree_manager, LP__CUT_NAMES_SERVED, &tout); if (! r_bufid){ if (pstat(p->tree_manager) != PROCESS_OK){ printf("TM has died -- LP exiting\n\n"); exit(-301); } } }while (! r_bufid); p->comp_times.idle_names += wall_clock(NULL) - start; receive_int_array(names, cutcnt); for (j = 0, i = bcutnum; j < cutcnt; i++){ if (rows[i].cut->name < 0 && (!rows[i].free || (rows[i].free && rstat[i] != SLACK_BASIC))) rows[i].cut->name = names[j++]; } } #endif /* create the cutind list and the extrarows basis description */ desc->cutind.type = EXPLICIT_LIST; desc->cutind.added = 0; desc->cutind.size = cutindsize; desc->basis.extrarows.type = EXPLICIT_LIST; desc->basis.extrarows.list = NULL; desc->basis.extrarows.size = cutindsize; if (cutindsize > 0){ desc->cutind.list = clist = (int *) malloc(cutindsize * ISIZE); desc->basis.extrarows.stat = erstat; for (cutindsize = 0, i = bcutnum; i < m; i++){ if ((rows[i].cut->branch & CUT_BRANCHED_ON) || !rows[i].free || (rows[i].free && rstat[i] != SLACK_BASIC)){ clist[cutindsize] = rows[i].cut->name; erstat[cutindsize++] = rstat[i]; } } qsortucb_ii(clist, erstat, cutindsize); }else{ desc->cutind.list = NULL; desc->basis.extrarows.stat = NULL; } /* create the baserows basis description */ desc->basis.baserows.type = EXPLICIT_LIST; desc->basis.baserows.size = bcutnum; desc->basis.baserows.list = NULL; if (bcutnum) desc->basis.baserows.stat = rstat; else FREE(rstat); /* Mark that there is a basis */ desc->basis.basis_exists = TRUE; /* Add user description */ add_to_desc_u(p, desc); return(desc); }
int main(void) { lp_prob *p; int r_bufid; double time, diff; struct timeval timeout = {10, 0}; char first_node_rec = FALSE; int termcode; p = (lp_prob *) calloc(1, sizeof(lp_prob)); p->start_time = wall_clock(NULL); if ((termcode = lp_initialize(p, 0)) < 0){ printf("LP initialization failed with error code %i\n\n", termcode); lp_exit(p); } /*------------------------------------------------------------------------*\ * Continue receiving node data and fathoming branches until this * process is killed \*------------------------------------------------------------------------*/ p->phase = 0; while (TRUE){ p->lp_data->col_set_changed = TRUE; /*---------------------------------------------------------------------*\ * waits for an active node message but if there's anything left after * receiving that, those messages are processed, before going to * process_chain(). \*---------------------------------------------------------------------*/ time = wall_clock(NULL); do{ r_bufid = treceive_msg(ANYONE, ANYTHING, &timeout); }while (! process_message(p, r_bufid, NULL, NULL) ); diff = wall_clock(NULL) - time; if (first_node_rec){ p->comp_times.idle_node += diff; }else{ first_node_rec = TRUE; p->comp_times.ramp_up_lp += diff; } do{ r_bufid = nreceive_msg(ANYONE, ANYTHING); if (r_bufid) process_message(p, r_bufid, NULL, NULL); }while (r_bufid); p->comp_times.communication += used_time(&p->tt); if (process_chain(p) < 0){ printf("\nThere was an error in the LP process. Exiting now.\n\n"); /* There was an error in the LP. Abandon node. */ lp_exit(p); } } p->comp_times.wall_clock_lp = wall_clock(NULL) - p->start_time; lp_exit(p); return(0); }