When trying to get the optimal dual values of an LP solution, only SCIPgetDualSolVal seems to return the correct value:
#include <stdio.h>
#include <stdbool.h>
#include "scip/scip.h"
#include <scip/scipdefplugins.h>
int main() {
// Setup
SCIP* scip;
SCIP_CALL_ABORT(SCIPcreate(&scip));
SCIP_CALL_ABORT(SCIPincludeDefaultPlugins(scip));
// Turn off features that seem problematic in conjunction with duals:
// https://www.solveforum.com/forums/threads/solved-how-to-completeley-disable-presolve-in-scip.2697850/
// https://github.com/scipopt/PySCIPOpt/issues/136
SCIP_CALL_ABORT(SCIPsetPresolving(scip, SCIP_PARAMSETTING_OFF, true));
SCIP_CALL_ABORT(SCIPsetHeuristics(scip, SCIP_PARAMSETTING_OFF, true));
SCIP_CALL_ABORT(SCIPsetIntParam(scip, "propagating/maxrounds", 0));
SCIP_CALL_ABORT(SCIPcreateProb(scip, "primal", NULL, NULL,
NULL, NULL, NULL, NULL, NULL));
SCIP_CALL_ABORT(SCIPsetObjsense(scip, SCIP_OBJSENSE_MAXIMIZE));
// Variables: x,y positive reals
SCIP_VAR* x;
SCIP_CALL_ABORT(SCIPcreateVar(scip, &x, "x", 0.0, SCIPinfinity(scip), 1.0,
SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE,
NULL, NULL, NULL, NULL, NULL));
SCIP_CALL_ABORT(SCIPaddVar(scip, x));
SCIP_VAR* y;
SCIP_CALL_ABORT(SCIPcreateVar(scip, &y, "y", 0.0, SCIPinfinity(scip), 1.0,
SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE,
NULL, NULL, NULL, NULL, NULL));
SCIP_CALL_ABORT(SCIPaddVar(scip, y));
// Constraints
SCIP_CONS* c1;
SCIP_VAR* vars[2] = {x, y};
double coeffs1 [2] = {1.0, 2.0};
SCIP_CALL_ABORT(SCIPcreateConsLinear(scip, &c1, "c1",
2, vars, coeffs1, 21.0, 21.0, TRUE,
TRUE, TRUE, TRUE, TRUE, FALSE,
FALSE, FALSE, FALSE, FALSE));
SCIP_CALL_ABORT(SCIPaddCons(scip, c1));
SCIP_CONS* c2;
double coeffs2 [2] = {2.0, 1.0};
SCIP_CALL_ABORT(SCIPcreateConsLinear(scip, &c2, "c2",
2, vars, coeffs2, 24.0, 24.0, TRUE,
TRUE, TRUE, TRUE, TRUE, FALSE,
FALSE, FALSE, FALSE, FALSE));
SCIP_CALL_ABORT(SCIPaddCons(scip, c2));
// Solution
SCIP_CALL_ABORT(SCIPsolve(scip));
SCIP_SOL* sol = SCIPgetBestSol(scip);
if (sol == NULL){
printf("No solution found\n");
}
else {
double x_val = SCIPgetSolVal(scip, sol, x);
double y_val = SCIPgetSolVal(scip, sol, y);
double c1_dual = SCIPgetDualsolLinear(scip, c1);
double c2_dual = SCIPgetDualsolLinear(scip, c2);
double c1_dual2;
double c2_dual2;
SCIP_CALL_ABORT(SCIPgetDualSolVal(scip, c1, &c1_dual2, NULL));
SCIP_CALL_ABORT(SCIPgetDualSolVal(scip, c2, &c2_dual2, NULL));
printf("Solution: x = %f, y = %f\n", x_val, y_val);
printf("getDualsolLinear: c1_dual = %f, c2_dual = %f\n", c1_dual, c2_dual);
printf("getDualSolVal: c1_dual = %f, c2_dual = %f\n", c1_dual2, c2_dual2);
}
// Cleanup
SCIP_CALL_ABORT(SCIPreleaseVar(scip, &x));
SCIP_CALL_ABORT(SCIPreleaseVar(scip, &y));
SCIP_CALL_ABORT(SCIPreleaseCons(scip, &c1));
SCIP_CALL_ABORT(SCIPreleaseCons(scip, &c2));
SCIP_CALL_ABORT(SCIPfree(&scip));
return 0;
}
The optimal dual values of constraints c1 and c2 are both 1/3, so only getDualSolVal returns the right value but getDualsolLinear doesn't.
I'm using SCIP 8.0.3 installed using conda on a Linux machine.
More details: