Il s'agit de l'une des méthodes d'échantillonnage stratifié à variables multiples. Lorsque n expériences sont spécifiées, chaque variable est divisée en n sections, et les valeurs sont extraites au hasard des sections et combinées au hasard. .. Je ne sais pas si c'est une phrase, donc il y avait un module appelé pyDOE, donc je vais l'essayer.
Installation
pip install pyDOE
Quel est le modèle expérimental lors de l'extraction du centre de la section avec 5 expériences et 2 variables?
>from pyDOE import lhs
>lhs(2,5,"c")
array([[ 0.3, 0.7],
[ 0.1, 0.1],
[ 0.5, 0.9],
[ 0.9, 0.5],
[ 0.7, 0.3]])
Si vous exécutez à nouveau ce qui précède, la combinaison sera différente. De plus, si l'argument «« c »» n'est pas spécifié, il sera extrait de manière aléatoire de l'intervalle. Ça ressemble à ça.
\begin{align}
& f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 \\
{\rm subject \: to} \: \: \:& -50.0\leq x \leq 50.0 \\
& -50.0\leq y \leq 50.0
\end{align}
Préparez le fichier paraboloid.py suivant
paraboloid.py
from openmdao.api import Component
class Paraboloid(Component):
""" Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 """
def __init__(self):
super(Paraboloid, self).__init__()
self.add_param('x', val=0.0)
self.add_param('y', val=0.0)
self.add_output('f_xy', shape=1)
def solve_nonlinear(self, params, unknowns, resids):
"""f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3 """
x = params['x']; y = params['y']
unknowns['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0
Préparez doe_paraboloid.py ci-dessous. La différence avec Résoudre le problème de minimisation de la surface parabolique avec OpenMDAO est décrite plus loin.
doe_paraboloid.py
#!/bin/pyhton
from openmdao.api import IndepVarComp, Group, Problem, SqliteRecorder
from paraboloid import Paraboloid
from openmdao.drivers.latinhypercube_driver import OptimizedLatinHypercubeDriver
from openmdao.core.mpi_wrap import MPI
if MPI: # pragma: no cover
# if you called this script with 'mpirun', then use the petsc data passing
from openmdao.core.petsc_impl import PetscImpl as impl
else:
# if you didn't use `mpirun`, then use the numpy data passing
from openmdao.api import BasicImpl as impl
top = Problem(impl=impl)
root = top.root = Group()
root.add('p1', IndepVarComp('x', 50.0), promotes=['x'])
root.add('p2', IndepVarComp('y', 50.0), promotes=['y'])
root.add('comp', Paraboloid(), promotes=['x', 'y', 'f_xy'])
top.driver = OptimizedLatinHypercubeDriver(num_samples=100, seed=0, population=20, \
generations=4, norm_method=2, num_par_doe=5)
top.driver.add_desvar('x', lower=-50.0, upper=50.0)
top.driver.add_desvar('y', lower=-50.0, upper=50.0)
doe_paraboloid.py a continué
top.driver.add_objective('f_xy')
recorder = SqliteRecorder('doe_paraboloid')
recorder.options['record_params'] = True
recorder.options['record_unknowns'] = True
recorder.options['record_resids'] = False
top.driver.add_recorder(recorder)
top.setup()
top.run()
top.cleanup()
Lors de l'ajout de Paraboloid () à root, p1.x et comp.x etc. sont automatiquement connectés en utilisant promeut comme argument.
Cette fois, j'ai utilisé le pilote optimisé Latin Hypercube, qui est un pilote qui fait du bien à utiliser GA pour organiser les points expérimentaux de LHS. OptimizedLatinHypercubeDriver a 100 échantillons, 0 graines aléatoires, 20 individus GA, 4 générations, une norme pour normaliser la distance entre chaque point DOE en GA (utilisée dans np.linalg.norm), parallèle à num_par_doe Le nombre de conversions est spécifié.
Procédez comme suit dans le terminal
mpirun -np 5 python doe_paraboloid.py
IPython
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import sqlitedict
db =sqlitedict.SqliteDict("doe_paraboloid","iterations")
res = np.array([[0.,0.,0.]] * len(db.items()))
for i, v in enumerate(db.items()):
res[i,0] = v[1]["Unknowns"]["x"]
res[i,1] = v[1]["Unknowns"]["y"]
res[i,2] = v[1]["Unknowns"]["f_xy"]
x = np.arange(-50, 50, 4)
y = np.arange(-50, 50, 4)
X, Y = np.meshgrid(x, y)
Z = (X-3.0)**2 + X*Y + (Y+4.0)**2 - 3.0
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_wireframe(X,Y,Z)
ax.scatter3D(res[:,0],res[:,1],res[:,2],c="r", marker="o")
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('f_xy')
plt.show()