Skip to content

Commit

Permalink
fix connected components computation time (#645)
Browse files Browse the repository at this point in the history
closes #504
  • Loading branch information
ccoffrin committed Jan 11, 2020
1 parent 6100ee7 commit 124e9da
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ PowerModels.jl Change Log
- Added native DC Power Flow solver and AdmittanceMatrix data structures
- Added PTDF-based OPF problem specification
- Added iterative flow limit cut OPF solvers (#619)
- Improved connected components computation time (#504)
- Removed `Inf` bounds from variables (#630)
- Removal of unused functions in `solution.jl`: `get_solution`, `add_generator_power_setpoint`, `add_storage_setpoint`, `add_branch_flow_setpoint`, `add_dcline_flow_setpoint` (breaking) (#637)

Expand Down
34 changes: 19 additions & 15 deletions src/core/data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2419,30 +2419,32 @@ end
computes the connected components of the network graph
returns a set of sets of bus ids, each set is a connected component
"""
function calc_connected_components(data::Dict{String,<:Any}; edges=["branch", "dcline"])
function calc_connected_components(data::Dict{String,<:Any}; edges=["branch", "dcline", "switch"])
if InfrastructureModels.ismultinetwork(data)
Memento.error(_LOGGER, "connected_components does not yet support multinetwork data")
end

active_bus = Dict(x for x in data["bus"] if x.second["bus_type"] != 4)
active_bus_ids = Set{Int64}([bus["bus_i"] for (i,bus) in active_bus])

neighbors = Dict(i => [] for i in active_bus_ids)
for line_type in edges
for line in values(get(data, line_type, Dict()))
if get(line, "br_status", 1) != 0 && line["f_bus"] in active_bus_ids && line["t_bus"] in active_bus_ids
push!(neighbors[line["f_bus"]], line["t_bus"])
push!(neighbors[line["t_bus"]], line["f_bus"])
neighbors = Dict(i => Int[] for i in active_bus_ids)
for comp_type in edges
status_key = get(pm_component_status, comp_type, "status")
status_inactive = get(pm_component_status_inactive, comp_type, 0)
for edge in values(get(data, comp_type, Dict()))
if get(edge, status_key, 1) != status_inactive && edge["f_bus"] in active_bus_ids && edge["t_bus"] in active_bus_ids
push!(neighbors[edge["f_bus"]], edge["t_bus"])
push!(neighbors[edge["t_bus"]], edge["f_bus"])
end
end
end

component_lookup = Dict(i => Set{Int64}([i]) for i in active_bus_ids)
component_lookup = Dict(i => Set{Int}([i]) for i in active_bus_ids)
touched = Set{Int64}()

for i in active_bus_ids
if !(i in touched)
_dfs(i, neighbors, component_lookup, touched)
_cc_dfs(i, neighbors, component_lookup, touched)
end
end

Expand All @@ -2453,17 +2455,19 @@ end


"""
perModels DFS on a graph
DFS on a graph
"""
function _dfs(i, neighbors, component_lookup, touched)
function _cc_dfs(i, neighbors, component_lookup, touched)
push!(touched, i)
for j in neighbors[i]
if !(j in touched)
new_comp = union(component_lookup[i], component_lookup[j])
for k in new_comp
component_lookup[k] = new_comp
for k in component_lookup[j]
push!(component_lookup[i], k)
end
_dfs(j, neighbors, component_lookup, touched)
for k in component_lookup[j]
component_lookup[k] = component_lookup[i]
end
_cc_dfs(j, neighbors, component_lookup, touched)
end
end
end
Expand Down

0 comments on commit 124e9da

Please sign in to comment.