Browse Source

Fixed minor bug MILP-based minimal command set generator. GurobiLpSolver is now able to deal with constraints involving several instances of the same variable.

Former-commit-id: 4b5575a886
tempestpy_adaptions
dehnert 11 years ago
parent
commit
33cce28df8
  1. 3
      src/counterexamples/MILPMinimalLabelSetGenerator.h
  2. 30
      src/solver/GurobiLpSolver.cpp

3
src/counterexamples/MILPMinimalLabelSetGenerator.h

@ -92,8 +92,7 @@ namespace storm {
StateInformation result;
result.relevantStates = storm::utility::graph::performProbGreater0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
result.relevantStates &= ~psiStates;
result.problematicStates = storm::utility::graph::performProbGreater0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
result.problematicStates.complement();
result.problematicStates = storm::utility::graph::performProb0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
result.problematicStates &= result.relevantStates;
LOG4CPLUS_DEBUG(logger, "Found " << phiStates.getNumberOfSetBits() << " filter states.");
LOG4CPLUS_DEBUG(logger, "Found " << psiStates.getNumberOfSetBits() << " target states.");

30
src/solver/GurobiLpSolver.cpp

@ -1,6 +1,7 @@
#include "src/solver/GurobiLpSolver.h"
#ifdef STORM_HAVE_GUROBI
#include <numeric>
#include "src/exceptions/InvalidStateException.h"
#include "src/settings/Settings.h"
@ -162,12 +163,29 @@ namespace storm {
throw storm::exceptions::InvalidStateException() << "Sizes of variable indices vector and coefficients vector do not match.";
}
// Convert the uint vector to ints for proper input to Gurobi.
std::vector<int> variablesCopy(variables.begin(), variables.end());
// As Gurobi requires the indices to be unique, we now explicitly make them unique. For this, we sort the
// variables and coefficients and eliminated duplicates by adding the coefficients.
// Copy the coefficients, because Gurobi does not take the coefficients as const values. The alternative to this would be casting
// away the constness, which gives undefined behaviour if Gurobi actually modifies something.
std::vector<double> coefficientsCopy(coefficients);
// We start by sorting both vectors.
std::vector<uint_fast64_t> sortedVariables(variables);
std::vector<double> sortedCoefficients(coefficients);
std::vector<uint_fast64_t> permutation(variables.size());
std::iota(permutation.begin(), permutation.end(), 0);
std::sort(permutation.begin(), permutation.end(), [&] (uint_fast64_t i, uint_fast64_t j) { return variables[i] < variables[j]; } );
std::transform(permutation.begin(), permutation.end(), sortedVariables.begin(), [&] (uint_fast64_t i) { return variables[i]; } );
std::transform(permutation.begin(), permutation.end(), sortedCoefficients.begin(), [&] (uint_fast64_t i) { return coefficients[i]; } );
// Now we perform the duplicate elimination step.
std::vector<int> uniqueVariables;
std::vector<double> uniqueCoefficients;
for (uint_fast64_t i = 0; i < sortedVariables.size(); ++i) {
if (!uniqueVariables.empty() && uniqueVariables.back() == sortedVariables[i]) {
uniqueCoefficients.back() += sortedCoefficients[i];
} else {
uniqueVariables.push_back(static_cast<int>(sortedVariables[i]));
uniqueCoefficients.push_back(sortedCoefficients[i]);
}
}
bool strictBound = boundType == LESS || boundType == GREATER;
char sense = boundType == LESS || boundType == LESS_EQUAL ? GRB_LESS_EQUAL : boundType == EQUAL ? GRB_EQUAL : GRB_GREATER_EQUAL;
@ -181,7 +199,7 @@ namespace storm {
rightHandSideValue += storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble();
}
}
int error = GRBaddconstr(model, variablesCopy.size(), variablesCopy.data(), coefficientsCopy.data(), sense, rightHandSideValue, name == "" ? nullptr : name.c_str());
int error = GRBaddconstr(model, uniqueVariables.size(), uniqueVariables.data(), uniqueCoefficients.data(), sense, rightHandSideValue, name == "" ? nullptr : name.c_str());
if (error) {
LOG4CPLUS_ERROR(logger, "Unable to assert Gurobi constraint (" << GRBgeterrormsg(env) << ", error code " << error << ").");

Loading…
Cancel
Save