How select a first population from my code in Pymoo

244 views Asked by At

I am need of a help.

My code is to maximize the profit and minimize the area, which is the sum of Xs. The X are the áreas, and 4 of them are free to use, and the other 4 have a cost to use, and have less productivity as the first 7.

I have 8 output variables of X. However, I need that my code create a population in Pymoo that first check the first 4. That code is it:

pip install -U pymoo==0.5.0
#importando algumas bibliotecas iniciais do Pymoo

import numpy as np

from pymoo.factory import get_problem
from pymoo.optimize import minimize
#valores iniciais (em R$/t)

S_preco = 2300

#Área (em ha)
#MA - 1
#TO - 2
#PI - 3
#BA - 4
#Nova terra MA - 5
#Nova terra TO - 6
#Nova terra PI - 7
#Nova terra BA - 8

AreaMAX = [600000, 650000, 500000, 1500000, 309853, 930190, 14197, 55525]

#produtividade das terras (em t/ha)

Produtividade = [3.206, 3.322, 3.377, 3.779, 3, 3.12, 3, 3.3]

#custos

#custo do plantio da soja (em R$/t)
S_custo = [983, 966.5, 1051.5, 1040.167, 983, 966.5, 1051.5, 1040.167]

#custo do uso da terra (em R$/t)

Custo_terra = [0, 0, 0, 0, 7500, 9000, 10000, 20500]

#demanda de soja a ser atendida (em t)

S_demanda = 5056921 + 2332769 - (5056921/117887685 + 2332769/117887685)*18344777

#demais preços e custos (valores constantes)

S_preco = 2500
F_preco = 2500
O_preco = 3500
B_preco = 3500

F_custo = 60
O_custo = 100
B_custo = 500

#demanda de farelo, óleo bruto e biodiesel (em t)

F_demanda = 1510028
O_demanda = 378913
B_demanda = 244031.02

#Valores iniciais da porcentagem de soja a ser vendida e da porcentagem de óleo a ser vendido

#S_per = 0
#O_per = 0

#modelo matemático:

#f1 é a equação de maximização do lucro da soja e dos subprodutos
#f2 é a equação de minimização das quatro áreas
#g1 a g8 são as restrições relacionadas a área máxima
  #g1 é a restrição da área máxima de MA
  #g2 é a restrição da área máxima de TO
  #g3 é a restrição da área máxima de PI
  #g4 é a restrição da área máxima da BA
  #g5 é a restrição da área máxima da área de aptidão do MA (Nova MA)
  #g6 é a restrição da área máxima da área de aptidão do TO (Nova TO)
  #g7 é a restrição da área máxima da área de aptidão do PI (Nova PI)
  #g8 é a restrição da área máxima da área de aptidão da BA (Nova BA)
#g9 a g12 são as restrições relacionadas a demanda de cada subproduto
  #g9 é a restrição de demanda mínima da soja
  #g10 é a restrição de demanda mínima do farelo
  #g11 é a restrição de demanda mínima do óleo bruto
  #g12 é a restrição de demanda mínima do biodiesel

import numpy as np
from pymoo.core.problem import ElementwiseProblem

