Available Strategies#
NPAP uses the Strategy Pattern to provide flexible, interchangeable algorithms for data loading, partitioning, and aggregation. This page provides an overview of all available strategies and how they work together.
The Workflow#
A typical NPAP workflow consists of four main steps:
flowchart LR
A[Load Data] --> B[Partition]
B --> C[Aggregate]
C --> D[Visualize]
style A fill:#2993B5,stroke:#1d6f8a,color:#fff
style B fill:#2993B5,stroke:#1d6f8a,color:#fff
style C fill:#2993B5,stroke:#1d6f8a,color:#fff
style D fill:#2993B5,stroke:#1d6f8a,color:#fff
Each step uses a specific strategy that can be swapped based on your requirements:
Step |
Manager |
Strategy Type |
Purpose |
|---|---|---|---|
Load Data |
InputDataManager |
DataLoadingStrategy |
Import network from various sources |
Partition |
PartitioningManager |
PartitioningStrategy |
Cluster nodes |
Aggregate |
AggregationManager |
Multiple strategies |
Reduce network by merging clusters |
Visualize |
(built-in) |
PlotStyle |
Create interactive maps |
Strategy Pattern Architecture#
flowchart TB
subgraph Managers
PAM[PartitionAggregatorManager]
IM[InputDataManager]
PM[PartitioningManager]
AM[AggregationManager]
end
subgraph Strategies
DL[Data Loading Strategies]
PS[Partitioning Strategies]
AS[Aggregation Strategies]
end
PAM --> IM
PAM --> PM
PAM --> AM
IM --> DL
PM --> PS
AM --> AS
style PAM fill:#2993B5,stroke:#1d6f8a,color:#fff
style IM fill:#2993B5,stroke:#1d6f8a,color:#fff
style PM fill:#2993B5,stroke:#1d6f8a,color:#fff
style AM fill:#2993B5,stroke:#1d6f8a,color:#fff
style DL fill:#0fad6b,stroke:#076b3f,color:#fff
style PS fill:#0fad6b,stroke:#076b3f,color:#fff
style AS fill:#0fad6b,stroke:#076b3f,color:#fff
The PartitionAggregatorManager is the main entry point that coordinates three specialized managers. Each manager handles its category of strategies.
How Strategies Work#
Strategies are registered with their managers and invoked by name:
import npap
manager = npap.PartitionAggregatorManager()
# Loading strategy is selected by name
manager.load_data("networkx_direct", graph=G)
# Partitioning strategy is selected by name
partition = manager.partition("geographical_kmeans", n_clusters=10)
# Aggregation uses profiles and modes
aggregated = manager.aggregate(mode=npap.AggregationMode.GEOGRAPHICAL)
Data Loading Strategies#
Strategy |
Description |
Required Parameters |
|---|---|---|
|
Load from existing NetworkX graph |
|
|
Load from separate CSV files |
|
|
Voltage-aware power system loader (CSV files) |
|
When to Use Each Loader#
Scenario |
Recommended Strategy |
|---|---|
Programmatic graph creation |
|
Standard CSV exports |
|
Multi-voltage power systems |
|
Networks with DC links |
|
See Data Loading for detailed documentation.
Partitioning Strategies#
NPAP provides four families of partitioning strategies:
Geographical Partitioning#
Clusters nodes based on geographic coordinates.
Strategy |
Algorithm |
Metric |
AC-Island Aware |
|---|---|---|---|
|
K-Means |
Euclidean |
No |
|
K-Medoids |
Euclidean |
Yes |
|
K-Medoids |
Haversine |
Yes |
|
DBSCAN |
Euclidean |
Yes |
|
DBSCAN |
Haversine |
Yes |
|
Agglomerative |
Euclidean |
Yes* |
|
HDBSCAN |
Euclidean |
Yes |
|
HDBSCAN |
Haversine |
Yes |
*Ward linkage does not support AC-island awareness
Required node attributes: lat, lon
Electrical Partitioning#
Clusters nodes based on electrical distance (PTDF approach) respecting AC islands.
Strategy |
Algorithm |
Description |
|---|---|---|
|
K-Means |
Provides arbitrary centroid node |
|
K-Medoids |
Provides existing centroid node (e.g. Kron-Reduction) |
Required attributes: Nodes: ac_island | Edges: x (reactance)
Voltage-Aware Geographical Partitioning#
Combines geographical distance with voltage level and AC island constraints.
Voltage-aware geographical partitioning provides two modes for defining the number of clusters per voltage level:
Standard: Only the total number of clusters over all voltage levels is specified by the user. The number of clusters per voltage level is set by the clustering algorithm.
Proportional: The user specifies the total number of clusters and the number of clusters per voltage level gets defined proportionally to the number of nodes at each voltage level.
Strategy |
Mode |
Description |
|---|---|---|
|
Standard |
K-Medoids with Euclidean distance |
|
Standard |
K-Medoids with Haversine distance |
|
Standard |
Agglomerative clustering |
|
Proportional |
Proportional by number of nodes |
|
Proportional |
Proportional by number of nodes |
|
Proportional |
Proportional by number of nodes |
Required node attributes: lat, lon, voltage, ac_island
Voltage-Aware Electrical Partitioning#
Combines electrical distance (PTDF approach) with voltage level and AC island constraints.
Strategy |
Algorithm |
|---|---|
|
K-Medoids |
|
Agglomerative |
Required attributes: Nodes: voltage, ac_island | Edges: x (reactance)
Choosing a Partitioning Strategy#
flowchart TD
A[Start] --> B{Multi-voltage?}
B -->|Yes| C{Need electrical distance?}
B -->|No| D{Need electrical distance?}
C -->|Yes| E[va_electrical_*]
C -->|No| F[va_geographical_*]
D -->|Yes| G[electrical_*]
D -->|No| H{AC islands?}
H -->|Yes| I[geographical_kmedoids_*]
H -->|No| L[geographical_*]
style A fill:#2993B5,stroke:#1d6f8a,color:#fff
style B fill:#FFBF00,stroke:#cc9900,color:#1e293b
style C fill:#FFBF00,stroke:#cc9900,color:#1e293b
style D fill:#FFBF00,stroke:#cc9900,color:#1e293b
style E fill:#0fad6b,stroke:#076b3f,color:#fff
style F fill:#0fad6b,stroke:#076b3f,color:#fff
style G fill:#0fad6b,stroke:#076b3f,color:#fff
style H fill:#FFBF00,stroke:#cc9900,color:#1e293b
style I fill:#0fad6b,stroke:#076b3f,color:#fff
style L fill:#0fad6b,stroke:#076b3f,color:#fff
See Partitioning for detailed documentation.
Aggregation Profiles#
Aggregation uses AggregationProfile that define how the network is reduced.
Aggregation Modes#
Predefined AggregationMode for common use cases:
Mode |
Topology |
Node Properties |
Edge Properties |
|---|---|---|---|
|
simple |
sum all |
sum all |
|
simple |
avg coords, sum loads |
sum capacity, equivalent reactance |
|
electrical |
Kron reduction |
Kron reduction |
|
user-defined |
user-defined |
user-defined |
from npap import AggregationMode
# Use a predefined mode
aggregated = manager.aggregate(mode=AggregationMode.GEOGRAPHICAL)
Custom Aggregation Profile#
For full control over the aggregation step, create an AggregationProfile:
from npap import AggregationProfile
profile = AggregationProfile(
topology_strategy="simple",
node_properties={
"lat": "average",
"lon": "average",
"load": "sum",
},
edge_properties={
"x": "equivalent_reactance",
"p_max": "sum",
},
default_node_strategy="sum",
default_edge_strategy="average"
)
aggregated = manager.aggregate(profile=profile)
Property Aggregation Strategies#
Node properties:
Strategy |
Formula |
Use Case |
|---|---|---|
|
\(\sum x_i\) |
Loads, generation |
|
\(\frac{1}{n}\sum x_i\) |
Coordinates, voltage |
|
\(x_1\) |
Names, categories |
Edge properties:
Strategy |
Formula |
Use Case |
|---|---|---|
|
\(\sum x_i\) |
Capacity |
|
\(\frac{1}{n}\sum x_i\) |
Length |
|
\(x_1\) |
Type, category |
|
\(\frac{1}{\sum \frac{1}{x_i}}\) |
Parallel impedances |
See Aggregation for detailed documentation.
Key Classes#
Main Entry Point#
Class |
Purpose |
|---|---|
Main orchestrator for all operations |
Data Structures#
Class |
Purpose |
|---|---|
Output of partitioning (cluster assignments) |
|
Configuration for network aggregation |
|
Predefined aggregation modes (enum) |
Managers#
Class |
Purpose |
|---|---|
|
Handles data loading strategies |
|
Handles partitioning strategies |
|
Handles aggregation strategies |
Enums#
Enum |
Values |
|---|---|
|
|
|
Exceptions#
Exception |
When Raised |
|---|---|
|
Base exception for all NPAP errors |
|
Problems loading input data |
|
Partitioning algorithm failures |
|
Aggregation failures |
|
Input validation failures |
|
Partition/graph mismatch |
Registering Custom Strategies#
You can extend NPAP by registering custom strategies:
# Custom data loader
manager.input_manager.register_strategy("my_loader", MyLoaderStrategy())
# Custom partitioning
manager.partitioning_manager.register_strategy("my_partitioner", MyPartitioningStrategy())
# Custom node/edge aggregation
manager.aggregation_manager.register_node_strategy("my_node_agg", MyNodeStrategy())
manager.aggregation_manager.register_edge_strategy("my_edge_agg", MyEdgeStrategy())
See Extending NPAP for detailed instructions on creating custom strategies.