Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,16 @@
package com.powsybl.openloadflow.graph;

import com.powsybl.commons.PowsyblException;
import org.jgrapht.Graph;
import org.jgrapht.graph.Pseudograph;

import java.util.*;
import java.util.stream.Collectors;

/**
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
*/
public abstract class AbstractGraphConnectivity<V, E> implements GraphConnectivity<V, E> {
public abstract class AbstractGraphConnectivity<V, E, G extends GraphModel<V, E>> implements GraphConnectivity<V, E> {

private final Graph<V, E> graph = new Pseudograph<>(null, null, false);
private final G graph;

private final Deque<ModificationsContext<V, E>> modificationsContexts = new ArrayDeque<>();

Expand All @@ -37,6 +35,10 @@ public abstract class AbstractGraphConnectivity<V, E> implements GraphConnectivi

protected abstract void updateComponents();

protected AbstractGraphConnectivity(G graph) {
this.graph = Objects.requireNonNull(graph);
}

@Override
public void addVertex(V vertex) {
Objects.requireNonNull(vertex);
Expand Down Expand Up @@ -147,7 +149,7 @@ protected Set<V> getNonConnectedVertices(V vertex) {
.flatMap(Collection::stream).collect(Collectors.toSet());
}

public Graph<V, E> getGraph() {
public G getGraph() {
return graph;
}

Expand Down
6 changes: 2 additions & 4 deletions src/main/java/com/powsybl/openloadflow/graph/EdgeAdd.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
*/
package com.powsybl.openloadflow.graph;

import org.jgrapht.Graph;

/**
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
*/
Expand All @@ -18,12 +16,12 @@ public EdgeAdd(V vertex1, V vertex2, E e) {
}

@Override
public void apply(Graph<V, E> graph) {
public void apply(GraphModel<V, E> graph) {
graph.addEdge(v1, v2, e);
}

@Override
public void undo(Graph<V, E> graph) {
public void undo(GraphModel<V, E> graph) {
graph.removeEdge(e);
}
}
Expand Down
6 changes: 2 additions & 4 deletions src/main/java/com/powsybl/openloadflow/graph/EdgeRemove.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
*/
package com.powsybl.openloadflow.graph;

import org.jgrapht.Graph;

/**
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
*/
Expand All @@ -19,12 +17,12 @@ public EdgeRemove(V vertex1, V vertex2, E e) {
}

@Override
public void apply(Graph<V, E> graph) {
public void apply(GraphModel<V, E> graph) {
graph.removeEdge(e);
}

@Override
public void undo(Graph<V, E> graph) {
public void undo(GraphModel<V, E> graph) {
graph.addEdge(v1, v2, e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
package com.powsybl.openloadflow.graph;

import com.powsybl.commons.PowsyblException;
import org.jgrapht.Graphs;

import java.util.*;
import java.util.stream.Collectors;
Expand All @@ -21,14 +20,18 @@
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
*/
public class EvenShiloachGraphDecrementalConnectivity<V, E> extends AbstractGraphConnectivity<V, E> {
public class EvenShiloachGraphDecrementalConnectivity<V, E> extends AbstractGraphConnectivity<V, E, JGraphTModel<V, E>> {

private Map<V, Integer> vertexToConnectedComponent;
private final List<Set<V>> newConnectedComponents = new ArrayList<>();

private final Map<V, LevelNeighbours> levelNeighboursMap = new HashMap<>();
private final Deque<Map<V, LevelNeighbours>> allSavedChangedLevels = new ArrayDeque<>();

public EvenShiloachGraphDecrementalConnectivity() {
super(new JGraphTModel<>());
}

@Override
protected void updateConnectivity(EdgeRemove<V, E> edgeRemoval) {
vertexToConnectedComponent = null;
Expand Down Expand Up @@ -93,9 +96,9 @@ public void startTemporaryChanges() {
}
super.startTemporaryChanges();
if (levelNeighboursMap.isEmpty()) {
Set<V> vertices = getGraph().vertexSet();
Set<V> vertices = getGraph().getVertices();
vertices.stream()
.max(Comparator.comparingInt(v -> getGraph().degreeOf(v)))
.max(Comparator.comparingInt(v -> getGraph().getNeighborEdgeCountOf(v)))
.ifPresent(v -> buildLevelNeighbours(Collections.singleton(v), 0));
if (vertices.size() > levelNeighboursMap.size()) {
// Checking if only one connected components at start
Expand All @@ -108,7 +111,7 @@ private void buildLevelNeighbours(Collection<V> level, int levelIndex) {
Collection<V> nextLevel = new HashSet<>();
for (V v : level) {
LevelNeighbours neighbours = levelNeighboursMap.computeIfAbsent(v, value -> new LevelNeighbours(levelIndex));
for (V adj : Graphs.neighborListOf(getGraph(), v)) {
for (V adj : getGraph().getNeighborVerticesOf(v)) {
LevelNeighbours adjNeighbours = levelNeighboursMap.computeIfAbsent(adj, value -> new LevelNeighbours(levelIndex + 1));
fillNeighbours(neighbours, adj, adjNeighbours.level);
}
Expand Down Expand Up @@ -156,7 +159,7 @@ public Set<V> getLargestConnectedComponent() {

private void computeMainConnectedComponent() {
if (componentSets.get(0) == null) {
Set<V> mainConnectedComponent = new HashSet<>(getGraph().vertexSet());
Set<V> mainConnectedComponent = new HashSet<>(getGraph().getVertices());
getSmallComponents().forEach(mainConnectedComponent::removeAll);
componentSets.set(0, mainConnectedComponent);
}
Expand Down Expand Up @@ -185,7 +188,7 @@ private void computeConnectivity() {
componentSets.addAll(newConnectedComponents);
int nbVerticesOut = newConnectedComponents.stream().mapToInt(Set::size).sum();
int maxNewComponentsSize = newConnectedComponents.stream().findFirst().map(Set::size).orElse(0);
Set<V> vertices = getGraph().vertexSet();
Set<V> vertices = getGraph().getVertices();
if (vertices.size() - nbVerticesOut < maxNewComponentsSize) {
// The initial connected component is smaller than some new connected components
// That is, the biggest connected component is among the new connected components list
Expand Down Expand Up @@ -269,7 +272,7 @@ private void initialStep() {

nLowLevel.upperLevel.remove(vertexBigLevel);
nBigLevel.lowerLevel.remove(vertexLowLevel);
if (nBigLevel.lowerLevel.isEmpty() && getGraph().getAllEdges(vertex1, vertex2).isEmpty()) {
if (nBigLevel.lowerLevel.isEmpty() && getGraph().getEdgesBetween(vertex1, vertex2).isEmpty()) {
this.verticesToUpdate.add(vertexBigLevel);
}
}
Expand Down Expand Up @@ -346,7 +349,7 @@ public Traverser(V vertexStart, Set<V> vertexEnd, Set<V> visitedVertices) {

public void next() {
V v = verticesToTraverse.removeLast();
for (V adj : Graphs.neighborListOf(getGraph(), v)) {
for (V adj : getGraph().getNeighborVerticesOf(v)) {
if (visitedVertices.add(adj)) {
verticesToTraverse.add(adj);
if (vertexEnd.contains(adj)) {
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/com/powsybl/openloadflow/graph/GraphModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2026, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.openloadflow.graph;

import java.util.List;
import java.util.Set;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public interface GraphModel<V, E> {

void addEdge(V v1, V v2, E e);

void removeEdge(E e);

void addVertex(V v);

void removeVertex(V v);

boolean containsVertex(V vertex);

boolean containsEdge(E edge);

V getEdgeSource(E edge);

V getEdgeTarget(E edge);

Set<E> getEdgesBetween(V vertex1, V vertex2);

Set<E> getEdges();

Set<E> getNeighborEdgesOf(V v);

int getNeighborEdgeCountOf(V v);

Set<V> getVertices();

List<V> getNeighborVerticesOf(V v);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@
*/
package com.powsybl.openloadflow.graph;

import org.jgrapht.Graph;

/**
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
*/
public interface GraphModification<V, E> {
void apply(Graph<V, E> graph);
void apply(GraphModel<V, E> graph);

void undo(Graph<V, E> graph);
void undo(GraphModel<V, E> graph);
}
93 changes: 93 additions & 0 deletions src/main/java/com/powsybl/openloadflow/graph/JGraphTModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* Copyright (c) 2026, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.openloadflow.graph;

import org.jgrapht.Graph;
import org.jgrapht.Graphs;
import org.jgrapht.graph.Pseudograph;

import java.util.List;
import java.util.Set;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
*/
public class JGraphTModel<V, E> implements GraphModel<V, E> {

private final Graph<V, E> graph = new Pseudograph<>(null, null, false);

@Override
public void addEdge(V v1, V v2, E e) {
graph.addEdge(v1, v2, e);
}

@Override
public void removeEdge(E e) {
graph.removeEdge(e);
}

@Override
public void addVertex(V v) {
graph.addVertex(v);
}

@Override
public void removeVertex(V v) {
graph.removeVertex(v);
}

@Override
public boolean containsVertex(V vertex) {
return graph.containsVertex(vertex);
}

@Override
public boolean containsEdge(E edge) {
return graph.containsEdge(edge);
}

@Override
public V getEdgeSource(E edge) {
return graph.getEdgeSource(edge);
}

@Override
public V getEdgeTarget(E edge) {
return graph.getEdgeTarget(edge);
}

@Override
public Set<E> getEdgesBetween(V vertex1, V vertex2) {
return graph.getAllEdges(vertex1, vertex2);
}

@Override
public Set<E> getEdges() {
return graph.edgeSet();
}

@Override
public Set<E> getNeighborEdgesOf(V v) {
return graph.edgesOf(v);
}

@Override
public int getNeighborEdgeCountOf(V v) {
return graph.degreeOf(v);
}

@Override
public Set<V> getVertices() {
return graph.vertexSet();
}

@Override
public List<V> getNeighborVerticesOf(V v) {
return Graphs.neighborListOf(graph, v);
}
}
Loading