es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo generar correctamente las restricciones para ecuaciones de matriz en Mystic?

Tengo un problema de optimización donde quiero minimizar la cantidad -sum(p log(p))dx (entropía) con las restricciones sum(p)dx == 1 y sum(p.x)dx == 0.2, donde p y x son arreglos y dx es un escalar.
Intenté implementar esto usando mystic de esta manera:

from pylab import *
from mystic.symbolic import generate_constraint, generate_solvers, simplify
from mystic.solvers import diffev2

x = linspace(0, 5, 100)
dx = x[1]-x[0]

def objetivo(p):
    return -sum(p*log(p))*dx

bounds = [(0,1)]*len(x)

equations = '''
sum(p)*dx == 1
sum(p*x)*dx == 0.2
'''

eqns = simplify(equations, variables=["p"], locals={"dx":dx, "x":x})

cf = generate_constraint(generate_solvers(eqns))

res = diffev2(objetivo, x0=[1/len(x)]*len(x), bounds=bounds, constraints=cf)

print(sum(res)*dx)
print(sum(res*x)*dx)

Pero obviamente no funciona bien, porque devuelve:

Optimization terminated successfully.
         Current function value: 0.145182
         Iterations: 264
         Function evaluations: 26500
0.030782323656083955
0.07399192217757057

Por lo tanto, se violan las restricciones.
¿Cómo debo proceder para resolver mi problema correctamente?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para resolver adecuadamente el problema de optimización, puedes probar el siguiente enfoque:

    1. Usa un método de optimización diferente, como la evolución diferencial (DE), con restricciones manejadas por un enfoque de función de penalización.
    2. Define la función de penalización para penalizar cualquier violación de la restricción de suma y la restricción de momento. Por ejemplo, si s1=sum(p)dx-1 y s2=sum(p.x)dx-0.2 son las restricciones, entonces la función de penalización puede definirse como:

    penalización = abs(max(0, s1))**2 + abs(max(0, s2))**2
    

    Esta función de penalización será diferente a cero solo si se violan las restricciones, y se usa el cuadrado de la violación para penalizarla.

    1. Modifica la función objetivo para incluir la función de penalización. Por ejemplo, la nueva función objetivo puede ser:
    def objetivo_con_penalizacion(p):
        return -sum(p*log(p))*dx + peso*penalización
    

    donde peso es un parámetro para controlar la importancia relativa de la función de penalización.

    1. Ejecuta la optimización con la función objetivo modificada y los límites originales. Puedes comenzar con un valor pequeño de peso y aumentarlo gradualmente para animar al optimizador a satisfacer las restricciones con más rigor.

    Aquí hay un ejemplo de código que implementa el enfoque anterior:

    import numpy as np
    from scipy.optimize import differential_evolution
    
    x = np.linspace(0, 5, 100)
    dx = x[1]-x[0]
    
    def objetivo(p):
        return -sum(p*log(p))*dx
    
    def penalización(p):
        s1 = sum(p)*dx - 1
        s2 = sum(p*x)*dx - 0.2
        return abs(max(0, s1))**2 + abs(max(0, s2))**2
    
    def objetivo_con_penalizacion(p, peso=1.0):
        return objetivo(p) + peso * penalización(p)
    
    límites = [(0,1)]*len(x)
    
    solución = differential_evolution(
        lambda p: objetivo_con_penalizacion(p, peso=0.1),
        límites=límites,
        tol=1e-6,
        maxiter=1000,
        popsize=15
    )
    
    print(solución.fun)
    print(sum(solución.x)*dx)
    print(sum(solución.x*x)*dx)
    

    Este código utiliza el optimizador differential_evolution de scipy, que es un optimizador popular para problemas de optimización global. El enfoque de función de penalización se implementa en la función objetivo_con_penalizacion, que toma un parámetro adicional de peso. sol.fun es el valor de la función objetivo en la solución óptima, y sol.x son los valores optimizados de p. La restricción de suma y la restricción de momento se cumplen con un alto grado de precisión.

Comments are closed.