Skip to content

Implement native multiplex routing with explicit layer-switching costs#960

Merged
SkBlaz merged 6 commits intomasterfrom
copilot/implement-routing-with-costs
Dec 29, 2025
Merged

Implement native multiplex routing with explicit layer-switching costs#960
SkBlaz merged 6 commits intomasterfrom
copilot/implement-routing-with-costs

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Dec 28, 2025

Adds native multiplex shortest-path routing that preserves layer semantics without flattening the network. Routes are computed over an implicit (node, layer) state space with configurable switching costs between layers.

Implementation

Core algorithm (py3plex/algorithms/routing/multiplex_paths.py):

  • Sparse Dijkstra over (node, layer) states with on-the-fly neighbor generation
  • Intralayer edges: (u, L) → (v, L) use original edge weights
  • Interlayer transitions: (u, L₁) → (u, L₂) use configurable switch costs
  • Multi-objective label-setting variant returns Pareto-optimal paths minimizing (distance, num_switches)

API:

from py3plex.algorithms.routing import multiplex_shortest_path

# Basic routing with switch cost
result = multiplex_shortest_path(net, 'A', 'C', switch_cost=1.0)
# Returns: {'path': [('A', 'work'), ('C', 'work')], 'total_distance': 0.5, ...}

# Asymmetric switch costs
switch_matrix = {('social', 'work'): 0.1, ('work', 'social'): 10.0}
result = multiplex_shortest_path(net, 'A', 'C', switch_cost_matrix=switch_matrix)

# Multi-objective Pareto optimization
result = multiplex_shortest_path(net, 'A', 'C', objective='pareto')
# Returns: {'paths': [...], 'objectives': [(dist, switches), ...]}

# Layer filtering
result = multiplex_shortest_path(net, 'A', 'C', allowed_layers=['L1', 'L2'])

Edge data handling: Fixed MultiGraph edge weight extraction to correctly handle NetworkX's {edge_key: {attr: value}} structure.

Testing

Unit Tests (32 tests in tests/algorithms/routing/test_multiplex_paths.py):

  • Switch cost scenarios (zero, high, asymmetric)
  • Pareto dominance correctness
  • Layer filtering and constraints
  • Edge cases (disconnected layers, self-routing)
  • Deterministic results verification
  • Additional corner cases (single-layer networks, minimal networks, isolated nodes, star topology, parallel edges)

Property Tests (20 tests in tests/property/test_multiplex_routing_properties.py):

  • Invariance properties (network non-mutation, determinism, layer semantics preservation)
  • Corner cases using Hypothesis (single-layer networks, single-node paths, empty filters)
  • Mathematical properties (optimality bounds, path length bounds, switch counting)
  • Pareto optimality verification (non-dominance, deterministic Pareto sets)
  • Error handling properties
  • Switch cost matrix behavior

Example script with 5 scenarios including multi-modal transportation network.

Total: 52 tests passing (32 unit + 20 property)

Version Update

Library version bumped to 1.1.0 (from 1.0.3) to reflect the new routing feature:

  • Updated pyproject.toml
  • Updated py3plex/__init__.py (__version__ and __api_version__)

Complexity

Time: O((|V|·|L|) log(|V|·|L|) + |E|) where |V| = nodes, |L| = layers, |E| = edges

State space grows as |V|·|L|, so performance scales with layer count.

Original prompt

This section details on the original issue you should resolve

<issue_title>spaths</issue_title>
<issue_description>You are extending the py3plex codebase.

TASK: Implement native multiplex shortest-path routing with explicit layer-switching costs and optional multi-objective optimization. DO NOT flatten the network.

CONTEXT:

  • py3plex already supports multilayer networks, supra representations, pipelines, and sparse operators.
  • Routing must preserve layer semantics and metadata.
  • Implementation must be sparse-first and scalable.

========================
CORE DESIGN

Represent routing states as (node_id, layer_id).

TODO:

  • Model intralayer edges as (u, L) -> (v, L) with original edge weight
  • Model interlayer transitions as (u, L1) -> (u, L2) with configurable switch cost
  • Avoid dense supra-adjacency materialization unless explicitly requested

========================
MODULE & API

Create module:
py3plex/algorithms/routing/multiplex_paths.py

Expose public API:

multiplex_shortest_path(
multilayer_network,
source,
target,
weight="weight",
switch_cost=1.0,
switch_cost_matrix=None,
allowed_layers=None,
objective="single", # "single" | "lexicographic" | "pareto"
method="dijkstra", # "dijkstra" | "astar" | "multiobjective"
return_path=True
)

