/** transforms given values of the given original variables into values of the given master variables */ void GCGrelaxTransformOrigvalsToMastervals( SCIP* scip, /**< SCIP data structure */ SCIP_VAR** origvars, /**< array with (subset of the) original variables */ SCIP_Real* origvals, /**< array with values (coefs) for the given original variables */ int norigvars, /**< number of given original variables */ SCIP_VAR** mastervars, /**< array of (all present) master variables */ SCIP_Real* mastervals, /**< array to store the values of the master variables */ int nmastervars /**< number of master variables */ ) { int i; int j; int k; assert(scip != NULL); assert(origvars != NULL); assert(origvals != NULL); assert(mastervars != NULL); assert(mastervals != NULL); assert(nmastervars >= 0); /* set all values to 0 initially */ for( i = 0; i < nmastervars; i++ ) mastervals[i] = 0.0; /* iterate over all original variables */ for( i = 0; i < norigvars; i++ ) { SCIP_VAR** varmastervars; SCIP_Real* varmastervals; int blocknr; assert(GCGvarIsOriginal(origvars[i])); varmastervars = GCGoriginalVarGetMastervars(origvars[i]); varmastervals = GCGoriginalVarGetMastervals(origvars[i]); blocknr = GCGvarGetBlock(origvars[i]); /* variable belongs to no block (or is a linking variable), so it was transferred directly to the master problem, * hence, we transfer the value directly to the corresponding master variabe */ if( blocknr < 0 ) { assert(blocknr == -1 || blocknr == -2); assert(SCIPvarIsOriginal(varmastervars[0])); assert(SCIPvarGetTransVar(varmastervars[0]) != NULL); for( k = 0; k < nmastervars; k++ ) { if( mastervars[k] == SCIPvarGetTransVar(varmastervars[0]) ) { mastervals[k] += (varmastervals[0] * origvals[i]); break; } } assert(k < nmastervars); } /* variable belongs to exactly one block, so we have to look at all master variables and increase their values * if they contain the original variable */ else { SCIP_VAR* pricingvar; SCIP_VAR* origvar; SCIP_VAR** curmastervars; SCIP_Real* curmastervals; int ncurmastervars; pricingvar = GCGoriginalVarGetPricingVar(origvars[i]); assert(GCGvarIsPricing(pricingvar)); origvar = GCGpricingVarGetOriginalVar(pricingvar); assert(GCGvarIsOriginal(origvar)); curmastervars = GCGoriginalVarGetMastervars(origvar); curmastervals = GCGoriginalVarGetMastervals(origvar); ncurmastervars = GCGoriginalVarGetNMastervars(origvar); for( j = 0; j < ncurmastervars; j++ ) { assert(SCIPvarIsTransformed(curmastervars[j])); for( k = 0; k < nmastervars; k++ ) if( mastervars[k] == curmastervars[j] ) { mastervals[k] += (curmastervals[j] * origvals[i]); break; } assert(k < nmastervars); } } } }
/** adds a solution value for a new variable in the transformed problem that has no original counterpart * a value can only be set if no value has been set for this variable before */ extern SCIP_RETCODE SCIPdebugAddSolVal( SCIP* scip, /**< SCIP data structure */ SCIP_VAR* var, /**< variable for which to add a value */ SCIP_Real val /**< solution value for variable */ ) { const char* varname; int i; assert(var != NULL); /* check if we are in the SCIP instance that we are debugging and not some different (subSCIP, auxiliary CIP, ...) */ if( !isSolutionInMip(scip->set) ) return SCIP_OKAY; if( SCIPvarIsOriginal(var) ) { SCIPerrorMessage("adding solution values for original variables is forbidden\n"); return SCIP_ERROR; } if( SCIPvarIsTransformedOrigvar(var) ) { SCIPerrorMessage("adding solution values for variable that are direct counterparts of original variables is forbidden\n"); return SCIP_ERROR; } /* allocate memory */ if( nsolvals >= solsize ) { solsize = MAX(2*solsize, nsolvals+1); SCIP_ALLOC( BMSreallocMemoryArray(&solnames, solsize) ); SCIP_ALLOC( BMSreallocMemoryArray(&solvals, solsize) ); } assert(nsolvals < solsize); /* store solution value in sorted list */ varname = SCIPvarGetName(var); for( i = nsolvals; i > 0 && strcmp(varname, solnames[i-1]) < 0; --i ) { solnames[i] = solnames[i-1]; solvals[i] = solvals[i-1]; } if( i > 0 && strcmp(varname, solnames[i-1]) == 0 ) { if( REALABS(solvals[i-1] - val) > 1e-9 ) { SCIPerrorMessage("already have stored different debugging solution value (%g) for variable <%s>, cannot store %g\n", solvals[i-1], varname, val); return SCIP_ERROR; } else { SCIPdebugMessage("already have stored debugging solution value %g for variable <%s>, do not store same value again\n", val, varname); for( ; i < nsolvals; ++i ) { solnames[i] = solnames[i+1]; solvals[i] = solvals[i+1]; } return SCIP_OKAY; } } /* insert new solution value */ SCIP_ALLOC( BMSduplicateMemoryArray(&solnames[i], varname, strlen(varname)+1) ); SCIPdebugMessage("add variable <%s>: value <%g>\n", solnames[i], val); solvals[i] = val; nsolvals++; /* update objective function value of debug solution */ debugsolval += solvals[i] * SCIPvarGetObj(var); SCIPdebugMessage("Debug Solution value is now %g.\n", debugsolval); return SCIP_OKAY; }