double Tube::min() const { if(is_unbounded()) return -1000; // BETA if(is_empty()) return 0; // BETA double min = (*this)[0].lb(); for(int i=1; i<size(); i++){ if((*this)[i].lb()<min) min = (*this)[i].lb(); } return min; }
double Tube::max() const { if(is_unbounded()) return POS_INFINITY; if(is_empty()) return NEG_INFINITY; // BETA double max = (*this)[0].ub(); for(int i=1; i<size(); i++) { if((*this)[i].ub()>max) max = (*this)[i].ub(); } return max; }
virtual result operator()(goal const & g) { return is_unbounded(g); }
MYBOOL crash_basis(lprec *lp) { int i; MATrec *mat = lp->matA; MYBOOL ok = TRUE; /* Initialize basis indicators */ if(lp->basis_valid) lp->var_basic[0] = FALSE; else default_basis(lp); /* Set initial partial pricing blocks */ if(lp->rowblocks != NULL) lp->rowblocks->blocknow = 1; if(lp->colblocks != NULL) lp->colblocks->blocknow = ((lp->crashmode == CRASH_NONE) || (lp->colblocks->blockcount == 1) ? 1 : 2); /* Construct a basis that is in some measure the "most feasible" */ if((lp->crashmode == CRASH_MOSTFEASIBLE) && mat_validate(mat)) { /* The logic here follows Maros */ LLrec *rowLL = NULL, *colLL = NULL; int ii, rx, cx, ix, nz; REAL wx, tx, *rowMAX = NULL, *colMAX = NULL; int *rowNZ = NULL, *colNZ = NULL, *rowWT = NULL, *colWT = NULL; REAL *value; int *rownr, *colnr; report(lp, NORMAL, "crash_basis: 'Most feasible' basis crashing selected\n"); /* Tally row and column non-zero counts */ ok = allocINT(lp, &rowNZ, lp->rows+1, TRUE) && allocINT(lp, &colNZ, lp->columns+1, TRUE) && allocREAL(lp, &rowMAX, lp->rows+1, FALSE) && allocREAL(lp, &colMAX, lp->columns+1, FALSE); if(!ok) goto Finish; nz = mat_nonzeros(mat); rownr = &COL_MAT_ROWNR(0); colnr = &COL_MAT_COLNR(0); value = &COL_MAT_VALUE(0); for(i = 0; i < nz; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep) { rx = *rownr; cx = *colnr; wx = fabs(*value); rowNZ[rx]++; colNZ[cx]++; if(i == 0) { rowMAX[rx] = wx; colMAX[cx] = wx; colMAX[0] = wx; } else { SETMAX(rowMAX[rx], wx); SETMAX(colMAX[cx], wx); SETMAX(colMAX[0], wx); } } /* Reduce counts for small magnitude to preserve stability */ rownr = &COL_MAT_ROWNR(0); colnr = &COL_MAT_COLNR(0); value = &COL_MAT_VALUE(0); for(i = 0; i < nz; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep) { rx = *rownr; cx = *colnr; wx = fabs(*value); #ifdef CRASH_SIMPLESCALE if(wx < CRASH_THRESHOLD * colMAX[0]) { rowNZ[rx]--; colNZ[cx]--; } #else if(wx < CRASH_THRESHOLD * rowMAX[rx]) rowNZ[rx]--; if(wx < CRASH_THRESHOLD * colMAX[cx]) colNZ[cx]--; #endif } /* Set up priority tables */ ok = allocINT(lp, &rowWT, lp->rows+1, TRUE); createLink(lp->rows, &rowLL, NULL); ok &= (rowLL != NULL); if(!ok) goto Finish; for(i = 1; i <= lp->rows; i++) { if(get_constr_type(lp, i)==EQ) ii = 3; else if(lp->upbo[i] < lp->infinite) ii = 2; else if(fabs(lp->rhs[i]) < lp->infinite) ii = 1; else ii = 0; rowWT[i] = ii; if(ii > 0) appendLink(rowLL, i); } ok = allocINT(lp, &colWT, lp->columns+1, TRUE); createLink(lp->columns, &colLL, NULL); ok &= (colLL != NULL); if(!ok) goto Finish; for(i = 1; i <= lp->columns; i++) { ix = lp->rows+i; if(is_unbounded(lp, i)) ii = 3; else if(lp->upbo[ix] >= lp->infinite) ii = 2; else if(fabs(lp->upbo[ix]-lp->lowbo[ix]) > lp->epsmachine) ii = 1; else ii = 0; colWT[i] = ii; if(ii > 0) appendLink(colLL, i); } /* Loop over all basis variables */ for(i = 1; i <= lp->rows; i++) { /* Select row */ rx = 0; wx = -lp->infinite; for(ii = firstActiveLink(rowLL); ii > 0; ii = nextActiveLink(rowLL, ii)) { tx = rowWT[ii] - CRASH_SPACER*rowNZ[ii]; if(tx > wx) { rx = ii; wx = tx; } } if(rx == 0) break; removeLink(rowLL, rx); /* Select column */ cx = 0; wx = -lp->infinite; for(ii = mat->row_end[rx-1]; ii < mat->row_end[rx]; ii++) { /* Update NZ column counts for row selected above */ tx = fabs(ROW_MAT_VALUE(ii)); ix = ROW_MAT_COLNR(ii); #ifdef CRASH_SIMPLESCALE if(tx >= CRASH_THRESHOLD * colMAX[0]) #else if(tx >= CRASH_THRESHOLD * colMAX[ix]) #endif colNZ[ix]--; if(!isActiveLink(colLL, ix) || (tx < CRASH_THRESHOLD * rowMAX[rx])) continue; /* Now do the test for best pivot */ tx = my_sign(lp->orig_obj[ix]) - my_sign(ROW_MAT_VALUE(ii)); tx = colWT[ix] + CRASH_WEIGHT*tx - CRASH_SPACER*colNZ[ix]; if(tx > wx) { cx = ix; wx = tx; } } if(cx == 0) break; removeLink(colLL, cx); /* Update row NZ counts */ ii = mat->col_end[cx-1]; rownr = &COL_MAT_ROWNR(ii); value = &COL_MAT_VALUE(ii); for(; ii < mat->col_end[cx]; ii++, rownr += matRowColStep, value += matValueStep) { wx = fabs(*value); ix = *rownr; #ifdef CRASH_SIMPLESCALE if(wx >= CRASH_THRESHOLD * colMAX[0]) #else if(wx >= CRASH_THRESHOLD * rowMAX[ix]) #endif rowNZ[ix]--; } /* Set new basis variable */ set_basisvar(lp, rx, lp->rows+cx); } /* Clean up */ Finish: FREE(rowNZ); FREE(colNZ); FREE(rowMAX); FREE(colMAX); FREE(rowWT); FREE(colWT); freeLink(&rowLL); freeLink(&colLL); } /* Construct a basis that is in some measure the "least degenerate" */ else if((lp->crashmode == CRASH_LEASTDEGENERATE) && mat_validate(mat)) { /* The logic here follows Maros */ LLrec *rowLL = NULL, *colLL = NULL; int ii, rx, cx, ix, nz, *merit = NULL; REAL *value, wx, hold, *rhs = NULL, *eta = NULL; int *rownr, *colnr; report(lp, NORMAL, "crash_basis: 'Least degenerate' basis crashing selected\n"); /* Create temporary arrays */ ok = allocINT(lp, &merit, lp->columns + 1, FALSE) && allocREAL(lp, &eta, lp->rows + 1, FALSE) && allocREAL(lp, &rhs, lp->rows + 1, FALSE); createLink(lp->columns, &colLL, NULL); createLink(lp->rows, &rowLL, NULL); ok &= (colLL != NULL) && (rowLL != NULL); if(!ok) goto FinishLD; MEMCOPY(rhs, lp->orig_rhs, lp->rows + 1); for(i = 1; i <= lp->columns; i++) appendLink(colLL, i); for(i = 1; i <= lp->rows; i++) appendLink(rowLL, i); /* Loop until we have found enough new bases */ while(colLL->count > 0) { /* Tally non-zeros matching in RHS and each active column */ nz = mat_nonzeros(mat); rownr = &COL_MAT_ROWNR(0); colnr = &COL_MAT_COLNR(0); ii = 0; MEMCLEAR(merit, lp->columns + 1); for(i = 0; i < nz; i++, rownr += matRowColStep, colnr += matRowColStep) { rx = *rownr; cx = *colnr; if(isActiveLink(colLL, cx) && (rhs[rx] != 0)) { merit[cx]++; ii++; } } if(ii == 0) break; /* Find maximal match; break ties with column length */ i = firstActiveLink(colLL); cx = i; for(i = nextActiveLink(colLL, i); i != 0; i = nextActiveLink(colLL, i)) { if(merit[i] >= merit[cx]) { if((merit[i] > merit[cx]) || (mat_collength(mat, i) > mat_collength(mat, cx))) cx = i; } } /* Determine the best pivot row */ i = mat->col_end[cx-1]; nz = mat->col_end[cx]; rownr = &COL_MAT_ROWNR(i); value = &COL_MAT_VALUE(i); rx = 0; wx = 0; MEMCLEAR(eta, lp->rows + 1); for(; i < nz; i++, rownr += matRowColStep, value += matValueStep) { ix = *rownr; hold = *value; eta[ix] = rhs[ix] / hold; hold = fabs(hold); if(isActiveLink(rowLL, ix) && (hold > wx)) { wx = hold; rx = ix; } } /* Set new basis variable */ if(rx > 0) { /* We have to update the rhs vector for the implied transformation in order to be able to find the new RHS non-zero pattern */ for(i = 1; i <= lp->rows; i++) rhs[i] -= wx * eta[i]; rhs[rx] = wx; /* Do the exchange */ set_basisvar(lp, rx, lp->rows+cx); removeLink(rowLL, rx); } removeLink(colLL, cx); } /* Clean up */ FinishLD: FREE(merit); FREE(rhs); freeLink(&rowLL); freeLink(&colLL); } return( ok ); }
result operator()(goal const & g) override { return is_unbounded(g); }