/** execution method of primal heuristic */ static SCIP_DECL_HEUREXEC(heurExecFixandinfer) { /*lint --e{715}*/ SCIP_HEURDATA* heurdata; SCIP_VAR** cands; int ncands; int startncands; int divedepth; SCIP_Bool cutoff; SCIP_Real large; *result = SCIP_DIDNOTRUN; /* we cannot run on problems with continuous variables */ if( SCIPgetNContVars(scip) > 0 ) return SCIP_OKAY; /* get unfixed variables */ SCIP_CALL( SCIPgetPseudoBranchCands(scip, &cands, &ncands, NULL) ); if( ncands == 0 ) return SCIP_OKAY; SCIPdebugMessage("starting fix-and-infer heuristic with %d unfixed integral variables\n", ncands); *result = SCIP_DIDNOTFIND; /* get heuristic data */ heurdata = SCIPheurGetData(heur); assert(heurdata != NULL); /* start probing */ SCIP_CALL( SCIPstartProbing(scip) ); /* fix variables and propagate inferences as long as the problem is still feasible and there are * unfixed integral variables */ cutoff = FALSE; divedepth = 0; startncands = ncands; /* determine large value to set variables to */ large = SCIPinfinity(scip); if( !SCIPisInfinity(scip, 0.1 / SCIPfeastol(scip)) ) large = 0.1 / SCIPfeastol(scip); while( !cutoff && ncands > 0 && (divedepth < heurdata->minfixings || (startncands - ncands) * 2 * MAXDIVEDEPTH >= startncands * divedepth) && !SCIPisStopped(scip) ) { divedepth++; /* create next probing node */ SCIP_CALL( SCIPnewProbingNode(scip) ); /* fix next variable */ SCIP_CALL( fixVariable(scip, cands, ncands, large) ); /* propagate the fixing */ SCIP_CALL( SCIPpropagateProbing(scip, heurdata->proprounds, &cutoff, NULL) ); /* get remaining unfixed variables */ if( !cutoff ) { SCIP_CALL( SCIPgetPseudoBranchCands(scip, &cands, &ncands, NULL) ); } } /* check, if we are still feasible */ if( cutoff ) { SCIPdebugMessage("propagation detected a cutoff\n"); } else if( ncands == 0 ) { SCIP_Bool success; success = FALSE; /* try to add solution to SCIP */ SCIP_CALL( SCIPtryCurrentSol(scip, heur, FALSE, FALSE, TRUE, &success) ); if( success ) { SCIPdebugMessage("found primal feasible solution\n"); *result = SCIP_FOUNDSOL; } else { SCIPdebugMessage("primal solution was rejected\n"); } } else { SCIPdebugMessage("probing was aborted (probing depth: %d, fixed: %d/%d)", divedepth, startncands - ncands, startncands); } /* end probing */ SCIP_CALL( SCIPendProbing(scip) ); return SCIP_OKAY; }
char constraintPropagation(CPropagation *cp, int var, double value, vector<Fixation> &fixations, int &unfixedVars, double *colLb, double *colUb, double *constrBound, int *unfixedVarsByRow) { assert(value == 0.0 || value == 1.0); assert(var >= 0 && var < cp->numCols); //assert(colLb[var] != colUb[var]); if(colLb[var] == colUb[var]) { // assert(colLb[var] == value); return NOIMPLICATION; } //assert(fixations.empty()); char status = NOIMPLICATION; queue<int> C; Fixation tmp; vector<char> rowIsInQueue(cp->numRows, 0); fixVariable(cp, var, value, unfixedVars, colLb, colUb, constrBound, unfixedVarsByRow); for(int i = 0; i < (int)cp->matrixByCol[var].size(); i++) { const pair<int, double> constraint = cp->matrixByCol[var][i]; const int idxRow = constraint.first; const double coef = constraint.second; if((unfixedVarsByRow[idxRow] > 0) && (value == 1.0 && coef > 0.0) || (value == 0.0 && coef < 0.0)) { C.push(idxRow); rowIsInQueue[idxRow] = 1; } } while(!C.empty()) { const int idxRow = C.front(); C.pop(); rowIsInQueue[idxRow] = 0; for(int i = 0; i < (int)cp->matrixByRow[idxRow].size(); i++) { const pair<int, double> var = cp->matrixByRow[idxRow][i]; const int idxVar = var.first; const double coef = var.second; if(colLb[idxVar] == colUb[idxVar]) continue; char eval = evaluateBound(cp, var, idxRow, constrBound); if(eval == ACTIVATE || eval == DEACTIVATE) { assert(colLb[idxVar] != colUb[idxVar]); tmp.idxVar = idxVar; tmp.valueToFix = eval; fixations.push_back(tmp); status = FIXATION; unfixedVars--; colLb[idxVar] = colUb[idxVar] = eval; for(int j = 0; j < (int)cp->matrixByCol[idxVar].size(); j++) { const pair<int, double> constraint = cp->matrixByCol[idxVar][j]; const int idxRow2 = constraint.first; const double coef2 = constraint.second; unfixedVarsByRow[idxRow2]--; if(eval == ACTIVATE && coef2 > 0.0) { constrBound[idxRow2] -= coef2; if(unfixedVarsByRow[idxRow2] > 0 && !rowIsInQueue[idxRow2]) { C.push(idxRow2); rowIsInQueue[idxRow2] = 1; } } else if(eval == DEACTIVATE && coef2 < 0.0) { constrBound[idxRow2] += coef2; if(unfixedVarsByRow[idxRow2] > 0 && !rowIsInQueue[idxRow2]) { C.push(idxRow2); rowIsInQueue[idxRow2] = 1; } } if(unfixedVarsByRow[idxRow2] == 0 && constrBound[idxRow2] < 0.0) status = CONFLICT; //nao posso retornar direto pq tenho q atualizar os bounds das retricoes } if(status == CONFLICT) return CONFLICT; } else if(eval == CONFLICT) return CONFLICT; } } return status; }