asDistancesModel

fun asDistancesModel(nameOf: (A) -> String = { it.name }): DistancesModel(source)

Snapshot this network as a spatial-layer ksl.modeling.spatial.DistancesModel. The returned model contains one location per node currently in the network (any agent with at least one incident edge) and one distance entry per reachable ordered pair, computed via shortest path (Dijkstra) from each node.

Use case: a model that already uses agent-layer NetworkProjection for graph dynamics (Contract-Net, rumor diffusion, etc.) and also needs MovableResource or KSLProcess.transportWith semantics over the same topology. The adapter gives the entity-layer movement code a DistancesModel whose distances match the network's shortest-path costs.

Semantics:

  • All-pairs shortest path is precomputed up front, not lazy. Edges represent "one hop"; the DistancesModel entry for (a, c) when only a→b→c exists holds weight(a,b) + weight(b,c). This matches user intuition that the "distance" between two locations on a network is the routing distance, not infinity for non-adjacent nodes.

  • Snapshot semantics. The DistancesModel reflects the network at the moment of the call. Edges added or removed afterward are not reflected. Call again to rebuild.

  • Reachability only. Unreachable pairs are not added. DistancesModel.distance(unreachableA, unreachableB) throws.

  • Self-pairs use DistancesModel.defaultSameLocationDistance (default 0.0).

Lookup: every node gets a location named nameOf(node) (default node.name). After construction, retrieve the LocationIfc for an agent via distancesModel.location(nameOf(agent)). Node names must be distinct under nameOf; collisions throw.

Complexity: O(V × (V + E) log V) for the Dijkstra-per-source pass. For small networks (< 1000 nodes) this is a one-time hit at setup; for larger networks consider Floyd-Warshall (O(V³)) or partial precomputation.

Return

a populated ksl.modeling.spatial.DistancesModel

Parameters

nameOf

maps each node to a unique location name in the DistancesModel. Defaults to agent.name; provide a custom mapper if multiple agents share names.