README.md

June 4, 2026 · View on GitHub

EoH: Evolution of Heuristics

A Platform of Evolutionary Computation (EC) + Large Language Model (LLM) for Automatic Algorithm/Heuristic Design

Chinese Version 中文版本

Github License Releases Wiki


A Lightweight and User-Friendly EoH Framework for LLM-driven Automated Algorithm/Heuristic Design

Note

Using the old EoH version? If your code uses Paras / eoh.EVOL, it targets the legacy v0.1 interface. Download or install the old version from the v0.1 release: The current main branch uses the new LLMConfig / EoH / BaseProblem API documented below.

eoh

News 🔥


Introduction 📖

Heuristics are indispensable for tackling complex search and optimization problems. However, manual heuristic design is tedious and demands significant human intuition and experience.

EOH introduces a novel paradigm that leverages the synergy between Large Language Models (LLMs) and Evolutionary Computation (EC) for Automatic Heuristic Design (AHD). The coevolution of thoughts and codes within an evolutionary framework offers superior AHD performance while mitigating computational expenses.

eoh

EOH designs very competitive algorithms/heuristics in minutes/hours. Notably, it surpasses FunSearch, identifying superior heuristics with significantly fewer computational budgets (i.e., queries to LLMs) on online bin packing problem.

The following figure shows the evolution of EOH on the online bin packing problem. We outline the key thoughts and the corresponding code snippets that have contributed to the best results during evolution. Additionally, we mark the prompt strategies that result in improvement. Finally, we present the optimal heuristic in the final population and compare it to the heuristics designed by humans and from FunSearch.

eoh

If you find EoH helpful for your research or applied projects:

