Skip to main content

SKROA — Sympodial Kawayan Rhizome Optimization Algorithm

KRNA (krna on PyPI) is a gradient-free, swarm-style framework for continuous optimization, inspired by the growth habit of running bamboo (kawayan): a biphasic strategy that alternates between wide exploration (rhizome creep via Lévy flights) and focused exploitation (vertical shoot, guided by finite-difference gradients), with two additional operators:

  • Sympodial Clamping — agents that crowd together repel each other, which keeps the swarm spread out and delays premature convergence.
  • Culm-Abortion — exploiting agents that stop improving for several consecutive steps are pruned and respawned near the current best, freeing their search budget.

The package also ships a multi-objective variant (MO-SKROA) that maps Pareto fronts of the ZDT suite, a baseline PSO for comparison, benchmark landscapes (Rastrigin, Ackley, Rosenbrock), a sensitivity-sweep harness, and a hyperparameter tuner for scikit-learn estimators.

Installation

pip install krna

Core features need only NumPy. Plotting (benchmark/sensitivity harnesses) adds Matplotlib, and the ML tuner adds scikit-learn:

pip install "krna[plots]"   # + matplotlib
pip install "krna[ml]"      # + scikit-learn (implies plots)

Quick start

import numpy as np
from krna import SKROA
from krna.benchmarks import rastrigin

optimizer = SKROA(
    evaluator=rastrigin,       # maps (N, D) candidate matrix -> (N,) fitness
    bounds=(-5.12, 5.12),      # same box bounds on every dimension
    dim=10,
    n_agents=50,
    max_iters=500,
    seed=42,                   # fully reproducible runs
)
result = optimizer.optimize()

print("best fitness :", result["g_best_fit"])
print("best position:", result["g_best_pos"])
# result["convergence_curve"] is a per-iteration history of the best fitness

Your evaluator receives a (n_agents, dim) float array and must return a (n_agents,) array of fitness values to minimize. Batch evaluation like this keeps the whole swarm vectorized — don't loop over agents in Python if your objective can be written with NumPy.

Hyperparameters

Parameter Default Role
n_agents 50 swarm size
max_iters 1000 iteration budget
delta_threshold None fitness cutoff for the exploit state; None uses the swarm median (keeps ~50% exploiting)
tau_stagnation 1e-4 minimum per-step improvement before an exploiting agent counts as stalled
max_stagnation_steps 10 stalled steps tolerated before Culm-Abortion respawns the agent
epsilon_clamp 1e-2 repulsion distance for Sympodial Clamping
gamma_lr 0.05 gradient-step learning rate (relative to the domain span)
levy_scale 0.01 Lévy-flight step scale (relative to the domain span)
sigma_jitter 1e-4 Gaussian jitter added to gradient steps
seed 42 RNG seed for reproducibility

Multi-objective optimization

from krna import MOSKROA
from krna.mo_benchmarks import ZDT1_BENCHMARK

opt = MOSKROA(evaluator=ZDT1_BENCHMARK.evaluator, bounds=(0.0, 1.0), dim=30)
res = opt.optimize()  # res["pareto_front_fitness"] -> (A, 2) objective matrix

MO-SKROA maintains a non-dominated archive; exploiting agents descend along randomly scalarized gradients so different agents cover different regions of the front.

Hyperparameter tuning for scikit-learn models

from sklearn.svm import SVC
from sklearn.datasets import load_breast_cancer
from krna.ml_tuning import SKROAMLTuner

data = load_breast_cancer()
space = {
    "C":     {"type": "log_float", "min": 1e-3, "max": 1e3},
    "gamma": {"type": "log_float", "min": 1e-4, "max": 1e1},
    "kernel": {"type": "categorical", "values": ["linear", "rbf", "sigmoid"]},
}
tuner = SKROAMLTuner(model_class=SVC, param_space=space,
                     X=data.data, y=data.target, seed=101)
print(tuner.tune())

Supported parameter types: int, float, log_float, categorical.

Tuning a random forest

The same interface works for any scikit-learn estimator — the tuner detects automatically whether the model accepts a random_state argument. Here is a RandomForestClassifier on the same dataset, mixing integer, log-scaled and categorical hyperparameters in one search space:

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from krna.ml_tuning import SKROAMLTuner

data = load_breast_cancer()
space = {
    "n_estimators": {"type": "int", "min": 25, "max": 400},
    "max_depth":    {"type": "int", "min": 2, "max": 20},
    "max_features": {"type": "categorical", "values": ["sqrt", "log2"]},
    "min_samples_leaf": {"type": "log_float", "min": 1e-3, "max": 0.3},
}

tuner = SKROAMLTuner(model_class=RandomForestClassifier, param_space=space,
                     X=data.data, y=data.target, cv_folds=5,
                     n_agents=20, max_iters=30, seed=101)
result = tuner.tune()
print(result["best_hyperparams"])         # decoded hyperparameter dict
print(f"CV accuracy: {result['best_accuracy_percent']:.2f}%")

Continuous coordinates are decoded with a log scale for log_float parameters, so the swarm explores min_samples_leaf between 1e-3 and 0.3 evenly across orders of magnitude — the same trick RandomizedSearchCV uses. Candidate models are cross-validated in parallel (n_jobs=-1); invalid combinations score worst instead of crashing the run.

Command line

krna benchmark      # SKROA vs PSO on Rastrigin/Ackley/Rosenbrock, CSV + plots
krna tune           # SKROA hyperparameter search on an SVM (breast cancer)
krna mo-benchmark   # MO-SKROA on ZDT1/ZDT2 Pareto fronts

