export { Constant } from './constant/index.mjs';
export { Delay } from './delay/index.mjs';
export { Generate } from './generate/index.mjs';
export { Is } from './is/index.mjs';
export { FromArray } from './array/index.mjs';
export { FromNum } from './number/index.mjs';
export { FromObject } from './object/index.mjs';
export { FromString } from './string/index.mjs';
export { FormatOptions, FromTime, ObjectifiedDate, cDate } from './time/index.mjs';
export { FromVector, VectorObject, createVector } from './vector/index.mjs';
export { Gacha } from './gacha/index.mjs';
export { FeatureExtractor, KMeans, KMeansND, KMeansNDOptions, NDCluster } from './kmeans/index.mjs';
export { Color, Logger } from './logger/index.mjs';
export { Obfuscator, ObfuscatorOptions, ObfuscatorVersion, obfuscator } from './obfuscator/index.mjs';
export { Sha256 } from './sha256/index.mjs';
export { Locale, Validator, validator } from './validator/index.mjs';

/** A single candidate solution. */
interface Individual<G> {
    /** The gene sequence representing a solution. */
    genes: G[];
    /** Fitness score. Higher values = more fit (by convention). */
    fitness: number;
}
interface GARunOptions<G> {
    /** Initial population (already evaluated). */
    population: Individual<G>[];
    /**
     * Returns a fitness score for a gene sequence.
     * Higher = more fit. Called every generation.
     */
    fitnessFn: (genes: G[]) => number;
    /** Number of generations to run. */
    generations: number;
    /** Probability [0, 1] that each gene mutates. Default: 0.01 */
    mutationRate?: number;
    /**
     * Called when a gene should be replaced by a random one.
     * Required for the `random` mutation strategy.
     */
    geneFactory?: () => G;
    /** Selection strategy. Default: `'tournament'` */
    selection?: SelectionStrategy;
    /** Tournament size when using tournament selection. Default: 3 */
    tournamentSize?: number;
    /** Crossover strategy. Default: `'single-point'` */
    crossover?: CrossoverStrategy;
    /**
     * Fraction of the population that advances to the next generation unchanged.
     * Default: 0.1  (10% elitism)
     */
    elitismRate?: number;
    /**
     * Called after every generation with the current best individual and
     * generation index (0-based). Useful for logging progress.
     */
    onGeneration?: (best: Individual<G>, generation: number) => void;
}
interface GAResult<G> {
    /** Best individual found across all generations. */
    best: Individual<G>;
    /** Final population (sorted best-first). */
    finalPopulation: Individual<G>[];
    /** Best fitness score of each generation. */
    history: number[];
}
type SelectionStrategy = 'tournament' | 'roulette' | 'rank';
type CrossoverStrategy = 'single-point' | 'two-point' | 'uniform';
/**
 * Creates a population of random individuals.
 *
 * @param size Number of individuals.
 * @param length Number of genes per individual.
 * @param geneFactory Returns a single random gene value.
 *
 * @example
 * // Binary-encoded population
 * const pop = GA.createPopulation(50, 20, () => Math.random() < 0.5 ? 0 : 1);
 *
 * @example
 * // Real-valued population in [-5, 5]
 * const pop = GA.createPopulation(100, 10, () => Math.random() * 10 - 5);
 */
declare function createPopulation<G>(size: number, length: number, geneFactory: () => G): Individual<G>[];
/**
 * Evaluates and assigns fitness to every individual in the population.
 * Returns a new array (does not mutate the original).
 *
 * @example
 * const evaluated = GA.evaluate(pop, (genes) => genes.filter(Boolean).length);
 */
declare function evaluate<G>(population: Individual<G>[], fitnessFn: (genes: G[]) => number): Individual<G>[];
/**
 * Sorts the population by fitness.
 * @param order `'desc'` (default) = best first, `'asc'` = worst first.
 */
declare function sortPopulation<G>(population: Individual<G>[], order?: 'asc' | 'desc'): Individual<G>[];
/**
 * Returns the top-n fittest individuals (best-first).
 */
declare function best<G>(population: Individual<G>[], n?: number): Individual<G>[];
/**
 * Tournament selection: picks `tournamentSize` random individuals and returns
 * the fittest among them.
 */
declare function tournamentSelect<G>(population: Individual<G>[], tournamentSize?: number): Individual<G>;
/**
 * Fitness-proportionate (roulette wheel) selection.
 * Requires all fitness values to be non-negative.
 */
declare function rouletteSelect<G>(population: Individual<G>[]): Individual<G>;
/**
 * Rank-based selection: selection probability is proportional to rank, not
 * raw fitness. Helps avoid premature convergence.
 */