TODO:

  • source/target are node IDs (layer-agnostic)
  • allow scalar or matrix-valued layer switching costs
  • support layer whitelisting/blacklisting
  • return full (node, layer) path with metadata

========================
ALGORITHMS

TODO:

  • Implement Dijkstra/A* over implicit (node, layer) state space
  • Track total distance and number of layer switches
  • Ensure sparse, on-the-fly neighbor generation
  • Support asymmetric switching costs

Multi-objective routing:
TODO:

  • Implement label-setting multi-objective Dijkstra
  • Objectives: (total_weight, num_switches)
  • Prune dominated labels
  • Return Pareto-optimal paths only

========================
SPECIAL ROUTING MODES

TODO:

  • Layer-constrained paths (must-use / must-avoid layers)
  • High switch cost should bias layer-pure paths
  • Zero switch cost must reduce to flattened shortest path

OPTIONAL:

  • Reliability-aware routing (maximize edge reliability via -log transform)

========================
INTEGRATION

TODO:

  • Add DSL operator: pipeline.route(...)
  • Ensure compatibility with pymnet-style visualization
  • Path output must be layer-aware and colorable

========================
TESTING

Create tests in:
tests/algorithms/routing/

TODO:

  • zero vs high switch cost behavior
  • asymmetric switch cost matrix
  • Pareto dominance correctness
  • disconnected layers
  • deterministic results

========================
DOCUMENTATION

TODO:

  • Add API docs
  • Add tutorial: "Multiplex Routing with Switching Costs"
  • Explain complexity and state-space growth

========================
CONSTRAINTS

  • No silent flattening
  • Preserve all layer semantics
  • Sparse-first implementation
  • Deterministic and reproducible
  • Follow existing py3plex code style</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits December 28, 2025 19:50
Co-authored-by: SkBlaz <10035780+SkBlaz@users.noreply.github.com>
Co-authored-by: SkBlaz <10035780+SkBlaz@users.noreply.github.com>
…ertions

Co-authored-by: SkBlaz <10035780+SkBlaz@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement multiplex shortest-path routing with layer-switching costs Implement native multiplex routing with explicit layer-switching costs Dec 28, 2025
Copilot AI requested a review from SkBlaz December 28, 2025 19:58
@SkBlaz
Copy link
Copy Markdown
Owner

SkBlaz commented Dec 29, 2025

@copilot missing concrete property tests for invariance + corner-cases (single layer) etc. No new md allowed

- Add 20 property-based tests using Hypothesis for invariance checking
- Test network non-mutation, determinism, layer semantics preservation
- Add corner cases: single layer, single edge, isolated nodes, star topology
- Test mathematical properties: optimality, bounds, switch counting
- Test Pareto optimality: non-dominance and determinism
- Add 8 additional unit tests for edge cases not previously covered
- All 52 tests passing (32 original + 20 property + 8 corner case)

Co-authored-by: SkBlaz <10035780+SkBlaz@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Dec 29, 2025

@copilot missing concrete property tests for invariance + corner-cases (single layer) etc. No new md allowed

Added comprehensive property tests and corner case tests in commit 7a00ec5:

Property Tests (20 tests in tests/property/test_multiplex_routing_properties.py):

  • Invariance: network non-mutation, determinism, layer semantics preservation
  • Corner cases: single layer networks, single node paths, empty filters
  • Mathematical properties: optimality bounds, path length bounds, switch counting
  • Pareto optimality: non-dominance verification, deterministic Pareto sets

Additional Corner Cases (8 tests added to existing file):

  • Single-layer networks with various switch costs
  • Minimal networks (single edge)
  • Isolated nodes, star topology, parallel edges
  • Empty switch cost matrix fallback

All 52 tests passing (32 original + 20 property + 8 corner case). No markdown files added.

@SkBlaz
Copy link
Copy Markdown
Owner

SkBlaz commented Dec 29, 2025

@copilot bump lib version

- Update version in pyproject.toml: 1.0.3 -> 1.1.0
- Update __version__ and __api_version__ in py3plex/__init__.py
- Minor version bump for new multiplex routing feature

Co-authored-by: SkBlaz <10035780+SkBlaz@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Dec 29, 2025

@copilot bump lib version

Version bumped to 1.1.0 in commit 410d6cc. Updated both pyproject.toml and py3plex/init.py.

@SkBlaz SkBlaz marked this pull request as ready for review December 29, 2025 12:32
@SkBlaz SkBlaz merged commit ed675ac into master Dec 29, 2025
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spaths

2 participants