Outputs land in results/logs/ (CSV telemetry) and results/plots/ (convergence curves, 3D surfaces, Pareto fronts, sensitivity heatmaps).

Benchmark results

Full head-to-head run of krna benchmark --trials 30: SKROA vs. baseline PSO on three classical landscapes — 30 independent trials per algorithm per landscape (seeds 1000–1029), D=10, 50 agents, 500 iterations, identical budgets and seeds for both algorithms. Statistics are two-sided Wilcoxon rank-sum tests with Cohen's r effect size (krna.stats), reported exactly as the suite prints them.

Landscape SKROA best fitness (mean ± std) PSO best fitness (mean ± std) Wilcoxon p Effect size r Verdict (α=0.05)
Rastrigin 14.196 ± 3.012 7.368 ± 2.966 5.97e-09 0.75 PSO significantly better
Ackley 3.598 ± 0.257 1.3e-07 ± 1.2e-07 3.02e-11 0.86 PSO significantly better
Rosenbrock 1855.12 ± 839.79 4.381 ± 1.983 3.02e-11 0.86 PSO significantly better

Reading the table honestly:

  • The baseline PSO wins on all three landscapes at this 500-iteration budget, and it also reaches a comparable fitness in roughly 1/6 of the wall-clock time (~0.4 s vs ~2.2 s per run). SKROA spends most of its budget on exploration, so with equal iteration counts it converges more slowly on these unimodal/mildly multimodal 10-D problems.
  • Both comparisons share one subtlety of any iteration-matched benchmark: per iteration, SKROA's finite-difference gradient probes cost extra function evaluations that PSO does not pay. That is the standard iteration-budget convention, but evaluation-matched comparisons may narrow the gap.
  • The p-values and large effect sizes say the differences are real, not noise — which is exactly why we report them rather than cherry-picking a favorable setting. We publish the suite's output as-is and treat the gap as a target for parameter tuning (see krna sensitivity harness) rather than a headline.

Reproduce with:

krna benchmark --trials 30          # ~5 min on a laptop; CSV + plots in results/

Raw telemetry for this table: results/logs/benchmark_metrics.csv.

Statistical significance testing

Comparing two metaheuristics by eyeballing mean fitness is not publishable — differences can be noise. The benchmark suite therefore reports, for every landscape, a two-sided Wilcoxon rank-sum test (Mann-Whitney U) between the SKROA and PSO final best-fitness samples, with tie correction and continuity correction, plus Cohen's r effect size. Both are implemented in krna.stats with NumPy only and are cross-checked against scipy.stats.mannwhitneyu in the test suite.

Each benchmark_metrics.csv row for PSO carries P_Value_RankSum, Effect_Size_r, and a plain-language Statistical_Verdict; the console prints a [STATS] line per landscape. Use at least 30 independent runs (--trials 30) for stable estimates.

You can also test your own samples:

from krna import wilcoxon_rank_sum, cohens_r, bonferroni_correct

result = wilcoxon_rank_sum(fitness_a, fitness_b)  # >= 8 runs per sample
print(result.u_statistic, result.p_value, result.is_significant)
print("effect size r =", cohens_r(fitness_a, fitness_b))
adjusted = bonferroni_correct([result.p_value, 0.02])  # family-wise control

For multi-problem studies, adjust for multiple comparisons (Bonferroni is provided; Holm or Friedman + Imany–Davenport are common stronger choices).

Methodology and reproducibility

  • Minimization everywhere. Evaluators map an (n_agents, dim) array of candidate positions to an (n_agents,) array of fitness values; lower is better.
  • Seeded runs. All stochastic operators draw from a NumPy Generator seeded at construction. Two runs with the same seed produce bit-identical convergence curves (verified by test).
  • Bounds are a hard contract. No point is ever handed to your evaluator outside [low, high] — gradient probes fold inward at boundaries (krna.gradient).
  • Exploration/exploitation split. Agents below the fitness threshold (default: the swarm median, delta_threshold=None) exploit via finite-difference gradient descent; the rest explore via Lévy flights. Stalled exploiting agents are respawned near the best solution after max_stagnation_steps non-improving iterations (Culm-Abortion).
  • Fair benchmarking. SKROA and PSO receive identical iteration budgets, swarm sizes, seeds, and evaluation functions per trial.

Running the tests

python -m unittest discover -s tests -v

Contributing

See CONTRIBUTING.md for development setup, ground rules, and pull-request checks. Notable changes are recorded in CHANGELOG.md.

License

MIT — see LICENSE.

Release files for krna 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for krna 1.0.1
File Size Uploaded
krna-1.0.1.tar.gz 43.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for krna 1.0.1
File Interpreter ABI Platform
krna-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 79.4 kB

Release files / krna-1.0.1.tar.gz

Download URL krna-1.0.1.tar.gz
Size 43.9 kB
Tags Source
SHA-256 checksum
How to use checksums
11d977171abfe71b54e734f82a989d35625b1f48dd842ea6189266af5c43408f
BLAKE2b-256 checksum
How to use checksums
8d24786a870342d7f1fdce8974756366a80848f0f9d174b44853ba8d7e9d21c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / krna-1.0.1-py3-none-any.whl

Download URL krna-1.0.1-py3-none-any.whl
Size 35.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
02a27ac29dc0cb8e577fd639b516a5742b3cb5c430c558b2d6e90d64881e5fac
BLAKE2b-256 checksum
How to use checksums
d743139d6d22702615d68d36d086051ec581b4df950a7a0ad8af9dfe3240af65
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.2

2 release files

This release

1.0.1 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page