/**
 * data-structure-typed
 *
 * @author Pablo Zeng
 * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
 * @license MIT License
 */
import type { DijkstraResult, EntryCallback, GraphOptions, VertexKey } from '../../types';
import { IterableEntryBase } from '../base';
import { IGraph } from '../../interfaces';
export declare abstract class AbstractVertex<V = any> {
    key: VertexKey;
    value: V | undefined;
    protected constructor(key: VertexKey, value?: V);
}
export declare abstract class AbstractEdge<E = any> {
    value: E | undefined;
    weight: number;
    protected constructor(weight?: number, value?: E);
    protected _hashCode: string;
    get hashCode(): string;
}
/**
 * Abstract graph over vertices and edges.
 * @template V - Vertex value type.
 * @template E - Edge value type.
 * @template VO - Concrete vertex subclass (extends AbstractVertex<V>).
 * @template EO - Concrete edge subclass (extends AbstractEdge<E>).
 * @remarks Time O(1), Space O(1)
 * @example examples will be generated by unit test
 */
export declare abstract class AbstractGraph<V = any, E = any, VO extends AbstractVertex<V> = AbstractVertex<V>, EO extends AbstractEdge<E> = AbstractEdge<E>> extends IterableEntryBase<VertexKey, V | undefined> implements IGraph<V, E, VO, EO> {
    /**
     * Construct a graph with runtime defaults.
     * @param options - `GraphOptions<V>` in `options.graph` (e.g. `vertexValueInitializer`, `defaultEdgeWeight`).
     * @remarks Time O(1), Space O(1)
     */
    constructor(options?: Partial<Record<string, unknown>>);
    protected _options: GraphOptions<V>;
    get options(): Readonly<GraphOptions<V>>;
    protected _vertexMap: Map<VertexKey, VO>;
    get vertexMap(): Map<VertexKey, VO>;
    set vertexMap(v: Map<VertexKey, VO>);
    get size(): number;
    /**
     * Create a new vertex instance (implementation specific).
     * @param key - Vertex identifier.
     * @param value - Optional payload.
     * @returns Concrete vertex instance.
     * @remarks Time O(1), Space O(1)
     */
    abstract createVertex(key: VertexKey, value?: V): VO;
    /**
     * Create a new edge instance (implementation specific).
     * @param srcOrV1 - Source/endpoint A key.
     * @param destOrV2 - Destination/endpoint B key.
     * @param weight - Edge weight (defaults may apply).
     * @param value - Edge payload.
     * @returns Concrete edge instance.
     * @remarks Time O(1), Space O(1)
     */
    abstract createEdge(srcOrV1: VertexKey, destOrV2: VertexKey, weight?: number, value?: E): EO;
    /**
     * Delete an edge by instance.
     * @param edge - Edge instance.
     * @returns Removed edge or `undefined`.
     * @remarks Time O(1) avg, Space O(1)
     */
    abstract deleteEdge(edge: EO): EO | undefined;
    /**
     * Get an edge between two vertices if present.
     * @param srcOrKey - Source/endpoint A vertex or key.
     * @param destOrKey - Destination/endpoint B vertex or key.
     * @returns Edge instance or `undefined`.
     * @remarks Time O(1) avg, Space O(1)
     */
    abstract getEdge(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | undefined;
    /**
     * Degree of a vertex in this graph model.
     * @param vertexOrKey - Vertex or key.
     * @returns Non-negative integer degree.
     * @remarks Time O(1) avg, Space O(1)
     */
    abstract degreeOf(vertexOrKey: VO | VertexKey): number;
    /**
     * All edges in the graph (unique, order not guaranteed).
     * @returns Array of edges.
     * @remarks Time O(E), Space O(E)
     */
    abstract edgeSet(): EO[];
    /**
     * Incident edges of a vertex.
     * @param vertexOrKey - Vertex or key.
     * @returns Array of incident edges.
     * @remarks Time O(deg), Space O(deg)
     */
    abstract edgesOf(vertexOrKey: VO | VertexKey): EO[];
    /**
     * One-step neighbors of a vertex.
     * @param vertexOrKey - Vertex or key.
     * @returns Array of neighbor vertices.
     * @remarks Time O(deg), Space O(deg)
     */
    abstract getNeighbors(vertexOrKey: VO | VertexKey): VO[];
    /**
     * Resolve endpoints of an edge to vertex instances.
     * @param edge - Edge instance.
     * @returns `[v1, v2]` or `undefined` if missing.
     * @remarks Time O(1), Space O(1)
     */
    abstract getEndsOfEdge(edge: EO): [VO, VO] | undefined;
    /**
     * Get vertex instance by key.
     * @param vertexKey - Vertex key.
     * @returns Vertex instance or `undefined`.
     * @remarks Time O(1), Space O(1)
     */
    getVertex(vertexKey: VertexKey): VO | undefined;
    /**
     * Whether a vertex exists.
     * @param vertexOrKey - Vertex or key.
     * @returns `true` if present, otherwise `false`.
     * @remarks Time O(1) avg, Space O(1)
     */
    hasVertex(vertexOrKey: VO | VertexKey): boolean;
    addVertex(vertex: VO): boolean;
    addVertex(key: VertexKey, value?: V): boolean;
    /**
     * Type guard: check if a value is a valid vertex key.
     * @param potentialKey - Value to test.
     * @returns `true` if string/number; else `false`.
     * @remarks Time O(1), Space O(1)
     */
    isVertexKey(potentialKey: unknown): potentialKey is VertexKey;
    /**
     * Delete a vertex and its incident edges.
     * @param vertexOrKey - Vertex or key.
     * @returns `true` if removed; otherwise `false`.
     * @remarks Time O(deg), Space O(1)
     */
    abstract deleteVertex(vertexOrKey: VO | VertexKey): boolean;
    /**
     * Delete multiple vertices.
     * @param vertexMap - Array of vertices or keys.
     * @returns `true` if any vertex was removed.
     * @remarks Time O(sum(deg)), Space O(1)
     */
    removeManyVertices(vertexMap: VO[] | VertexKey[]): boolean;
    /**
     * Whether an edge exists between two vertices.
     * @param v1 - Endpoint A vertex or key.
     * @param v2 - Endpoint B vertex or key.
     * @returns `true` if present; otherwise `false`.
     * @remarks Time O(1) avg, Space O(1)
     */
    hasEdge(v1: VertexKey | VO, v2: VertexKey | VO): boolean;
    addEdge(edge: EO): boolean;
    addEdge(src: VO | VertexKey, dest: VO | VertexKey, weight?: number, value?: E): boolean;
    /**
     * Set the weight of an existing edge.
     * @param srcOrKey - Source vertex or key.
     * @param destOrKey - Destination vertex or key.
     * @param weight - New weight.
     * @returns `true` if updated; otherwise `false`.
     * @remarks Time O(1) avg, Space O(1)
     */
    setEdgeWeight(srcOrKey: VertexKey | VO, destOrKey: VertexKey | VO, weight: number): boolean;
    /**
     * Enumerate simple paths up to a limit.
     * @param v1 - Source vertex or key.
     * @param v2 - Destination vertex or key.
     * @param limit - Maximum number of paths to collect.
     * @returns Array of paths (each path is an array of vertices).
     * @remarks Time O(paths) worst-case exponential, Space O(V + paths)
     */
    getAllPathsBetween(v1: VO | VertexKey, v2: VO | VertexKey, limit?: number): VO[][];
    /**
     * Sum the weights along a vertex path.
     * @param path - Sequence of vertices.
     * @returns Path weight sum (0 if empty or edge missing).
     * @remarks Time O(L), Space O(1) where L is path length
     */
    getPathSumWeight(path: VO[]): number;
    /**
     * Minimum hops/weight between two vertices.
     * @param v1 - Source vertex or key.
     * @param v2 - Destination vertex or key.
     * @param isWeight - If `true`, compare by path weight; otherwise by hop count.
     * @returns Minimum cost or `undefined` if missing/unreachable.
     * @remarks Time O((V + E) log V) weighted / O(V + E) unweighted, Space O(V + E)
     */
    getMinCostBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean): number | undefined;
    /**
     * Minimum path (as vertex sequence) between two vertices.
     * @param v1 - Source vertex or key.
     * @param v2 - Destination vertex or key.
     * @param isWeight - If `true`, compare by path weight; otherwise by hop count.
     * @param isDFS - For weighted mode only: if `true`, brute-force all paths; if `false`, use Dijkstra.
     * @returns Vertex sequence, or `undefined`/empty when unreachable depending on branch.
     * @remarks Time O((V + E) log V) weighted / O(V + E) unweighted, Space O(V + E)
     */
    getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean, isDFS?: boolean): VO[] | undefined;
    /**
     * Dijkstra without heap (array-based selection).
     * @param src - Source vertex or key.
     * @param dest - Optional destination for early stop.
     * @param getMinDist - If `true`, compute global minimum distance.
     * @param genPaths - If `true`, also generate path arrays.
     * @returns Result bag or `undefined` if source missing.
     * @remarks Time O(V^2 + E), Space O(V + E)
     */
    dijkstraWithoutHeap(src: VO | VertexKey, dest?: VO | VertexKey | undefined, getMinDist?: boolean, genPaths?: boolean): DijkstraResult<VO> | undefined;
    dijkstra(src: VO | VertexKey, dest?: VO | VertexKey | undefined, getMinDist?: boolean, genPaths?: boolean): DijkstraResult<VO> | undefined;
    /**
     * Bellman-Ford single-source shortest paths with option to scan negative cycles.
     * @param src - Source vertex or key.
     * @param scanNegativeCycle - If `true`, also detect negative cycles.
     * @param getMin - If `true`, compute global minimum distance.
     * @param genPath - If `true`, generate path arrays via predecessor map.
     * @returns Result bag including distances, predecessors, and optional cycle flag.
     * @remarks Time O(V * E), Space O(V + E)
     */
    bellmanFord(src: VO | VertexKey, scanNegativeCycle?: boolean, getMin?: boolean, genPath?: boolean): {
        hasNegativeCycle: boolean | undefined;
        distMap: Map<VO, number>;
        preMap: Map<VO, VO>;
        paths: VO[][];
        min: number;
        minPath: VO[];
    };
    /**
     * Floyd–Warshall all-pairs shortest paths.
     * @returns `{ costs, predecessor }` matrices.
     * @remarks Time O(V^3), Space O(V^2)
     */
    floydWarshall(): {
        costs: number[][];
        predecessor: (VO | undefined)[][];
    };
    /**
     * Enumerate simple cycles (may be expensive).
     * @param isInclude2Cycle - If `true`, include 2-cycles when graph semantics allow.
     * @returns Array of cycles (each as array of vertex keys).
     * @remarks Time exponential in worst-case, Space O(V + E)
     */
    getCycles(isInclude2Cycle?: boolean): VertexKey[][];
    /**
     * Induced-subgraph filter: keep vertices where `predicate(key, value)` is true,
     * and only keep edges whose endpoints both survive.
     * @param predicate - `(key, value, index, self) => boolean`.
     * @param thisArg - Optional `this` for callback.
     * @returns A new graph of the same concrete class (`this` type).
     * @remarks Time O(V + E), Space O(V + E)
     */
    filter(predicate: EntryCallback<VertexKey, V | undefined, boolean>, thisArg?: unknown): this;
    /**
     * Preserve the old behavior: return filtered entries as an array.
     * @remarks Time O(V), Space O(V)
     */
    filterEntries(predicate: EntryCallback<VertexKey, V | undefined, boolean>, thisArg?: unknown): [VertexKey, V | undefined][];
    map<T>(callback: EntryCallback<VertexKey, V | undefined, T>, thisArg?: unknown): T[];
    /**
     * Create a deep clone of the graph with the same species.
     * @remarks Time O(V + E), Space O(V + E)
     */
    /**
     * Create a deep clone of the graph with the same species.
     * @returns A new graph of the same concrete class (`this` type).
     * @remarks Time O(V + E), Space O(V + E)
     */
    clone(): this;
    /**
     * Internal iterator over `[key, value]` entries in insertion order.
     * @returns Iterator of `[VertexKey, V | undefined]`.
     * @remarks Time O(V), Space O(1)
     */
    protected _getIterator(): IterableIterator<[VertexKey, V | undefined]>;
    /**
     * Capture configuration needed to reproduce the current graph.
     * Currently the graph has no runtime options, so we return an empty object.
     */
    /**
     * Capture configuration needed to reproduce the current graph.
     * @returns Options bag (opaque to callers).
     * @remarks Time O(1), Space O(1)
     */
    protected _snapshotOptions(): Record<string, unknown>;
    /**
     * Create an empty graph instance of the same concrete species (Directed/Undirected/etc).
     * @remarks Time O(1), Space O(1)
     */
    /**
     * Create an empty graph instance of the same concrete species.
     * @param _options - Snapshot options from `_snapshotOptions()`.
     * @returns A new empty graph instance of `this` type.
     * @remarks Time O(1), Space O(1)
     */
    protected _createInstance(_options?: Partial<Record<string, unknown>>): this;
    /**
     * Create a same-species graph populated with the given entries.
     * Also preserves edges between kept vertices from the source graph.
     * @remarks Time O(V + E), Space O(V + E)
     */
    /**
     * Create a same-species graph populated with entries; preserves edges among kept vertices.
     * @param iter - Optional entries to seed the new graph.
     * @param options - Snapshot options.
     * @returns A new graph of `this` type.
     * @remarks Time O(V + E), Space O(V + E)
     */
    protected _createLike(iter?: Iterable<[VertexKey, V | undefined]>, options?: Partial<Record<string, unknown>>): this;
    /**
     * Internal hook to attach an edge into adjacency structures.
     * @param edge - Edge instance.
     * @returns `true` if inserted; otherwise `false`.
     * @remarks Time O(1) avg, Space O(1)
     */
    protected abstract _addEdge(edge: EO): boolean;
    /**
     * Insert a pre-built vertex into the graph.
     * @param newVertex - Concrete vertex instance.
     * @returns `true` if inserted; `false` if key already exists.
     * @remarks Time O(1) avg, Space O(1)
     */
    protected _addVertex(newVertex: VO): boolean;
    /**
     * Resolve a vertex key or instance to the concrete vertex instance.
     * @param vertexOrKey - Vertex key or existing vertex.
     * @returns Vertex instance or `undefined`.
     * @remarks Time O(1), Space O(1)
     */
    protected _getVertex(vertexOrKey: VertexKey | VO): VO | undefined;
    /**
     * Resolve a vertex key from a key or vertex instance.
     * @param vertexOrKey - Vertex key or existing vertex.
     * @returns The vertex key.
     * @remarks Time O(1), Space O(1)
     */
    protected _getVertexKey(vertexOrKey: VO | VertexKey): VertexKey;
    /**
     * The edge connector string used in visual output.
     * Override in subclasses (e.g., '--' for undirected, '->' for directed).
     */
    protected get _edgeConnector(): string;
    /**
     * Generate a text-based visual representation of the graph.
     *
     * **Adjacency list format:**
     * ```
     * Graph (5 vertices, 6 edges):
     * A -> B (1), C (2)
     * B -> D (3)
     * C -> (no outgoing edges)
     * D -> A (1)
     * E (isolated)
     * ```
     *
     * @param options - Optional display settings.
     * @param options.showWeight - Whether to show edge weights (default: true).
     * @returns The visual string.
     */
    toVisual(options?: {
        showWeight?: boolean;
    }): string;
    /**
     * Generate DOT language representation for Graphviz.
     *
     * @param options - Optional display settings.
     * @param options.name - Graph name (default: 'G').
     * @param options.showWeight - Whether to label edges with weight (default: true).
     * @returns DOT format string.
     */
    toDot(options?: {
        name?: string;
        showWeight?: boolean;
    }): string;
    /**
     * Print the graph to console.
     * @param options - Display settings passed to `toVisual`.
     */
    print(options?: {
        showWeight?: boolean;
    }): void;
}