class MyProblem(ElementwiseProblem):

    def __init__(self):
        super().__init__(n_var=10,
                         n_obj=2,
                         n_constr=12,
                         xl=np.array([0,0,0,0,0,0,0,0,0,0]),
                         xu=np.array([AreaMAX[0],AreaMAX[1],AreaMAX[2],AreaMAX[3],AreaMAX[4],AreaMAX[5],AreaMAX[6],AreaMAX[7],1,1]))

    def _evaluate(self, X, out, *args, **kwargs):
        f1 = -1*((X[0]*Produtividade[0] + X[1]*Produtividade[1] + X[2]*Produtividade[2] + X[3]*Produtividade[3] + X[4]*Produtividade[4] + X[5]*Produtividade[5] + X[6]*Produtividade[6] + X[7]*Produtividade[7])*X[8]*S_preco + (X[0]*Produtividade[0] + X[1]*Produtividade[1] + X[2]*Produtividade[2] + X[3]*Produtividade[3] + X[4]*Produtividade[4] + X[5]*Produtividade[5] + X[6]*Produtividade[6] + X[7]*Produtividade[7])*(1 - X[8])*(F_preco*0.4 + 0.2*(X[9]*O_preco + (1 - X[9])*B_preco)) - (X[0]*(Produtividade[0]*S_custo[0] + Custo_terra[0]) + X[1]*(Produtividade[1]*S_custo[1] + Custo_terra[1]) + X[2]*(Produtividade[2]*S_custo[2] + Custo_terra[2]) + X[3]*(Produtividade[3]*S_custo[3] + Custo_terra[3]) + X[4]*(Produtividade[4]*S_custo[4] + Custo_terra[4]) + X[5]*(Produtividade[5]*S_custo[5] + Custo_terra[5]) + X[6]*(Produtividade[6]*S_custo[6] + Custo_terra[6]) + X[7]*(Produtividade[7]*S_custo[7] + Custo_terra[7])) - (X[0]*Produtividade[0] + X[1]*Produtividade[1] + X[2]*Produtividade[2] + X[3]*Produtividade[3] + X[4]*Produtividade[4] + X[5]*Produtividade[5] + X[6]*Produtividade[6] + X[7]*Produtividade[7])*(1 - X[8])*(F_custo + O_custo + 0.2*(1 - X[9])*(B_custo)))/1e10
        f2 = (X[0] + X[1] + X[2] + X[3] + X[4] + X[5] + X[6] + X[7])/1e7

        g1 = X[0] - AreaMAX[0]
        g2 = X[1] - AreaMAX[1]
        g3 = X[2] - AreaMAX[2]
        g4 = X[3] - AreaMAX[3]
        g5 = X[4] - AreaMAX[4]
        g6 = X[5] - AreaMAX[5]
        g7 = X[6] - AreaMAX[6]
        g8 = X[7] - AreaMAX[7]
        g9 = -1*((X[0]*Produtividade[0] + X[1]*Produtividade[1] + X[2]*Produtividade[2] + X[3]*Produtividade[3] + X[4]*Produtividade[4] + X[5]*Produtividade[5] + X[6]*Produtividade[6] + X[7]*Produtividade[7])*X[8] - S_demanda)
        g10 = -1*((X[0]*Produtividade[0] + X[1]*Produtividade[1] + X[2]*Produtividade[2] + X[3]*Produtividade[3] + X[4]*Produtividade[4] + X[5]*Produtividade[5] + X[6]*Produtividade[6] + X[7]*Produtividade[7])*(1 - X[8])*0.4 - F_demanda)
        g11 = -1*((X[0]*Produtividade[0] + X[1]*Produtividade[1] + X[2]*Produtividade[2] + X[3]*Produtividade[3] + X[4]*Produtividade[4] + X[5]*Produtividade[5] + X[6]*Produtividade[6] + X[7]*Produtividade[7])*(1 - X[8])*0.2*X[9] - O_demanda)
        g12 = -1*((X[0]*Produtividade[0] + X[1]*Produtividade[1] + X[2]*Produtividade[2] + X[3]*Produtividade[3] + X[4]*Produtividade[4] + X[5]*Produtividade[5] + X[6]*Produtividade[6] + X[7]*Produtividade[7])*(1 - X[8])*0.2*(1 - X[9]) - B_demanda)

        out["F"] = [f1, f2]
        out["G"] = [g1, g2, g3, g4, g5 ,g6, g7, g8, g9, g10, g11, g12]

problem = MyProblem()

#X[0] - Área de soja da região do MA
#X[1] - Área de soja da região do TO
#X[2] - Área de soja da região do PI
#X[3] - Área de soja da região da BA
#X[4] - Área de soja da região da Nova MA
#X[5] - Área de soja da região da Nova TO
#X[6] - Área de soja da região da Nova PI
#X[7] - Área de soja da região da Nova BA
#X[8] - S_Per (porcentagem de soja vendido)
#X[9] - O_Per (porcentagem de oleo vendido)

problem = MyProblem()

#importando as bibliotecas do NSGA-II

from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.factory import get_sampling, get_crossover, get_mutation

algorithm = NSGA2(
    pop_size=1100,
    n_offsprings=10,
    sampling=get_sampling("real_random"),
    crossover=get_crossover("real_sbx", prob=0.9, eta=15),
    mutation=get_mutation("real_pm", eta=20),
    eliminate_duplicates=True
)

#definindo o número de gerações

from pymoo.factory import get_termination

termination = get_termination("n_gen", 1000)

#rodando o NSGA-II

from pymoo.optimize import minimize

res = minimize(problem,
               algorithm,
               termination,
               seed=1,
               save_history=True,
               verbose=True)

X = res.X
F = res.F

res.F[:,0] *= -1

#plotando a fronteira de Pareto do NSGA-II

from pymoo.visualization.scatter import Scatter

plot = Scatter(title = "Espaço Objetivo")
plot.add(res.F, color="red")
plot.show()

#gerando o arquivo em csv das variaveis do NSGA-II

X = res.pop.get("X")
np.savetxt("NSGApop.csv", X, delimiter=",",)

#gerando o arquivo em csv dos resultados de f1 e f2 do NSGA-II

F = res.pop.get("F")
np.savetxt("NSGAResult.csv", F, delimiter=",")

So, what changes in population (and in the code) I have to do, to ensure that code will priorize the first X0 to X3, and use the other 4 after (X4 to X7). Also, how the choice of individuals of population works in Pymoo. Anyone can help?

I think I have doubts about how population works in Pymoo, related to code also.

I just wanted to learn how to write the first population of my code. And how I can write the population code to priorize the first X(0 to 3).

1

There are 1 answers

1
Pieter-Jan On

You can set a first population as a starting point by using initialization. Here is an example: https://pymoo.org/customization/initialization.html