Skip to content

Commit 38fe918

Browse files
committed
close the container templates in cp::assignment to prevent hashing mismatches
1 parent d284a99 commit 38fe918

File tree

4 files changed

+240
-133
lines changed

4 files changed

+240
-133
lines changed

ortools/constraint_solver/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ cc_library(
219219
"@abseil-cpp//absl/base:core_headers",
220220
"@abseil-cpp//absl/base:log_severity",
221221
"@abseil-cpp//absl/base:nullability",
222-
"@abseil-cpp//absl/container:btree",
223222
"@abseil-cpp//absl/container:flat_hash_map",
224223
"@abseil-cpp//absl/container:flat_hash_set",
225224
"@abseil-cpp//absl/flags:flag",

ortools/constraint_solver/assignment.cc

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232

3333
namespace operations_research {
3434

35+
template class AssignmentContainer<IntVar, IntVarElement>;
36+
template class AssignmentContainer<IntervalVar, IntervalVarElement>;
37+
template class AssignmentContainer<SequenceVar, SequenceVarElement>;
38+
3539
// ----------------- Solutions ------------------------
3640

3741
// ----- IntVarElement -----
@@ -1018,6 +1022,184 @@ DecisionBuilder* Solver::MakeStoreAssignment(Assignment* assignment) {
10181022
return RevAlloc(new StoreAssignment(assignment));
10191023
}
10201024

1025+
bool Assignment::Empty() const {
1026+
return int_var_container_.Empty() && interval_var_container_.Empty() &&
1027+
sequence_var_container_.Empty();
1028+
}
1029+
1030+
int Assignment::Size() const {
1031+
return NumIntVars() + NumIntervalVars() + NumSequenceVars();
1032+
}
1033+
1034+
int Assignment::NumIntVars() const { return int_var_container_.Size(); }
1035+
1036+
int Assignment::NumIntervalVars() const {
1037+
return interval_var_container_.Size();
1038+
}
1039+
1040+
int Assignment::NumSequenceVars() const {
1041+
return sequence_var_container_.Size();
1042+
}
1043+
1044+
void Assignment::AddObjective(IntVar* const v) { AddObjectives({v}); }
1045+
1046+
void Assignment::AddObjectives(const std::vector<IntVar*>& vars) {
1047+
// Objective can only set once.
1048+
DCHECK(!HasObjective());
1049+
objective_elements_.reserve(vars.size());
1050+
for (IntVar* const var : vars) {
1051+
if (var != nullptr) {
1052+
objective_elements_.emplace_back(var);
1053+
}
1054+
}
1055+
}
1056+
1057+
void Assignment::ClearObjective() { objective_elements_.clear(); }
1058+
1059+
int Assignment::NumObjectives() const { return objective_elements_.size(); }
1060+
1061+
IntVar* Assignment::Objective() const { return ObjectiveFromIndex(0); }
1062+
1063+
IntVar* Assignment::ObjectiveFromIndex(int index) const {
1064+
return HasObjectiveFromIndex(index) ? objective_elements_[index].Var()
1065+
: nullptr;
1066+
}
1067+
1068+
bool Assignment::HasObjective() const { return !objective_elements_.empty(); }
1069+
1070+
bool Assignment::HasObjectiveFromIndex(int index) const {
1071+
return index < objective_elements_.size();
1072+
}
1073+
1074+
int64_t Assignment::ObjectiveMin() const { return ObjectiveMinFromIndex(0); }
1075+
1076+
int64_t Assignment::ObjectiveMax() const { return ObjectiveMaxFromIndex(0); }
1077+
1078+
int64_t Assignment::ObjectiveValue() const {
1079+
return ObjectiveValueFromIndex(0);
1080+
}
1081+
1082+
bool Assignment::ObjectiveBound() const { return ObjectiveBoundFromIndex(0); }
1083+
1084+
void Assignment::SetObjectiveMin(int64_t m) { SetObjectiveMinFromIndex(0, m); }
1085+
1086+
void Assignment::SetObjectiveMax(int64_t m) { SetObjectiveMaxFromIndex(0, m); }
1087+
1088+
void Assignment::SetObjectiveValue(int64_t value) {
1089+
SetObjectiveValueFromIndex(0, value);
1090+
}
1091+
1092+
void Assignment::SetObjectiveRange(int64_t l, int64_t u) {
1093+
SetObjectiveRangeFromIndex(0, l, u);
1094+
}
1095+
1096+
int64_t Assignment::ObjectiveMinFromIndex(int index) const {
1097+
return HasObjectiveFromIndex(index) ? objective_elements_[index].Min() : 0;
1098+
}
1099+
1100+
int64_t Assignment::ObjectiveMaxFromIndex(int index) const {
1101+
return HasObjectiveFromIndex(index) ? objective_elements_[index].Max() : 0;
1102+
}
1103+
1104+
int64_t Assignment::ObjectiveValueFromIndex(int index) const {
1105+
return HasObjectiveFromIndex(index) ? objective_elements_[index].Value() : 0;
1106+
}
1107+
1108+
bool Assignment::ObjectiveBoundFromIndex(int index) const {
1109+
return HasObjectiveFromIndex(index) ? objective_elements_[index].Bound()
1110+
: true;
1111+
}
1112+
1113+
void Assignment::SetObjectiveMinFromIndex(int index, int64_t m) {
1114+
if (HasObjectiveFromIndex(index)) {
1115+
objective_elements_[index].SetMin(m);
1116+
}
1117+
}
1118+
1119+
void Assignment::SetObjectiveMaxFromIndex(int index, int64_t m) {
1120+
if (HasObjectiveFromIndex(index)) {
1121+
objective_elements_[index].SetMax(m);
1122+
}
1123+
}
1124+
1125+
void Assignment::SetObjectiveValueFromIndex(int index, int64_t value) {
1126+
if (HasObjectiveFromIndex(index)) {
1127+
objective_elements_[index].SetValue(value);
1128+
}
1129+
}
1130+
1131+
void Assignment::SetObjectiveRangeFromIndex(int index, int64_t l, int64_t u) {
1132+
if (HasObjectiveFromIndex(index)) {
1133+
objective_elements_[index].SetRange(l, u);
1134+
}
1135+
}
1136+
1137+
void Assignment::ActivateObjective() { ActivateObjectiveFromIndex(0); }
1138+
1139+
void Assignment::DeactivateObjective() { DeactivateObjectiveFromIndex(0); }
1140+
1141+
bool Assignment::ActivatedObjective() const {
1142+
return ActivatedObjectiveFromIndex(0);
1143+
}
1144+
1145+
void Assignment::ActivateObjectiveFromIndex(int index) {
1146+
if (HasObjectiveFromIndex(index)) {
1147+
objective_elements_[index].Activate();
1148+
}
1149+
}
1150+
1151+
void Assignment::DeactivateObjectiveFromIndex(int index) {
1152+
if (HasObjectiveFromIndex(index)) {
1153+
objective_elements_[index].Deactivate();
1154+
}
1155+
}
1156+
1157+
bool Assignment::ActivatedObjectiveFromIndex(int index) const {
1158+
return HasObjectiveFromIndex(index) ? objective_elements_[index].Activated()
1159+
: true;
1160+
}
1161+
1162+
bool Assignment::AreAllElementsBound() const {
1163+
return int_var_container_.AreAllElementsBound() &&
1164+
interval_var_container_.AreAllElementsBound() &&
1165+
sequence_var_container_.AreAllElementsBound();
1166+
}
1167+
1168+
const Assignment::IntContainer& Assignment::IntVarContainer() const {
1169+
return int_var_container_;
1170+
}
1171+
1172+
Assignment::IntContainer* Assignment::MutableIntVarContainer() {
1173+
return &int_var_container_;
1174+
}
1175+
1176+
const Assignment::IntervalContainer& Assignment::IntervalVarContainer() const {
1177+
return interval_var_container_;
1178+
}
1179+
1180+
Assignment::IntervalContainer* Assignment::MutableIntervalVarContainer() {
1181+
return &interval_var_container_;
1182+
}
1183+
1184+
const Assignment::SequenceContainer& Assignment::SequenceVarContainer() const {
1185+
return sequence_var_container_;
1186+
}
1187+
1188+
Assignment::SequenceContainer* Assignment::MutableSequenceVarContainer() {
1189+
return &sequence_var_container_;
1190+
}
1191+
1192+
bool Assignment::operator==(const Assignment& assignment) const {
1193+
return int_var_container_ == assignment.int_var_container_ &&
1194+
interval_var_container_ == assignment.interval_var_container_ &&
1195+
sequence_var_container_ == assignment.sequence_var_container_ &&
1196+
objective_elements_ == assignment.objective_elements_;
1197+
}
1198+
1199+
bool Assignment::operator!=(const Assignment& assignment) const {
1200+
return !(*this == assignment);
1201+
}
1202+
10211203
std::ostream& operator<<(std::ostream& out, const Assignment& assignment) {
10221204
return out << assignment.DebugString();
10231205
}

0 commit comments

Comments
 (0)