declare function rankSelect<G>(population: Individual<G>[]): Individual<G>;
/**
 * Single-point crossover: splits both parents at a random point and swaps tails.
 */
declare function singlePointCrossover<G>(p1: Individual<G>, p2: Individual<G>): [Individual<G>, Individual<G>];
/**
 * Two-point crossover: swaps the segment between two random cut points.
 */
declare function twoPointCrossover<G>(p1: Individual<G>, p2: Individual<G>): [Individual<G>, Individual<G>];
/**
 * Uniform crossover: each gene is independently taken from either parent
 * with equal probability.
 * @param mixRate Probability of taking each gene from parent2 (default 0.5).
 */
declare function uniformCrossover<G>(p1: Individual<G>, p2: Individual<G>, mixRate?: number): [Individual<G>, Individual<G>];
/**
 * Bit-flip mutation for boolean/binary-encoded individuals.
 * Each gene is flipped with probability `rate`.
 */
declare function bitFlipMutate(individual: Individual<number | boolean>, rate: number): Individual<number | boolean>;
/**
 * Swap mutation: randomly selects two positions and swaps them.
 * Applied once if `Math.random() < rate`.
 * Useful for permutation-encoded problems (TSP, scheduling).
 */
declare function swapMutate<G>(individual: Individual<G>, rate: number): Individual<G>;
/**
 * Inversion mutation: reverses a random sub-sequence of genes.
 * Applied once if `Math.random() < rate`.
 */
declare function inversionMutate<G>(individual: Individual<G>, rate: number): Individual<G>;
/**
 * Random-reset mutation: replaces each gene with a new random value with
 * probability `rate`. Works for any encoding.
 * @param geneFactory Returns a random gene value.
 */
declare function randomResetMutate<G>(individual: Individual<G>, rate: number, geneFactory: () => G): Individual<G>;
/**
 * Runs a full genetic algorithm evolution loop.
 *
 * @example
 * // Maximise the number of 1-bits in a 20-gene binary chromosome
 * const pop = GA.evaluate(
 *   GA.createPopulation(50, 20, () => Math.round(Math.random())),
 *   (genes) => genes.reduce((a, b) => a + b, 0),
 * );
 *
 * const result = GA.run({
 *   population: pop,
 *   fitnessFn: (genes) => genes.reduce((a, b) => a + b, 0),
 *   generations: 100,
 *   mutationRate: 0.02,
 *   geneFactory: () => Math.round(Math.random()),
 * });
 *
 * console.log(result.best.genes, result.best.fitness);
 */
declare function run<G>(options: GARunOptions<G>): GAResult<G>;
declare const GA: {
    /** Create a random population of given size and chromosome length. */
    createPopulation: typeof createPopulation;
    /** Evaluate and assign fitness scores to all individuals. Returns new array. */
    evaluate: typeof evaluate;
    /** Sort a population by fitness (`'desc'` = best first, default). */
    sort: typeof sortPopulation;
    /** Return the top-n fittest individuals. */
    best: typeof best;
    selection: {
        /** Tournament selection — pick the best among `tournamentSize` random candidates. */
        tournament: typeof tournamentSelect;
        /** Fitness-proportionate (roulette wheel) selection. */
        roulette: typeof rouletteSelect;
        /** Rank-based selection — selection pressure without raw-fitness dominance. */
        rank: typeof rankSelect;
    };
    crossover: {
        /** Split at one random cut point and swap tails. */
        singlePoint: typeof singlePointCrossover;
        /** Swap the segment between two random cut points. */
        twoPoint: typeof twoPointCrossover;
        /**
         * Each gene is independently drawn from either parent.
         * @param mixRate Probability of taking from parent2 (default 0.5).
         */
        uniform: typeof uniformCrossover;
    };
    mutation: {
        /**
         * Flip each binary gene with probability `rate`.
         * Designed for `0 | 1` or `boolean` encodings.
         */
        bitFlip: typeof bitFlipMutate;
        /**
         * Swap two random positions with probability `rate`.
         * Best for permutation encodings (TSP, scheduling).
         */
        swap: typeof swapMutate;
        /**
         * Reverse a random sub-sequence with probability `rate`.
         * Good complement to crossover for permutation problems.
         */
        inversion: typeof inversionMutate;
        /**
         * Replace each gene with a new random value with probability `rate`.
         * Works for any encoding; requires a `geneFactory`.
         */
        randomReset: typeof randomResetMutate;
    };
    /**
     * Run a full evolution loop. Handles selection, crossover, mutation,
     * elitism, and fitness evaluation each generation.
     */
    run: typeof run;
};

export { type CrossoverStrategy, GA, type GAResult, type GARunOptions, type Individual, type SelectionStrategy };
