Skip to content

Commit

Permalink
SOS: fail also if repeated 0 and any non-0 weight #163
Browse files Browse the repository at this point in the history
Gurobi requires unique weights

We ignore all-0 SOS
  • Loading branch information
glebbelov committed Mar 19, 2024
1 parent 9693f72 commit 89f0ba0
Showing 1 changed file with 21 additions and 8 deletions.
29 changes: 21 additions & 8 deletions include/mp/flat/problem_flattener.h
Original file line number Diff line number Diff line change
Expand Up @@ -925,21 +925,34 @@ class ProblemFlattener :
void ConvertSOSCollection(ArrayRef<int> sosno, ArrayRef<double> ref,
bool fAllSOS2) {
assert(sosno.size() == ref.size());
std::map< int, std::map< double, int > > sos_map;
std::map< int, // pair.first: N repeated zeros
std::pair< int, std::map< double, int > > > sos_map;
for (auto i=ref.size(); i--; )
if (sosno[i]) {
auto& sos_group = sos_map[sosno[i]];
if (!sos_group.insert( {ref[i], i} ).second
&& ref[i]) // weights 0 for all: redundant linearization
MP_RAISE("An SOS/SOS2 constraint has repeated weights");
if (!sos_group.second.insert( {ref[i], i} ).second) {
if (!fAllSOS2 || ref[i]) // weights 0 for all: redundant PL linearization
MP_RAISE(
fmt::format(
"SOS/SOS2 constraint {} has repeated weight {}",
sosno[i], ref[i]));
else
++sos_group.first;
}
}
for (const auto& group: sos_map) {
if (group.second.size()>1) {
if (group.second.second.size()
&& group.second.first
&& group.second.second.begin()->first) // key non-0
MP_RAISE(
fmt::format(
"SOS/SOS2 constraint {} has repeated 0 weights", group.first));
if (group.second.second.size()>1) {
std::vector<int> vars;
vars.reserve(group.second.size());
vars.reserve(group.second.second.size());
std::vector<double> weights;
weights.reserve(group.second.size());
for (const auto& wv: group.second) {
weights.reserve(group.second.second.size());
for (const auto& wv: group.second.second) {
weights.push_back(wv.first);
vars.push_back(wv.second);
}
Expand Down

0 comments on commit 89f0ba0

Please sign in to comment.