@inproceedings{fei2024eoh,
    title={Evolution of Heuristics: Towards Efficient Automatic Algorithm Design Using Large Language Model},
    author={Fei Liu, Xialiang Tong, Mingxuan Yuan, Xi Lin, Fu Luo, Zhenkun Wang, Zhichao Lu, Qingfu Zhang},
    booktitle={International Conference on Machine Learning (ICML)},
    year={2024},
    url={https://arxiv.org/abs/2401.02051}
}

If you are interested in LLM4Opt or EoH, you can:

  1. Contact us through email fliu36-c@my.cityu.edu.hk.

  2. Visit a collection of references and research papers on LLM4Opt

  3. Join our QQ Group

If you encounter any difficulty using the code, you can contact us through the above or submit an issue

Requirements

  • python >= 3.10
  • numpy
  • joblib

EoH Example Usage 💻

Step 1: Install EoH

We suggest installing and running EoH in a conda environment with python >= 3.10.

cd eoh
pip install .

Step 2: Configure your LLM and run an example

Set up your endpoint and key for a remote LLM, or configure a local LLM, before starting!

from eoh import EoH, LLMConfig
from prob import MyProblem  # your problem class (see "Use EoH in Your Application" below)

llm = LLMConfig(
    api_endpoint="api.deepseek.com",  # e.g. "api.openai.com" or "api.deepseek.com"
    api_key="your-api-key",
    model="deepseek-chat",            # e.g. "gpt-4o", "deepseek-chat"
    timeout=150,
)

task = MyProblem(timeout=40, n_processes=4)

eoh = EoH(
    llm=llm,
    problem=task,
    pop_size=5,       # population size per generation
    n_pop=20,         # number of generations
    operators=['e1', 'e2', 'm1', 'm2'],
    output_dir="./results",
)
eoh.run()
Example 1: Constructive Algorithm for TSP
cd examples/tsp_construct
python runEoH.py

Evaluation

cd examples/tsp_construct/evaluation
# copy your heuristic to heuristic.py (function name/input/output must match the evaluation block)
python runEval.py
Example 2: Online Bin Packing

(Generate a new best heuristic in 30 minutes on your personal computer! i7-10700 2.9GHz, 32 GB)

cd examples/bp_online
python runEoH.py

Evaluation

cd examples/bp_online/evaluation
# copy your heuristic to heuristic.py (function name/input/output must match the evaluation block)
python runEval.py

Use EoH in Your Application

Define your problem by subclassing BaseProblem. You need to provide:

  • template_program: a Python function (or class) skeleton the LLM will evolve.
  • task_description: a one-sentence description of what the LLM should optimise.
  • evaluate_program: a method that receives the generated callable and returns a float fitness (lower is better), or None on failure.
import numpy as np
from eoh import EoH, LLMConfig, BaseProblem


class MyProblem(BaseProblem):
    template_program = '''
def heuristic(x: np.ndarray) -> float:
    """Compute a score for input x."""
    return float(x.mean())
'''
    task_description = "Design a heuristic function that minimises the mean of the input."

    def evaluate_program(self, program_str: str, callable_func) -> float | None:
        # Replace with your actual evaluation logic
        score = callable_func(np.random.rand(10))
        return score  # lower is better


llm = LLMConfig(
    api_endpoint="api.deepseek.com",
    api_key="your-api-key",
    model="deepseek-chat",
)

task = MyProblem(timeout=30, n_processes=4)

eoh = EoH(llm=llm, problem=task, pop_size=5, n_pop=20, output_dir="./results")
eoh.run()

EoH supports three template kinds, detected automatically:

  • function — a single function (most common).
  • multi_function — multiple cooperating functions; the last one is the entry point.
  • class — a class with a designated method; the class name is the entry point.

See examples/tsp_construct_class and examples/tsp_construct_multifunction for class and multi-function examples.

Three Levels of Heuristic Design

EoH supports three levels of heuristic design, offering increasing expressiveness. All three are illustrated using the TSP constructive heuristic task.


Level 1 — Single Function (tsp_construct)

The simplest and most common form. The LLM evolves a single standalone function. The entry point is the function itself.

template_program = '''
def select_next_node(current_node: int, destination_node: int,
                     unvisited_nodes: np.ndarray,
                     distance_matrix: np.ndarray) -> int:
    """Select the next node to visit in a TSP greedy construction."""
    return unvisited_nodes[np.argmin(distance_matrix[current_node][unvisited_nodes])]
'''

Level 2 — Multi-Function (tsp_construct_multifunction)

The LLM evolves multiple cooperating functions. The last top-level function is the entry point; helper functions defined above it are called internally. This allows the LLM to decompose the heuristic into reusable sub-components.

template_program = '''
def compute_node_scores(current_node: int, unvisited_nodes: np.ndarray,
                        distance_matrix: np.ndarray,
                        destination_node: int) -> np.ndarray:
    """Compute a priority score for each candidate unvisited node."""
    return -distance_matrix[current_node][unvisited_nodes]


def select_next_node(current_node: int, destination_node: int,
                     unvisited_nodes: np.ndarray,
                     distance_matrix: np.ndarray) -> int:
    """Select the next node using compute_node_scores."""
    scores = compute_node_scores(current_node, unvisited_nodes,
                                 distance_matrix, destination_node)
    return unvisited_nodes[np.argmax(scores)]
'''

Level 3 — Class (tsp_construct_class)

The LLM evolves an entire class. The class name is the entry point — EoH instantiates it and calls the designated method. This is the most expressive level, enabling stateful heuristics, internal data structures, and object-oriented design.

template_program = '''
class TSPConstructor:
    """Constructive heuristic for the Travelling Salesman Problem."""

    def select_next_node(self, current_node: int, destination_node: int,
                         unvisited_nodes: np.ndarray,
                         distance_matrix: np.ndarray) -> int:
        """Select the next node to visit."""
        return unvisited_nodes[np.argmin(distance_matrix[current_node][unvisited_nodes])]
'''

Single FunctionMulti-FunctionClass
Entry pointthe functionlast top-level functionthe class (instantiated)
Helper componentsadditional functions abovemethods and attributes
Stateful designyes
Typical usemost heuristicsdecomposed scoring/selectionstateful or complex heuristics
Exampletsp_constructtsp_construct_multifunctiontsp_construct_class

Examples

The table below lists all 33 example tasks included in the examples/ directory.

TSP Constructive HeuristicBBOB MetaheuristicAtari Breakout
tsp_constructbbob_metaheuristicale_breakout
NameDescriptionLinkNote
aco_pheromoneDesign a pheromone update rule for Ant Colony Optimization on TSP.code
admissible_setDesign a priority function for greedy construction of maximum-cardinality symmetric admissible sets.code
ale_breakoutEvolve an action-selection heuristic for an Atari Breakout agent.codeRequires ALE
ale_pongEvolve an action-selection heuristic for an Atari Pong agent.codeRequires ALE
bbob_metaheuristicDesign a complete single-objective metaheuristic for continuous black-box optimization.codeClass template
bo_acquisitionDesign an acquisition function for Bayesian Optimization to guide candidate selection.codePPSN 2024 Best Paper Nomination
bp_onlineDesign a bin-scoring function for online bin packing to minimise the number of used bins.codeEoH paper benchmark
cmaes_cov_updateDesign a covariance matrix update rule for CMA-ES on 10-D benchmarks.code
cvrp_constructDesign a greedy constructive heuristic for the Capacitated Vehicle Routing Problem.code
de_crossover_100dDesign an adaptive crossover operator for Differential Evolution at 100 dimensions.codeHigh-dimensional
de_mutationDesign a novel mutation operator for Differential Evolution on 10-D benchmarks.code
deap_eaSimple_selectionDesign a parent selection operator for a DEAP genetic algorithm on 10-D benchmarks.codeUses DEAP
es_step_sizeDesign a step-size adaptation rule for (1+λ)-Evolution Strategy.code
evo_dynamicDesign a population response strategy for dynamic optimization under periodic environment changes.codeDynamic environment
fssp_glsDesign a guided local search perturbation for flow-shop scheduling to minimise makespan.code
gnn_aggregationDesign a neighborhood aggregation function for GNN node classification.codeRequires PyTorch
large_scale_esDesign diagonal variance adaptation for separable CMA-ES at 100 dimensions.codeHigh-dimensional
mobbob_metaheuristicDesign a multi-objective metaheuristic to maximise hypervolume on 2-objective BBOB.codeMulti-objective; class template
moead_decompositionDesign a decomposition function for MOEA/D to convert multi-objective problems into scalar subproblems.codeMulti-objective
nsga2_crowdingDesign a crowding-distance metric for NSGA-II to maximise hypervolume on ZDT problems.codeMulti-objective
nsga2_pymooDesign a crossover operator for NSGA-II via pymoo on ZDT problems.codeMulti-objective; uses pymoo
nurse_rosteringDesign a shift-assignment priority function for nurse rostering to balance workload and preferences.code
one_plus_oneDesign a mutation noise generator for nevergrad's (1+1)-ES on 10-D benchmarks.codeUses nevergrad
portfolio_constructDesign an asset scoring function for greedy portfolio construction to maximise Sharpe ratio.code
pso_velocityDesign a velocity update rule for Particle Swarm Optimization on 10-D benchmarks.code
sa_acceptanceDesign an acceptance probability function for Simulated Annealing on 10-D benchmarks.code
tabu_tspDesign a move-scoring function for Tabu Search with 2-opt moves on TSP.code
tpe_bandwidthDesign an observation-weighting function for Optuna's Tree-structured Parzen Estimator.codeUses Optuna
tsp_constructDesign a next-node selection heuristic for greedy TSP tour construction.codeEoH paper benchmark
tsp_construct_classDesign a TSP constructive heuristic as a class with a select_next_node method.codeClass template example
tsp_construct_multifunctionDesign two cooperating functions (node scoring + selection) for TSP construction.codeMulti-function template example
tsp_glsDesign an edge-distance update strategy for TSP Guided Local Search.code
tsp_rnrDesign a destroy operator (node selection) for a ruin-and-recreate TSP algorithm.code

LLMs

Set api_endpoint, api_key, and model in LLMConfig. Any OpenAI-compatible endpoint works:

llm = LLMConfig(
    api_endpoint="api.openai.com",   # or "api.deepseek.com", etc.
    api_key="your-api-key",
    model="gpt-4o",
    timeout=150,
)

Supported providers include:

2) Local LLM

Set use_local=True and point local_url to your running inference server:

llm = LLMConfig(
    use_local=True,
    local_url="http://127.0.0.1:11012/completions",
    timeout=180,
)

The local server must accept POST requests in the format expected by api_local_llm.py. Any server that serves a Hugging Face model (e.g., via a simple Flask/FastAPI wrapper) and returns {"content": ["<generated text>"]} will work.

3) Custom Implementation

Subclass the LLM interface in eoh/src/eoh/llm/ to integrate any other LLM provider.

Frequently Asked Questions

For answers to common questions about installation, LLM configuration, defining problems, evolutionary operators, results, and troubleshooting, see the FAQ.


Welcome to visit a collection of references and research papers on LLM4Opt

Contributors

Fei Liu Rui Zhang Zhiyuan Yang Ping Guo
Shunyu Yao