UNPKG

@euriklis/ds-architect

Version:

`@euriklis/ds-architect` is a modular and extensible library that provides a rich ecosystem for graph and network-based data structures. Designed with both academic rigor and practical application in mind, this library offers powerful graph algorithms and

310 lines (309 loc) 12.8 kB
import type { Integer } from "../../../Types"; import { Node, Arc } from "../../DataNode/Models"; import { DynamicStack } from "../../Stack"; import { BaseGraph } from "./BaseGraph"; /** * Extension of `Graph` where nodes carry numeric values and edges have * weights, enabling common network metrics and algorithms. * The BaseNetwork is a generic Graph structure which requires three * types - the type of the data of the nodes, the type of the edge data and * the type of the state of the network. */ export declare class BaseNetwork<V, T, S = unknown> extends BaseGraph<Node<V>, Arc<T>, V, T, S> { /** * Function used to derive a numeric weight from an edge's stored weight and * data. Users can override this to globally change how algorithms interpret * edge weights. */ weightFn: (weight: number, data: T, g?: BaseNetwork<V, T, S>) => number; /** * Generate an n-dimensional cube network. */ static nCube(n: number): BaseNetwork<number[], null>; /** * Generate an Erdos-Renyi random network with * `n` nodes and connection probability `p`. */ static erdosRenyi(n: number, p: number): BaseNetwork<number, null>; /** * Generate a weighted Erdos-Renyi random network. Each created edge will * receive a weight produced by the optional `weightGenerator` function which * by default draws from `Math.random()`. */ static erdosRenyiWeighted(n: number, p: number, weightGenerator?: () => number): BaseNetwork<number, null>; /** * Generate a regular ring lattice where each node connects to `k` neighbours on each side. */ static ringLattice(n: number, k: number): BaseNetwork<number, null>; /** * Weighted variant of `ringLattice` where each edge weight is determined by * `weightGenerator` (defaults to `Math.random`). */ static ringLatticeWeighted(n: number, k: number, weightGenerator?: () => number): BaseNetwork<number, null>; /** * Generate a Watts–Strogatz small-world network. */ static wattsStrogatz(n: number, k: number, beta: number): BaseNetwork<number, null>; /** * Weighted Watts–Strogatz small-world network generator. It behaves like * `wattsStrogatz` but assigns a random weight (via `weightGenerator`) to each * created edge. */ static wattsStrogatzWeighted(n: number, k: number, beta: number, weightGenerator?: () => number): BaseNetwork<number, null>; /** Alias for `wattsStrogatzWeighted` using a more concise name. */ static smallWorldWeighted(n: number, k: number, beta: number, weightGenerator?: () => number): BaseNetwork<number, null>; /** * Generate a Barabasi–Albert preferential attachment network. * `n` is the number of nodes and `m` the number of edges added for each new node. */ static barabasiAlbert(n: number, m: number): BaseNetwork<number, null>; /** * Build a deterministic hierarchical scale-free network using the pseudofractal model. */ static hierarchical(iterations: number): BaseNetwork<number, null>; /** * Generate a network exhibiting the rich‑club phenomenon. */ static richClub(n: number, clubSize: number, p: number): BaseNetwork<number, null>; /** * Build an Apollonian network by recursively subdividing triangles. */ static apollonian(iterations: number): BaseNetwork<number, null>; /** * Generate a simple stochastic block model with equal intra and inter community probabilities. */ static stochasticBlockModel(blockSizes: number[], pIn: number, pOut: number): BaseNetwork<number, null>; /** * Generate a latent space/random dot-product network. */ static latentSpace(n: number, d: number, threshold: number): BaseNetwork<number[], null>; constructor({ nodes, edges, weightFn, }?: { nodes?: { name: string; data: V; value: number; }[]; edges?: { source: string; target: string; data: T; weight: number; }[]; weightFn?: (weight: number, data: T, g?: BaseNetwork<V, T, S>) => number; }); protected createNode({ name, data, options, }: { name: string; data: V; options: { value: number; [prop: string]: unknown; }; }): Node<V>; getNode(name: string): { name: string; data: V | null; value: number; } | null; inDegree(name: string): number; outDegree(name: string): number; get order(): Integer; get weightedOrder(): number; get size(): Integer; get weightedSize(): number; get density(): number; get weightedDensity(): number; get nodes(): { name: string; data: V | null; value: number; }[]; get edges(): { source: string; target: string; data: T; weight: number; }[]; /** * Generate the adjacency matrix using edge weights. If no edge exists between * two nodes the value is `0`. */ adjacencyMatrix(weightFn?: (weight: number, data: T, g?: BaseNetwork<V, T, S>) => number): number[][]; clone(): BaseNetwork<V, T, S>; BFSNode({ startingNode, callback, errorCallback, }: { startingNode: Node<V> | string; callback?: (node: Node<V> | null, g?: BaseNetwork<V, T, S>) => unknown; errorCallback?: (node: Node<V> | null, error: Error, g?: BaseNetwork<V, T, S>) => unknown; }): this; BFSNodeAsync({ startingNode, callback, errorCallback, }: { startingNode: Node<V> | string; callback?: (node: Node<V> | null, g?: BaseNetwork<V, T, S>) => Promise<unknown>; errorCallback?: (node: Node<V> | null, error: Error, g?: BaseNetwork<V, T, S>) => Promise<unknown>; }): Promise<this>; BFS({ callback, errorCallback, }?: { callback?: (node: Node<V> | null, g?: BaseNetwork<V, T, S>) => unknown; errorCallback?: (node: Node<V> | null, error: Error, g?: BaseNetwork<V, T, S>) => unknown; }): this; BFSAsync({ callback, errorCallback, }?: { callback?: (node: Node<V>, g?: BaseNetwork<V, T, S>) => Promise<unknown>; errorCallback?: (node: Node<V>, error: Error, g?: BaseNetwork<V, T, S>) => Promise<unknown>; }): Promise<this>; DFS({ callback, errorCallback, }: { callback?: (node: Node<V>, g?: BaseNetwork<V, T, S>) => unknown; errorCallback?: (node: Node<V>, error: Error, g?: BaseNetwork<V, T, S>) => unknown; }): this; DFSAsync({ callback, errorCallback, }?: { callback?: (node: Node<V>, g?: BaseNetwork<V, T, S>) => Promise<unknown>; errorCallback?: (node: Node<V>, error: Error, g?: BaseNetwork<V, T, S>) => Promise<unknown>; }): Promise<this>; DFSNode({ startingNode, callback, errorCallback, }: { startingNode: Node<V> | string; callback?: (node: Node<V>, g?: BaseNetwork<V, T, S>) => unknown; errorCallback?: (node: Node<V>, error: Error, g?: BaseNetwork<V, T, S>) => unknown; }): this; DFSNodeAsync({ startingNode, callback, errorCallback, }: { startingNode: Node<V> | string; callback?: (node: Node<V>, g?: BaseNetwork<V, T, S>) => Promise<unknown>; errorCallback?: (node: Node<V>, error: Error, g?: BaseNetwork<V, T, S>) => Promise<unknown>; }): Promise<this>; subgraph({ callback, }: { callback: (node: Node<V>, g: BaseNetwork<V, T, S>) => boolean; }): BaseNetwork<V, T, S>; union(n2: BaseNetwork<V, T, S>): BaseNetwork<V, T, S>; difference(n2: BaseNetwork<V, T, S>): BaseNetwork<V, T, S>; kronecker<V2, T2>(n2: BaseNetwork<V2, T2>): BaseNetwork<[V, V2], [T, T2], S>; /** * Check if the network is connected using an undirected traversal. */ isConnected(): boolean; /** * Find all bridges in the network treating edges as undirected. */ bridges(weightFn?: (weight: number, data: T, g?: BaseNetwork<V, T, S>) => number): { source: string; target: string; data: T; weight: number; }[]; /** * Find all directed bridges in the network. An edge (u,v) is a * directed bridge if there is no alternative directed path from * u to v when this edge is ignored. */ directedBridges(weightFn?: (weight: number, data: T, g?: BaseNetwork<V, T, S>) => number): { source: string; target: string; data: T; weight: number; }[]; /** * Return all simple cycles in the network. */ cycles(): string[][]; /** * Try to find a Hamiltonian cycle in the network. */ Hamiltonian(): string[] | null; /** * Return a topological ordering of the network nodes if acyclic. * Returns null if a cycle is detected. */ topologicalOrder(): string[] | null; /** * Find the shortest path between two nodes using * Dijkstra's algorithm. */ shortestPath({ start, end }: { start: string; end: string; }): { distance: number; path: string[]; pathStack: DynamicStack<string>; } | null; /** * Construct a minimum spanning tree using Kruskal's algorithm. */ minimumSpanningTree(): BaseNetwork<V, T, S>; /** * Construct a minimum spanning tree using Prim's algorithm. */ PRIM({ start, weightFn, }?: { start?: string; weightFn?: (weight: number, data: T, g?: BaseNetwork<V, T, S>) => number; }): BaseNetwork<V, T, S>; /** * Compute earliest finish times for nodes using a forward pass (PERT). */ PERT(weightFn?: (weight: number, data: T, g?: BaseNetwork<V, T, S>) => number): Map<string, number>; /** * Determine the critical path and its duration using CPM. */ CPM(weightFn?: (weight: number, data: T, g?: BaseNetwork<V, T, S>) => number): { duration: number; path: string[]; pathStack: DynamicStack<string>; }; /** * Determine if the network is bipartite. */ biGraph(): boolean; /** Weighted variant of `isErdosRenyi` using edge weights. */ isWeightedErdosRenyi(tolerance?: number): boolean; /** Weighted check if each node has degree roughly `2*k` as in a ring lattice. */ isWeightedRingLattice(k: number, tolerance?: number): boolean; /** Weighted heuristic for Barabasi-Albert style degree distribution. */ isWeightedBarabasiAlbert(): boolean; /** Weighted variant of rich-club detection. */ hasWeightedRichClub(threshold?: number): boolean; /** Weighted Watts–Strogatz detection using weighted clustering. */ isWeightedWattsStrogatz(k: number, betaTolerance?: number): boolean; /** Weighted hierarchical structure check. */ isWeightedHierarchical(): boolean; /** Weighted planar approximation for an Apollonian network. */ isWeightedApollonian(): boolean; /** Weighted community structure heuristic. */ isWeightedStochasticBlockModel(): boolean; /** Weighted latent space detection using edge weights. */ isWeightedLatentSpace(): boolean; private weightedDegree; private weightedNodeClusteringCoefficient; private weightedAverageClusteringCoefficient; /** * Heuristic check if the network resembles an Erdos-Renyi random network. */ isErdosRenyi(tolerance?: number): boolean; /** Check if each node has degree approximately `2*k` as in a ring lattice. */ isRingLattice(k: number): boolean; /** Rough test for a Barabasi–Albert style degree distribution. */ isBarabasiAlbert(): boolean; /** Check for rich‑club organisation using a simple coefficient. */ hasRichClub(threshold?: number): boolean; /** Estimate if the network originated from a Watts–Strogatz process. */ isWattsStrogatz(k: number, betaTolerance?: number): boolean; /** Basic check for a deterministic hierarchical structure. */ isHierarchical(): boolean; /** Quick planar check for an Apollonian network. */ isApollonian(): boolean; /** Rough heuristic detecting block community structure. */ isStochasticBlockModel(): boolean; /** Determine if node vectors likely generated edges via dot-product similarity. */ isLatentSpace(): boolean; private nodeClusteringCoefficient; private averageClusteringCoefficient; /** Serialize network to an object including weights. */ toJSON(): { nodes: { name: string; data: V | null; value: number; }[]; edges: { source: string; target: string; data: T; weight: number; }[]; state: S | null; }; [Symbol.iterator](): Iterator<Node<V>>; }