-
Notifications
You must be signed in to change notification settings - Fork 63
Feature/minimum degree topology #440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
70 commits
Select commit
Hold shift + click to select a range
b387999
add sparse iteration to code base
mgovers bf05a4d
fix naming conventions
mgovers d970f42
different location
mgovers c507ba2
Merge remote-tracking branch 'origin/main' into feature/minimum-degre…
mgovers e97d594
use doctest instead of raw print
mgovers fbfe02d
remove deprecated
mgovers 3d5b74b
remove redundant vector
mgovers 6bb3c49
call minimum degree ordening from topology
mgovers 1a4b122
switch to new min degree algorithm
mgovers ef9ae29
attempt to fix permutations
mgovers 281486f
Merge branch 'main' into feature/minimum-degree-topology
mgovers 0d8fe10
more debug
mgovers d2c7514
fix last remaining issue
mgovers 15846b5
remove logging
mgovers e5a11ad
Merge branch 'feature/minimum-degree-topology' of https://github.com/…
mgovers 3b1c090
Merge branch 'main' into feature/minimum-degree-topology
mgovers 91257da
Merge remote-tracking branch 'origin/main' into feature/minimum-degre…
mgovers ed9f483
remove bad import
mgovers 632798e
major cleanup minimum degree ordening
mgovers 9de4a44
more cleanup
mgovers 6f3e9b5
more improvements
mgovers 0c0c667
minor
mgovers 903ad46
Merge branch 'main' into feature/minimum-degree-topology
mgovers 3110da1
Merge remote-tracking branch 'origin/main' into feature/minimum-degre…
mgovers f1e9923
update licenses of new files
mgovers 7c78624
fix clang tidy
mgovers 1e7dee2
Merge remote-tracking branch 'origin/main' into feature/minimum-degre…
mgovers ae8eea7
Merge branch 'main' into feature/minimum-degree-topology
Jerry-Jinfeng-Guo a4b1397
Merge branch 'main' into feature/minimum-degree-topology
Jerry-Jinfeng-Guo 0541217
Merge branch 'main' into feature/minimum-degree-topology
mgovers d2b198a
resolve code smells - part 1
mgovers 6c4e36c
resolve sonar cloud
mgovers d65b929
resolve sonar cloud
mgovers 0d64526
fix compilation
mgovers 8b03643
more efficient implementation
mgovers a3de21d
fix clang tidy
mgovers 2b38049
resolve sonar cloud
mgovers 6549be4
fix
mgovers a207fec
fix more code smells
mgovers f1000b7
fix
mgovers 4ad9084
clang-tidy
mgovers 01ea81e
rename sparse ordening -> sparse ordering
mgovers 30fc68e
Merge branch 'main' into feature/minimum-degree-topology
mgovers 5dd73a9
Merge branch 'main' into feature/minimum-degree-topology
mgovers c862036
Merge remote-tracking branch 'origin/main' into feature/minimum-degre…
mgovers 26ca1bf
remove test code
mgovers 9fd6e9f
[skip ci] minor
mgovers b105195
Merge branch 'main' into feature/minimum-degree-topology
mgovers 68aa35b
Merge remote-tracking branch 'origin/main' into feature/minimum-degre…
mgovers 9caf62d
minor fix
mgovers feb0755
fix benchmark
mgovers 14def66
Merge remote-tracking branch 'origin/main' into feature/minimum-degre…
mgovers 565907f
Merge branch 'main' into feature/minimum-degree-topology
mgovers f9d4216
capturing structured bindings will be supported starting Clang16
mgovers d6293a3
fix sonar cloud
mgovers 89a894b
Merge branch 'main' into feature/minimum-degree-topology
mgovers 0d6422a
Merge branch 'main' into feature/minimum-degree-topology
mgovers 62c2710
Merge branch 'main' into feature/minimum-degree-topology
mgovers 3303d10
Merge branch 'main' into feature/minimum-degree-topology
mgovers ce569a2
Merge branch 'main' into feature/minimum-degree-topology
mgovers 49b87a0
minor fix to the fictional grid
mgovers d38417b
remove TODO
mgovers a64e775
minor
mgovers b38e813
minor improvements
mgovers c978774
significant improvements to sparse ordering
mgovers 36afc79
major speedup in obtaining minimum degree vertex
mgovers 74b9d52
improve current most expensive step
mgovers 986a294
fix ci
mgovers cd55f73
fix
mgovers ca040d5
resolve sonar cloud
mgovers File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
221 changes: 221 additions & 0 deletions
221
power_grid_model_c/power_grid_model/include/power_grid_model/sparse_ordering.hpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,221 @@ | ||
| // SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org> | ||
| // | ||
| // SPDX-License-Identifier: MPL-2.0 | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "common/common.hpp" | ||
|
|
||
| #include <algorithm> | ||
| #include <cassert> | ||
| #include <compare> | ||
| #include <map> | ||
| #include <set> | ||
| #include <utility> | ||
| #include <vector> | ||
|
|
||
| namespace power_grid_model { | ||
|
|
||
| namespace detail { | ||
| class DegreeLookup { | ||
| public: | ||
| void set(Idx u, Idx degree) { | ||
| if (auto degree_it = vertex_to_degree.find(u); degree_it != vertex_to_degree.end()) { | ||
| remove_degree(u, degree_it->second); | ||
| degree_it->second = degree; | ||
| } else { | ||
| vertex_to_degree.try_emplace(u, degree); | ||
| } | ||
| degrees_to_vertex[degree].insert(u); | ||
| } | ||
|
|
||
| void erase(Idx u) { | ||
| auto vertex_it = vertex_to_degree.find(u); | ||
| if (vertex_it == vertex_to_degree.end()) { | ||
| return; | ||
| } | ||
| Idx const degree = vertex_it->second; | ||
| vertex_to_degree.erase(vertex_it); | ||
| remove_degree(u, degree); | ||
| } | ||
|
|
||
| friend auto min_element(DegreeLookup const& dgd); | ||
|
|
||
| private: | ||
| void remove_degree(Idx u, Idx degree) { | ||
| if (auto degree_it = degrees_to_vertex.find(degree); degree_it != degrees_to_vertex.end()) { | ||
| degree_it->second.erase(u); | ||
| if (degree_it->second.empty()) { | ||
| degrees_to_vertex.erase(degree_it); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| std::map<Idx, Idx> vertex_to_degree; | ||
| std::map<Idx, std::set<Idx>> degrees_to_vertex; | ||
| }; | ||
|
|
||
| inline auto min_element(DegreeLookup const& dgd) { | ||
| Idx const vertex = *dgd.degrees_to_vertex.begin()->second.begin(); | ||
| return dgd.vertex_to_degree.find(vertex); | ||
| } | ||
|
|
||
| inline void remove_element_degree(Idx u, DegreeLookup& dgd) { dgd.erase(u); } | ||
|
|
||
| inline void set_element_degree(Idx u, Idx degree, DegreeLookup& dgd) { dgd.set(u, degree); } | ||
|
|
||
| inline Idx num_adjacent(Idx const u, std::map<Idx, IdxVector> const& d) { | ||
| if (auto it = d.find(u); it != d.end()) { | ||
| return static_cast<Idx>(it->second.size()); | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| inline IdxVector const& adj(Idx const u, std::map<Idx, IdxVector> const& d) { return d.at(u); } | ||
|
|
||
| inline std::vector<std::pair<Idx, DegreeLookup>> comp_size_degrees_graph(std::map<Idx, IdxVector> const& d) { | ||
| DegreeLookup dd; | ||
| IdxVector v; | ||
|
|
||
| for (auto const& [k, adjacent] : d) { | ||
| v.push_back(k); | ||
| set_element_degree(k, static_cast<Idx>(adjacent.size()), dd); | ||
| } | ||
|
|
||
| return {{d.size(), dd}}; | ||
| } | ||
|
|
||
| inline std::map<Idx, IdxVector> make_clique(IdxVector& l) { | ||
| std::map<Idx, IdxVector> d; | ||
|
|
||
| for (Idx i = 0; i < static_cast<Idx>(l.size()); i++) { | ||
| IdxVector sl(l.size() - 1); | ||
| std::copy(l.begin(), l.begin() + i, sl.begin()); | ||
| std::copy(l.begin() + i + 1, l.end(), sl.begin() + i); | ||
| d[l[i]] = std::move(sl); | ||
| } | ||
|
|
||
| return d; | ||
| } | ||
|
|
||
| inline std::vector<std::pair<IdxVector, IdxVector>> check_indistguishable(Idx const u, | ||
| std::map<Idx, IdxVector> const& d) { | ||
| IdxVector rl; | ||
|
|
||
| auto l = adj(u, d); | ||
| auto lu = l; | ||
| lu.push_back(u); | ||
| std::ranges::sort(lu); | ||
|
|
||
| for (auto const& v : l) { | ||
| auto lv = adj(v, d); | ||
| lv.push_back(v); | ||
| std::ranges::sort(lv); | ||
| if (lu == lv) { | ||
| rl.push_back(v); | ||
| } | ||
| } | ||
|
|
||
| return {{l, rl}}; | ||
| } | ||
|
|
||
| inline bool in_graph(std::pair<Idx, Idx> const& e, std::map<Idx, IdxVector> const& d) { | ||
| if (auto edges_it = d.find(e.first); | ||
| edges_it != d.cend() && std::ranges::find(edges_it->second, e.second) != edges_it->second.cend()) { | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| inline IdxVector remove_vertices_update_degrees(Idx const u, std::map<Idx, IdxVector>& d, DegreeLookup& dgd, | ||
| std::vector<std::pair<Idx, Idx>>& fills) { | ||
| std::vector<std::pair<IdxVector, IdxVector>> nbsrl = check_indistguishable(u, d); | ||
| auto& [nbs, rl] = nbsrl[0]; | ||
| IdxVector alpha = rl; | ||
| std::map<Idx, IdxVector> dd; | ||
|
|
||
| rl.push_back(u); | ||
|
|
||
| for (auto uu : rl) { | ||
| if (uu != u) { | ||
| std::erase(nbs, uu); | ||
| } | ||
|
|
||
| remove_element_degree(uu, dgd); | ||
| IdxVector el; | ||
| for (auto e : d[uu]) { | ||
| auto& adjacents = d[e]; | ||
| std::erase(adjacents, uu); | ||
| if (adjacents.empty()) { | ||
| el.push_back(e); | ||
| } | ||
| } | ||
|
|
||
| el.push_back(uu); | ||
|
|
||
| for (auto const& it : el) { | ||
| d.erase(it); | ||
| } | ||
| } | ||
|
|
||
| dd = make_clique(nbs); | ||
|
|
||
| for (auto const& [k, adjacent] : dd) { | ||
| auto it = d.find(k); | ||
| for (Idx const e : adjacent) { | ||
| if (!in_graph(std::make_pair(k, e), d)) { | ||
| if (it == d.end()) { | ||
| std::tie(it, std::ignore) = d.try_emplace(k); | ||
| } | ||
| it->second.push_back(e); | ||
| d[e].push_back(k); | ||
| fills.emplace_back(k, e); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| for (auto const& e : nbs) { | ||
| set_element_degree(e, num_adjacent(e, d), dgd); | ||
| } | ||
|
|
||
| return alpha; | ||
| } | ||
| } // namespace detail | ||
|
|
||
| inline std::pair<IdxVector, std::vector<std::pair<Idx, Idx>>> minimum_degree_ordering(std::map<Idx, IdxVector> d) { | ||
| // make symmetric | ||
| for (auto const& [k, adjacent] : d) { | ||
| for (auto e : adjacent) { | ||
| d[e].push_back(k); | ||
| } | ||
| } | ||
| for (auto& [k, adjacent] : d) { | ||
| std::set<Idx> const unique_sorted_adjacent{adjacent.begin(), adjacent.end()}; | ||
| adjacent = IdxVector{unique_sorted_adjacent.begin(), unique_sorted_adjacent.end()}; | ||
| } | ||
|
|
||
| auto data = detail::comp_size_degrees_graph(d); | ||
| auto& [n, dgd] = data[0]; | ||
|
|
||
| IdxVector alpha; | ||
| std::vector<std::pair<Idx, Idx>> fills; | ||
|
|
||
| for (Idx k = 0; k < n; ++k) { | ||
| Idx const u = get<0>(*detail::min_element(dgd)); | ||
| alpha.push_back(u); | ||
| if (d.size() == 2) { | ||
| assert(d.begin()->second.size() == 1); | ||
|
|
||
| Idx const from = d.begin()->first; | ||
| Idx const to = d.begin()->second[0]; | ||
| alpha.push_back(alpha.back() == from ? to : from); | ||
| return {alpha, fills}; | ||
| } | ||
| std::ranges::copy(detail::remove_vertices_update_degrees(u, d, dgd, fills), std::back_inserter(alpha)); | ||
| if (d.empty()) { | ||
| return {alpha, fills}; | ||
| } | ||
| } | ||
| return {alpha, fills}; | ||
| } | ||
| } // namespace power_grid_model | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.