/**
 * A {@link LayeringSimplex} that assigns layers to minimize the number of
 * dummy nodes.
 *
 * @packageDocumentation
 */
import type { Rank } from "../../graph";
import { type U } from "../../utils";
import type { Group, Layering } from ".";
/** simplex operator operators */
export interface LayeringSimplexOps<in N = never, in L = never> {
    /** rank operator */
    rank: Rank<N, L>;
    /** group operator */
    group: Group<N, L>;
}
/** the node datum of a set of operators */
export type OpsNodeDatum<Ops extends LayeringSimplexOps> = Ops extends LayeringSimplexOps<infer N, never> ? N : never;
/** the link datum of a set of operators */
export type OpsLinkDatum<Ops extends LayeringSimplexOps> = Ops extends LayeringSimplexOps<never, infer L> ? L : never;
/**
 * A layering operator that assigns layers to minimize the number of dummy
 * nodes (long edges) added to the layout.
 *
 * Computing this layering requires solving an integer linear program, which
 * may take a long time, although in practice is often quite fast. This is
 * often known as the network simplex layering from
 * {@link https://www.graphviz.org/Documentation/TSE93.pdf | Gansner et al.
 * [1993]}.
 *
 * Because this is solving a linear program, it is relatively easy to add new
 * constraints. The current implementation allows specifying {@link rank}
 * constraints that indicate which nodes should be above other nodes, or
 * {@link group} constraints that say which nodes should be on the same layer.
 * Note that adding these constraints can cause the optimization to become
 * ill-defined.
 *
 * Create with {@link layeringSimplex}.
 */
export interface LayeringSimplex<Ops extends LayeringSimplexOps = LayeringSimplexOps> extends Layering<OpsNodeDatum<Ops>, OpsLinkDatum<Ops>> {
    /**
     * set the {@link Rank}
     *
     * Any node with a rank assigned will have a second ordering enforcing
     * ordering of the ranks. Note, this can cause the simplex optimization to be
     * ill-defined, and may result in an error during layout.
     */
    rank<NewRank extends Rank>(newRank: NewRank): LayeringSimplex<U<Ops, "rank", NewRank>>;
    /**
     * get the current {@link Rank}
     */
    rank(): Ops["rank"];
    /**
     * set the {@link Group}
     *
     * Any node with a group assigned will have a second ordering enforcing all
     * nodes with the same group have the same layer.  Note, this can cause the
     * simplex optimization to be ill-defined, and may result in an error during
     * layout.
     */
    group<NewGroup extends Group>(newGroup: NewGroup): LayeringSimplex<U<Ops, "group", NewGroup>>;
    /**
     * get the current {@link Group}
     */
    group(): Ops["group"];
    /** @internal flag indicating that this is built in to d3dag and shouldn't error in specific instances */
    readonly d3dagBuiltin: true;
}
/** default simplex operator */
export type DefaultLayeringSimplex = LayeringSimplex<{
    /** unconstrained rank */
    rank: Rank<unknown, unknown>;
    /** unconstrained group */
    group: Group<unknown, unknown>;
}>;
/**
 * create a default {@link LayeringSimplex}
 *
 * This layering operator assigns layers to minimize the overall lengths of
 * edges. In most cases this strikes a good balance between compactness and
 * time to compute.
 *
 * The current implementation allows specifying {@link LayeringSimplex#rank}
 * constraints that indicate which nodes should be above other nodes, and
 * {@link LayeringSimplex#group} constraints that say which nodes should be on
 * the same layer.  Note that adding these constraints can cause the
 * optimization to become ill-defined.
 *
 * @example
 *
 * ```ts
 * const layout = sugiyama().layering(layeringSimplex());
 * ```
 */
export declare function layeringSimplex(...args: never[]): DefaultLayeringSimplex;
