Dies ist eine der mehrvariablen geschichteten Stichprobenmethoden. Wenn n Experimente angegeben werden, wird jede Variable in n Abschnitte unterteilt, und die Werte werden zufällig aus den Abschnitten extrahiert und zufällig kombiniert. .. Ich bin mir nicht sicher, ob es ein Satz ist, also gab es ein Modul namens pyDOE, also werde ich es versuchen.
Installation
pip install pyDOE
Was ist das experimentelle Muster beim Extrahieren der Mitte des Abschnitts mit 5 Experimenten und 2 Variablen?
>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]])
Wenn Sie die oben genannten Schritte erneut ausführen, ist die Kombination unterschiedlich. Wenn das Argument "c" nicht angegeben wird, wird es außerdem zufällig aus dem Intervall extrahiert. Es sieht aus wie das.
\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}
Bereiten Sie die folgende Datei paraboloid.py vor
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
Bereiten Sie doe_paraboloid.py unten vor. Der Unterschied zu Lösen des Minimierungsproblems der parabolischen Oberfläche mit OpenMDAO wird später erläutert.
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 fuhr fort
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()
Beim Hinzufügen von Paraboloid () zu root werden p1.x und comp.x usw. automatisch verbunden, indem Promotions als Argument verwendet werden.
Dieses Mal habe ich den optimierten lateinischen Hypercube-Treiber verwendet, bei dem es sich gut anfühlt, GA zu verwenden, um die experimentellen Punkte von LHS anzuordnen. OptimizedLatinHypercubeDriver hat 100 Proben, 0 zufällige Samen, 20 GA-Individuen, 4 Generationen, eine Norm zum Normalisieren des Abstands zwischen jedem DOE-Punkt in GA (verwendet in np.linalg.norm), parallel zu num_par_doe Die Anzahl der Conversions wird angegeben.
Gehen Sie im Terminal wie folgt vor
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()