Skip to content

Commit

Permalink
Fix the O(N^2) bug of passColName and passRowName
Browse files Browse the repository at this point in the history
  • Loading branch information
metab0t committed May 30, 2024
1 parent 4f54ef2 commit eeb92c0
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/lp_data/HStruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ struct HighsNameHash {
std::unordered_map<std::string, int> name2index;
void form(const std::vector<std::string>& name);
bool hasDuplicate(const std::vector<std::string>& name);
void update(int index, const std::string& old_name,
const std::string& new_name);
void clear();
};

Expand Down
4 changes: 2 additions & 2 deletions src/lp_data/Highs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,8 @@ HighsStatus Highs::passColName(const HighsInt col, const std::string& name) {
return HighsStatus::kError;
}
this->model_.lp_.col_names_.resize(num_col);
this->model_.lp_.col_hash_.update(col, this->model_.lp_.col_names_[col], name);
this->model_.lp_.col_names_[col] = name;
this->model_.lp_.col_hash_.clear();
return HighsStatus::kOk;
}

Expand All @@ -611,8 +611,8 @@ HighsStatus Highs::passRowName(const HighsInt row, const std::string& name) {
return HighsStatus::kError;
}
this->model_.lp_.row_names_.resize(num_row);
this->model_.lp_.row_hash_.update(row, this->model_.lp_.row_names_[row], name);
this->model_.lp_.row_names_[row] = name;
this->model_.lp_.row_hash_.clear();
return HighsStatus::kOk;
}

Expand Down
22 changes: 17 additions & 5 deletions src/lp_data/HighsLp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,14 +594,13 @@ void HighsNameHash::form(const std::vector<std::string>& name) {
size_t num_name = name.size();
this->clear();
for (size_t index = 0; index < num_name; index++) {
const bool duplicate = !this->name2index.emplace(name[index], index).second;
auto emplace_result = this->name2index.emplace(name[index], index);
const bool duplicate = !emplace_result.second;
if (duplicate) {
// Find the original and mark it as duplicate
auto search = this->name2index.find(name[index]);
assert(search != this->name2index.end());
auto& search = emplace_result.first;
assert(int(search->second) < int(this->name2index.size()));
this->name2index.erase(search);
this->name2index.insert({name[index], kHashIsDuplicate});
search->second = kHashIsDuplicate;
}
}
}
Expand All @@ -618,4 +617,17 @@ bool HighsNameHash::hasDuplicate(const std::vector<std::string>& name) {
return has_duplicate;
}

void HighsNameHash::update(int index, const std::string& old_name,
const std::string& new_name) {
this->name2index.erase(old_name);
auto emplace_result = this->name2index.emplace(new_name, index);
const bool duplicate = !emplace_result.second;
if (duplicate) {
// Find the original and mark it as duplicate
auto& search = emplace_result.first;
assert(int(search->second) < int(this->name2index.size()));
search->second = kHashIsDuplicate;
}
}

void HighsNameHash::clear() { this->name2index.clear(); }

0 comments on commit eeb92c0

Please sign in to comment.