我设置了 MPSolver 的回调
问题是它会在更大的输入上运行,并且要求绝对最优是不合理的,所以我仍然需要从回调中获取解决方案。
/*
IsSolution:1, X1=0, X2=0, X3=1000
Result:0, X1=1000, X2=0, X3=0
*/
#include "ortools/linear_solver/linear_solver.h"
#include <memory>
#include <iostream>
#include <stdio.h>
using namespace operations_research;
void RangeHelper(MPConstraint* c) {}
template<class ...T>
void RangeHelper(MPConstraint* c, MPVariable* x0, double c0, T... TT) {
c->SetCoefficient(x0, c0);
RangeHelper(c, TT...);
}
template<class ...T>
static MPConstraint* Ranger(MPSolver& solver, MPVariable* condition, double RangeL, T... TT) {
MPConstraint* c = solver.MakeRowConstraint(RangeL, solver.infinity());
c->SetCoefficient(condition, 1e20);
RangeHelper(c, TT...);
return c;
}
struct CMPCBK : MPCallback {
const MPVariable* X1, * X2, * X3;
CMPCBK(const MPVariable* X1, const MPVariable* X2, const MPVariable* X3) :
X1(X1), X2(X2), X3(X3), MPCallback(0, 0) {}
void RunCallback(MPCallbackContext* r) {
if (r->Event() == MPCallbackEvent::kMipSolution) {
printf("IsSolution:%d, X1 = %f, X2 = %f, X3 = %f\n",
r->CanQueryVariableValues(), r->VariableValue(X1), r->VariableValue(X2), r->VariableValue(X3));
}
}
};
int main() {
std::unique_ptr<MPSolver> solver(MPSolver::CreateSolver("SCIP"));
const double INF = solver->infinity();
MPVariable* X1 = solver->MakeNumVar(-INF, INF, "a");
MPVariable* X2 = solver->MakeNumVar(0, INF, "b");
MPConstraint* C1 = solver->MakeRowConstraint(0, 0);
MPVariable* X3 = solver->MakeIntVar(0, 1, "c");
Ranger(*solver, X3, 1000, X2, -1, X1, 1);
C1->SetCoefficient(X3, 1);
MPObjective* obj = solver->MutableObjective();
obj->SetCoefficient(X1, 1);
obj->SetMinimization();
CMPCBK mpcbk(X1, X2, X3);
solver->SetCallback(&mpcbk);
printf("Result:%d, ", solver->Solve());
printf("X1 = %f, X2 = %f, X3 = %f\n",
X1->solution_value(), X2->solution_value(), X3->solution_value());
}