[Python] How to automatically convert objective expression from pyomo model to use as...

Discussão em 'Python' iniciado por Stack, Julho 29, 2025.

  1. Stack

    Stack Membro Participativo

    I use pyomo to formulate optimization problems and tyically use solvers like for example IPOPT. Now I would like to apply metaheuristic solvers to those optimization problems. I have already heared of frameworks like pymoo or pygad that could be used for such purposes.

    However, one always has to formulate the objective and constraints by hand. I would like to find an automated way to fetch the objective or constraints formulations from the pyomo ConcreteModel instance and use it to formulate the fitness_func for pygad.

    For my MWE I just create a simple model with a simple objective (and try to pass this objective as a fitness_func to pygad GA), no constraints yet.

    Minimum (not as desired) Working Example:

    from pyomo import environ as pe
    import pygad

    model = pe.ConcreteModel()
    model.set1 = pe.Set(
    initialize=[i for i in range(10)]
    )
    model.param1 = pe.Param(
    model.set1,
    initialize={
    i: (i+1)**2 for i in model.set1
    },
    mutable=True
    )
    model.var = pe.Var(
    model.set1,
    domain=pe.PositiveReals,
    bounds=(2, 5)
    )

    def obj_rule(model):
    return sum(
    model.param1 * model.var
    for i in model.set1
    )

    model.obj = pe.Objective(
    rule=obj_rule,
    sense=pe.maximize
    )

    solver = pe.SolverFactory('IPOPT')
    solver.solve(model)

    solution_ipopt = model.obj.expr()

    #=== pyomo model done, now comes everything pygad related ======================
    n_vars = len(model.set1)

    def fitness_func(instance, solution, solution_idx):
    # desired: something automated like
    # return model.obj.expr
    # (but that would be too easy and doesn't work)
    return sum(
    (i+1)**2 * solution for i in range(1, n_vars)
    ) # yes, that works but is coded manually, I need something automated

    ga_instance = pygad.GA(
    num_generations = 100,
    num_parents_mating = 10,
    fitness_func = fitness_func,
    sol_per_pop = 100,
    num_genes = n_vars,
    gene_type = float,
    gene_space = [{'low': 2., 'high': 5.} for _ in range(n_vars)],
    parent_selection_type = "tournament",
    crossover_type = "single_point",
    mutation_type = "random",
    mutation_percent_genes = 50,
    parallel_processing= ["thread", 8]
    )

    ga_instance.run()
    solution, solution_fitness, solution_idx = ga_instance.best_solution()


    In fitness_func I had to manually type sum((i+1)**2 * solution for i in range(1, n_vars)) to build the fitness function according to the model.obj objective function. And I need an automated way (for example I found out, that model.obj.expr (without paranthesis!) gives me something that looks promising, but of course that would be too easy and does not work).

    Is there a way to automatically convert the objective function of a pyomo optimization model to an expression suitable to pass to the fitness_func for pygad.GA?

    Continue reading...

Compartilhe esta Página