-
Notifications
You must be signed in to change notification settings - Fork 118
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
Optimal Clustering of Substations for Topology Optimization Using the Louvain Algorithm #613
Comments
Hello, Thanks for this detailed description. First, let me start by saying that the examples code are simple examples, sufficient to get started and focus on the usage of ray / rllib. Also, the "dev_multiagent" branch is, as its name suggest still a development version and as such missing a whole lot of core features (required to make grid2op fully "multi agent"). TL;DRFirst, create another script that come up (with the method of your choice) with the ACTION_DOMAINS and OBSERVATION_DOMAINS. This script can be what you have made already. And save its output in your preferred format: csv, json, yaml, pickle etc. Once you have that, copy paste the example script, remove the "ACTION_DOMAINS" and "OBSERVATION_DOMAINS" definition (remove these global variable). And read back the "responsibility area" of each agent from the file that you saved (csv, json, yaml, pickle etc.) Long answerLet me then try to answer to some of your point (and maybe suggest a few solutions when I can think of some)
Yes, exactly. And this will always be the case in the current implementation. It's at the environment creation that you need to define what are the area operated by each agent. We have no solution right now to change dynamically the area operated by each agent after the environment is created.
I don't see why. I mean, of course there exists lots of grid clustering algorithms. But for me the process would be:
Following this process, if someone come up with a brilliant new way to cluster the grid, only the "step 1" above needs to be changed. And you can still use step 2 without anything. On the other hand, if you put inside grid2op some clustering algorithms you:
This consumes much more "man power" that to have an independant (of grid2op) process to come up with "action domains" and "observation domains" And this is clearly suboptimal (you might not have implemented the right clustering algorithms) and not flexible (you have to recode everything every time) |
So basically, I recommend something like this:
import grid2op
from lightsim2grid import LightSimBackend
from grid2op.multi_agent import ClusterUtils
ENV_NAME = "l2rpn_case14_sandbox"
env = grid2op.make(ENV_NAME, backend=LightSimBackend())
# Get ACTION_DOMAINS by clustering the substations
action_domains = ClusterUtils.cluster_substations(env)
# save it somewhere
action_domains.save("action_domain_{env_name}_{method_name}.json") Then get rid of all global variable some code here
ENV_NAME = "l2rpn_case14_sandbox"
DO_NOTHING_EPISODES = -1 # 200
ACTION_DOMAINS = {
'agent_0' : [0, 1, 2, 3, 4],
'agent_1' : [5, 6, 7, 8, 9, 10, 11, 12, 13]
}
OBSERVATION_DOMAINS = {"agent_0": [0, 1, 2, 3, 4, 5, 8, 6],
"agent_1": [5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 3]}
env_for_cls = grid2op.make(ENV_NAME,
action_class=PlayableAction,
backend=LightSimBackend())
# wrapper for gym env
class MAEnvWrapper(MAEnv):
def __init__(self, env_config=None):
super().__init__()
if env_config is None:
env_config = {}
env = grid2op.make(ENV_NAME,
action_class=PlayableAction,
backend=LightSimBackend())
action_domains = copy.deepcopy(ACTION_DOMAINS]
if "action_domains" in env_config:
action_domains = env_config["action_domains"]
observation_domains = copy.deepcopy(OBSERVATION_DOMAINS)
if "observation_domains" in env_config:
observation_domains = env_config["observation_domains"]
self.ma_env = MultiAgentEnv(env,
action_domains,
observation_domains)
some other code there too
if __name__ == "__main__":
again, some other code...
# load back your clustering
action_domain = json.load("action_domain_{env_name}_{method_name}.json")
observation_domain = json.load("observation_domain_{env_name}_{method_name}.json")
ray_ma_env = MAEnvWrapper(env_config={"action_domain": action_domain, "observation_domain": observation_domain})
again lots of other code This is somewhat what is done in the second example. |
And about clustering algorithm, I know (and I have worked a bit with him) that Nourredine Henka is working on grid clustering. He made some article with reproducible code available here https://github.com/rte-france/grid2op-milp-agent Nourredine now tries to come up with a clustering technique that scales (to real grid) and that is able to cluster "changing grid" so that you don't have to cluster the grid multiple times (ideally). The outcome should be a "robust" clustering. One of the core algorithm is infomap https://github.com/mapequation/infomap (not sure if this is the right repo). I'll see if Nourredine can add some precisions :-) |
Finally (now that I reached your implementation) you have tons of methods in grid2op to retrieve more or less information with a graph structure. You can have an example in the documentation, available here: https://grid2op.readthedocs.io/en/latest/grid_graph.html especially https://grid2op.readthedocs.io/en/latest/grid_graph.html#how-to-retrieve-the-graph-in-grid2op |
Hi @BDonnot , I have noted down our responses to each of your comments and concerns below. Looking forward to hearing your thoughts on this too.
|
Hello :-) Thanks for this super interesting work. I am working on a new grid2op release at the moment (for the "main" branch) and I will get back to you ASAP concerning this. I also saw the PR which is awesome, thanks :-) Again, I will try to have a look asap. As you mentioned it's super interesting to have a good default clustering. Which is of course way better than the "random" clustering proposed in the notebook. I'll keep you posted as soon as I have some time to work on it :-) |
Hi Benjamin,
Thank you for the feedback and glad to know that you think it's useful.
We are eagerly looking forward to your feedback on the PR and making the
contribution
…On Thu, Jul 4, 2024 at 7:20 PM Benjamin DONNOT ***@***.***> wrote:
Hello :-)
Thanks for this super interesting work. I am working on a new grid2op
release at the moment (for the "main" branch) and I will get back to you
ASAP concerning this.
I also saw the PR which is awesome, thanks :-)
Again, I will try to have a look asap. As you mentioned it's super
interesting to have a good default clustering. Which is of course way
better than the "random" clustering proposed in the notebook.
I'll keep you posted as soon as I have some time to work on it :-)
—
Reply to this email directly, view it on GitHub
<#613 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AVEO3ZUSW4OPVKZMGMCX72TZKVHKHAVCNFSM6AAAAABJIULS2WVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMBZGA2TAMBYHA>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Related Problem & Feature Request
Related Problem
In the official Grid2Op repo; a Multi-Agent Reinforcement Learning(MARL) example is currently being developed under the branch dev_multiagent .
In the current implementation, when creating the multi-agent environment a parameter called ACTION_DOMAINS is passed. This represents a dictionary that maps agent names to a list of substations they control. This approach aims to cluster the grid into smaller subgrids, each managed by an individual agent.
However, the primary issue with the current implementation is the lack of an optimal clustering methodology. Currently; as shown below, the agents and the substations they control are hard-coded (i.e. the substation ids are manually assigned by hand) for the l2rpn_case14_sandbox environment.
This hardcoded clustering approach is not ideal because:
Lack of Flexibility: Hardcoding limits the adaptability of the solution to different environments and scenarios.
Suboptimal Clustering: Without a systematic method for clustering, the current setup may not effectively optimize the agents' performance.
Feature Request
Due to the limitations of the current hardcoded clustering, our team @rootcodelabs is exploring methods to perform this clustering more optimally. Currently, manually assigning IDs to agents and clustering the grid does not adequately consider factors such as connectivity and the inherent relationships between different sections of the grid. This can lead to sub-optimal performance of the agent. To address this, we are developing dynamic and adaptable clustering algorithms that can better partition the grid. These algorithms will ensure optimal clustering, with subgrids sharing more internal connectivity. This approach aims to improve overall performance and scalability by creating clusters that are more logically connected and efficient.
By addressing this issue, we aim to strengthen the current MARL approach implemented within Grid2Op.
Solution: Clustering Substations using the Louvain Algorithm
To improve substation clustering in the Grid2Op environment, our team explored various graph clustering algorithms. The basis for exploring these algorithms lies in their ability to analyze and partition the grid based on connectivity. Graph clustering algorithms help identify communities or clusters within a network, ensuring that closely connected substations are grouped together. This results in more cohesive subgrids and optimized performance. After evaluating multiple such algorithms, we selected the Louvain Algorithm for its superior performance in detecting community structures within large networks and its ability to maximize modularity. This ensures that the resulting clusters have dense internal connections and sparser connections between them, making it particularly suitable for our needs.
Results & Comparison
Figure 1
Figure 2
The first image displays the episode reward over time for the MARL implementation in Grid2op but with hardcoded substation clusters (the original method) instead of using the Louvain algorithm for clustering.
The second image shows the episode reward over time for the same MARL solution implementation; but with the substation clustering performed using the Louvain algorithm (the proposed method).
Comparing the two images, a few key differences can be observed:
The maximum episode reward (orange line) in the second image (with Louvain clustering) reaches significantly higher
values, around 30,000, compared to the first image (with hardcoded clusters), where the maximum reward is around 4,000.
The mean episode reward (blue line) in the second image also tends to be higher, especially in the later episodes,
suggesting better overall performance with the Louvain clustering approach.
The minimum episode reward (green line) in the second image exhibits more fluctuations and occasional dips to lower
values compared to the first image, which may indicate greater variability or exploration in the learning process with
Louvain clustering.
These differences suggest that the Louvain algorithm for substation clustering, by identifying relevant community structures in the power grid network may enable the MARL solution to learn more effective strategies and achieve higher rewards in the Grid2op environment compared to the hardcoded substation clustering approach.
Solution Implementation
Sample Execution & Output
Output
Alternatives considered
Prior to finalizing the Clustering using the Louvain Algorithm, our team explored a couple of different alternatives.
Clustering substations using K-Means or DBSCAN algorithms - This was our initial approach and faced difficulties
when creating a matrix with substation-specific information that will be fed to the algorithm; due to lacking expert
domain knowledge in some power-grid properties. Although we managed to gather the required domain knowledge
through resource persons the clusters formed using K-Means had poor performance.
Dynamic Clustering: In this approach, we brainstormed the possibility of performing a dynamic clustering (Clustering
substations every time when agents deem it necessary to take an action) instead of static clustering at the initial stage.
We realized that dynamic clustering does not provide any specific advantage and will actually be more computationally
intensive.
Additional Context
Louvain Algorithm
Introduction
The Louvain Algorithm is a widely used method for detecting communities in large networks, renowned for its ability to identify high modularity communities efficiently. It is particularly useful for partitioning networks into clusters and is known for its scalability and rapid convergence. This algorithm is a type of greedy community detection algorithm and supports both weighted and unweighted graphs. One of its key features is the provision of hierarchical clustering, making it suitable for complex network analysis.
How the Louvain Algorithm Works
The Louvain Algorithm operates in an iterative manner, with each iteration consisting of two main phases aimed at maximizing modularity:
Phase 1: Change Community Memberships of Nodes (Partitioning)
In this phase, each node is assigned to different communities in a greedy manner. The objective is to maximize the
modularity gain, which measures the density of links inside communities compared to links between communities.
Nodes are moved between communities to find the configuration that results in the highest increase in modularity.
This process is repeated until no further improvement can be achieved.
Phase 2: Aggregate Identified Communities into Super-Nodes (Restructuring)
Once the optimal community structure is identified in Phase 1, these communities are aggregated into super-nodes,
effectively reducing the network's size.
The resulting network, with super-nodes, is then used as the input for the next iteration, where the algorithm repeats
the process of community assignment and aggregation.
This two-phase process continues iteratively, with each iteration refining the community structure until maximum modularity is achieved, and no further changes occur.
Advantages of the Louvain Algorithm
High Modularity Communities: Effectively identifies communities with high modularity, ensuring dense connections
within communities and sparse connections between them.
Scalable: Handles large networks efficiently, making it suitable for extensive datasets.
Greedy Community Detection: Uses a greedy approach for community assignment, ensuring rapid convergence.
Hierarchical Clustering: Provides a hierarchical clustering of the network, allowing for multi-level analysis.
Suitability of the Louvain algorithm for clustering substations
The Louvain algorithm is suitable for clustering substations in a power grid environment like grid2op for the following reasons:
Power Grid as a Network: A power grid can be represented as a network or graph, where substations are nodes, and
the transmission lines connecting them are edges. The Louvain algorithm is designed to identify communities or clusters
within such networks.
Electrical Connectivity: Substations that are electrically connected and have a high degree of interaction are more
likely to belong to the same cluster or community. The Louvain algorithm aims to maximize the modularity of the
network, which measures the density of connections within clusters compared to connections between clusters.
Hierarchical Clustering: The Louvain algorithm can detect hierarchical community structures, which is beneficial in
power grids where substations may be organized into different voltage levels or operational zones.
Scalability: The Louvain algorithm is known for its efficiency and scalability, making it suitable for clustering large-
scale power grids with numerous substations and transmission lines.
The text was updated successfully, but these errors were encountered: