NetworkProjection

class NetworkProjection<A : AgentLike> @JvmOverloads constructor(val context: AgentModel.Context<A>, val directed: Boolean = false, val name: String = "network") : Projection<A> (source)

A graph-based projection: agents are nodes, edges are typed relationships between pairs of agents. The third projection type in the agent layer's spatial abstraction (alongside ContinuousProjection and GridProjection).

Use this for relationships that aren't about position — friendship networks, contact graphs, communication links, organizational hierarchies. An agent can simultaneously be in a ContinuousProjection (its physical position) and a NetworkProjection (its social contacts) on the same AgentModel.Context, because both abstractions layer over the context's membership rather than owning it.

Directionality:

  • directed = false (default): connecting a to b is the same as connecting b to a. neighborsOf returns both ends. edges returns each logical edge once with (from, to) in the order in which it was originally connected.

  • directed = true: an edge has a direction. neighborsOf returns out-neighbors only; inNeighborsOf returns in-neighbors. To connect in both directions, call connect twice.

Weights:

  • Each edge has a weight (default 1.0). The unweighted graph algorithms (shortestPath, reachableFrom) ignore weights. User code can read weights via weightOf for its own purposes.

Lifecycle:

  • Nodes are implicit: any agent in the context can be referenced by connect / disconnect / neighborsOf; no separate "add node" step is needed.

  • When an agent leaves the context, onAgentLeft drops every edge incident to that agent.

Constructors

Link copied to clipboard
constructor(context: AgentModel.Context<A>, directed: Boolean = false, name: String = "network")

Types

Link copied to clipboard
object Defaults

Mutable global defaults for NetworkProjection edges.

Properties

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Number of distinct logical edges.

Link copied to clipboard
open override val name: String

Display name for diagnostics.

Link copied to clipboard

Number of nodes that currently have at least one incident edge. Note: an agent in the context with no edges is not counted here. Use AgentModel.Context.size for total membership.

Functions

Link copied to clipboard
fun asDistancesModel(nameOf: (A) -> String = { it.name }): DistancesModel

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.

Link copied to clipboard
fun connect(a: A, b: A, weight: Double = Defaults.edgeWeight)

Add an edge from a to b with the given weight. For undirected networks this is symmetric with connect(b, a, weight). Idempotent on the existence of the edge — calling connect twice updates the weight to the most recent value rather than creating a parallel edge.

Link copied to clipboard
fun degreeOf(agent: A): Int

Out-degree of agent (number of outgoing edges). For undirected networks this is identical to the total degree.

Link copied to clipboard
fun disconnect(a: A, b: A): Boolean

Remove the edge from a to b if one exists. For undirected networks this also removes b -> a. Returns true if any edge was actually removed.

Link copied to clipboard
fun edges(): List<Edge<A>>

All edges in the network. For undirected networks each logical edge appears once, in the original connect argument ordering.

Link copied to clipboard
fun hasEdge(a: A, b: A): Boolean

True if there is an edge from a to b.

Link copied to clipboard
fun inDegreeOf(agent: A): Int

In-degree of agent.

Link copied to clipboard
fun inNeighborsOf(agent: A): Set<A>

In-neighbors of agent: agents with an edge pointing to agent. For undirected networks this is identical to neighborsOf.

Link copied to clipboard
fun largestSCC(): Set<A>

The largest strongly connected component, by size. Ties are broken by the order SCCs are emitted by stronglyConnectedComponents (reverse topological order of the condensation). Returns an empty set if the network has no edges.

Link copied to clipboard
fun neighborsOf(agent: A): Set<A>

All neighbors of agent. For a directed network this is out-neighbors only; for undirected it's all incident agents. Returns an empty set for an agent with no edges.

Link copied to clipboard
open override fun onAgentLeft(agent: A)

Called by the AgentModel.Context when agent leaves. Default no-op — projections that track per-agent state (positions, edges) typically override to drop their bookkeeping for the departing agent.

Link copied to clipboard
fun reachableFrom(start: A): Set<A>

All agents reachable from start via outgoing edges (BFS). Includes start itself. For undirected networks this is the connected component containing start; for directed networks it's the forward-reachable set (also called "out-component"). To get a weakly-connected-component style answer for a directed graph, the caller can union with reachableFrom walking inEdges, or invert the graph.

Link copied to clipboard
fun sccContaining(agent: A): Set<A>?

The strongly connected component containing agent, or null if agent has no incident edges. Cheaper than calling stronglyConnectedComponents when only one SCC is needed, but still O(V + E) in the worst case.

Link copied to clipboard
fun shortestPath(from: A, to: A): List<A>?

Unweighted shortest path from from to to (BFS). Returns the list of agents on the path, including both endpoints. Returns null if to is not reachable. Returns a single-element list when from === to.

Link copied to clipboard
fun shortestPathLength(from: A, to: A): Int

Hop count of the shortest path from from to to, or -1 if unreachable. Returns 0 when from === to.

Link copied to clipboard

Compute the strongly connected components of this network. A strongly connected component (SCC) is a maximal set of agents where every agent can reach every other agent via directed paths.

Link copied to clipboard
fun weightedShortestPath(from: A, to: A, heuristic: (current: A, target: A) -> Double = { _, _ -> 0.0 }): WeightedPath<A>?

Weighted shortest path from from to to, respecting edge weights. Returns the path (including both endpoints) plus total weighted cost. Returns null if to is not reachable. A self-path (from === to) returns WeightedPath(listOf(from), 0.0).

Link copied to clipboard
fun weightedShortestPathLength(from: A, to: A, heuristic: (current: A, target: A) -> Double = { _, _ -> 0.0 }): Double

Convenience accessor: total weighted distance from from to to, or Double.POSITIVE_INFINITY if unreachable. Returns 0.0 for the self-path.

Link copied to clipboard
fun weightOf(a: A, b: A): Double?

Weight of the edge from a to b, or null if there is no such edge.