Source code for optiwindnet.baselines.utils

# SPDX-License-Identifier: MIT
# https://gitlab.windenergy.dtu.dk/TOPFARM/OptiWindNet/

import networkx as nx
import numpy as np
from scipy.spatial.distance import pdist, squareform


[docs] def length_matrix_single_depot_from_G( A: nx.Graph, *, scale: float, complete: bool = False ) -> tuple[np.ndarray, float]: """Edge length matrix for VRP-based solvers. It is assumed that the problem has been pre-scaled, such that multiplying all lengths by `scale` will place them within a numerically stable range. Length of return to depot from all nodes is set to 0 (i.e. Open-VRP). Order of nodes in the returned matrix is depot, clients (required by some VRP methods), which differs from optiwindnet order (i.e clients, depot). Args: A: Must contain graph attributes `R`, 'T', `VertexC` and 'd2roots'. A's edges must have the 'length' attribute. scale: Factor to multiply all lengths by. complete: make the full graph over A available (links not in A assumed direct) Returns: L, len_max: Matrix of lengths and maximum length value (below +inf). """ R, T, d2roots = (A.graph[k] for k in ('R', 'T', 'd2roots')) assert R == 1, 'ERROR: only single depot supported' if complete: # bring depot to before the clients VertexC = A.graph['VertexC'] VertexCmod = np.r_[VertexC[-R:], VertexC[:T]] Lv = pdist(VertexCmod) * scale len_max = Lv.max() L = squareform(Lv) else: # non-available edges will have infinite length L = np.full((T + R, T + R), np.inf) len_max = d2roots[:T, 0].max() * scale for u, v, length in A.edges(data='length'): scaled_length = length * scale L[u + 1, v + 1] = L[v + 1, u + 1] = scaled_length len_max = max(len_max, scaled_length) L[0, 1:] = d2roots[:T, 0] * scale # make return to depot always free L[:, 0] = 0.0 return L, len_max