Optimization problem

Hello, i want to solve a problem using python and I don’t know how to start:
The problem is about the optimization of a runner parameter to finish a run faster.

import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt

Définition des constantes

a = 21 # Énergie anaérobique du coureur, en J/kg
beta = 4 # Coefficient de création d’énergie en secondes carrées
T = 1.8 # Taille en mètres
m = 58 # Masse en kilos
S = (np.sqrt((T * m) / 3600)) / 2 # Surface du corps de face en fonction de la taille T et de la masse m (formule de Mosteller)
r = 1.2 # Masse volumique de l’air à 20°C
g = 9.81
pe = 20 # Pente globale en pourcentage
u = 1 # Coefficient de frottement solide estimé pour chaussure de trail
C_xS = 1 # Coefficient aérodynamique
f_air = (1 / 2) * r * C_xS

velocity

def v(t, V, B, w):
return V + B * np.sin(w * t)

all the forces applied on the runner and he must counter to move

def f(t V, B, w):
return g * (np.sin(np.arctan(pe / 100)) + u) + f_air * (1 / m) * (v(t, V, B, w) ** 2)

velocity derivative

def dv_dt(t, V, B, w):
return B * w * np.cos(w * t)

beta function represent the recreation on energy in the runner body

def beta_func(t, V, B, w):
return 4 if dv_dt(t, V, B, w) < 0 else 0

Finally I have for constraint this equation(enclosed) of energy control where e(t) represent the internal energy of the runner and is 1700 J/kg initially the rare symbol is the beta function and there is just a coefficient 1/0,25 before f*v moreover sigma is a constant called ‘a’ in my code representing the anaerobic energy.

Thus the goal is to find the best parameter V, B and w to run faster knowing we have a limited stock of energy.


What happened to the stickied post that would explain how to format code? I don’t see it in Python Help anymore.

Profile → Preferences → Interface:
image

1 Like

Are you able to help ?

Someone would be able to help (having enough time) if the code is formatted correctly. Could you please read the pinned thread?

1 Like

Just to make others happy, here’s the OP’s code in code fences below.
I’m on email, so I get this stuff cleanly anyway. Of course, I don’t get
images :slight_smile:

import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt

# Définition des constantes
a = 21  # Énergie anaérobique du coureur, en J/kg
beta = 4  # Coefficient de création d'énergie en secondes carrées
T = 1.8  # Taille en mètres
m = 58  # Masse en kilos
S = (np.sqrt((T * m) / 3600)) / 2  # Surface du corps de face en fonction de la taille T et de la masse m (formule de Mosteller)
r = 1.2  # Masse volumique de l'air à 20°C
g = 9.81
pe = 20  # Pente globale en pourcentage
u = 1  # Coefficient de frottement solide estimé pour chaussure de trail
C_xS = 1  # Coefficient aérodynamique
f_air = (1 / 2) * r * C_xS

# velocity
def v(t, V, B, w):
     return V + B * np.sin(w * t)

# all the forces applied on the runner and he must counter to move
def f(t V, B, w):
     return g * (np.sin(np.arctan(pe / 100)) + u) + f_air * (1 / m) * 
(v(t, V, B, w) ** 2)

# velocity derivative
def dv_dt(t, V, B, w):
     return B * w * np.cos(w * t)

# beta function represent the recreation on energy in the runner body
def beta_func(t, V, B, w):
     return 4 if dv_dt(t, V, B, w) < 0 else 0

Thanks a lot :grin:

It’s unclear what/where exactly your “problem” is: does “problem” refer to the (“academic”) problem you are studying, or to a concrete technical problem you have in Python…?

In any case, you should write a function find_T(params) which computes the arrival time depending on parameters. To do this, you can use solve_ivp which you import from scipy.integrate, but you don’t use it yet. Is this the problem? In solve_ivp you can specify events which are numeric functions that define the event by changing sign. That function could be the distance from the arrival, dist=lambda t,y: L-y, with attribute dist.terminal=True so that the integration stops when the distance becomes zero (or negative).
(The differential equation you integrate with solve_IVP is y’ = dx/dt = v(t), your x and scipy’s y are the same. [Actually, no: As explained below, you need to include e(t) in the function to integrate, so y(t) = (x(t), e(t)), x = y[0], and you integrate y’(t) = F(t,y) = (v(t), de/dt). You have to define that 2-component function F(t,y) and pass it to solve_ivp])

Then you need a function minimize( f = find_T, params) where params = { name: (lo,hi), ...} gives the parameters to vary and the bounds within they should vary. You can write your own or use scipy.optimize.minimize.
(However, scipy’s minimize needs the parameters that should be varied to be the components of one vector x, which is of course not your x = distance, but whose components are the numerical values of the parameters to be varied (which would be (V,B,w) if I understand well), in some fixed order.

Now I understand that the constraint that prevents you from taking V and/or B as large as you want is the energy which has to stay positive. So you will have to include e(t) in the vector of variables you want to integrate, viz. y(t) = (x(t), e(t)), y’ = (v(t), de/dt), and you will add an additional events sentinel which checks that the energy doesn’t get negative. If it does, you should add a big enough penalty to the function find_T that is to be minimized. I think that penalty should grow with the distance that remains to be run. Maybe you can use find_T = T (at which the event occurs) + (L-x(t))/(some small “minimum” velocity).)

I hope that helps.