0

在下面的代码中,我想使用 optuna 优化目标函数。

"""
Additional modules
   pip install optuna
   pip install scikit-optimize
"""

import time

from py_wake.examples.data.hornsrev1 import V80 
from py_wake.examples.data.hornsrev1 import Hornsrev1Site # We work with the Horns Rev 1 site, which comes already set up with PyWake.
from py_wake import BastankhahGaussian

import numpy as np
import optuna

from py_wake.turbulence_models import GCLTurbulence
from py_wake.deflection_models.jimenez import JimenezWakeDeflection
from py_wake.wind_turbines.power_ct_functions import PowerCtFunctionList, PowerCtTabular



def newSite(x,y):
    
    xNew=np.array([x[0]+560*i for i in range(4)])
    yNew=np.array([y[0]+560*i for i in range(4)])
    x_newsite=np.array([xNew[0],xNew[0],xNew[0],xNew[1],xNew[1],xNew[1],xNew[2],xNew[2],xNew[2]])
    y_newsite=np.array([yNew[0],yNew[1],yNew[2],yNew[0],yNew[1],yNew[2],yNew[0],yNew[1],yNew[2]])
    return (x_newsite,y_newsite)




def objective(trial):

    site = Hornsrev1Site()
    x, y = site.initial_position.T
    x_newsite,y_newsite=newSite(x,y)
    windTurbines = V80()
    
    
    # We ask values of c from optuna.
    c = []
    for i in range(9):
        for l in range(360):
            for k in range(23):

                varname = f'c{i}'
                minv, maxv, stepv = 0, 1, 1
                c.append(trial.suggest_int(varname, minv, maxv, step=stepv))
    C=np.array(c)
    C=C.reshape((9,360,23))
    
    for item in range(9):
        for j in range(10,370,10):
            for i in range(j-10,j):
                C[item][i]=C[item][j-5]
   
    windTurbines.powerCtFunction = PowerCtFunctionList(
    key='operating',
    powerCtFunction_lst=[PowerCtTabular(ws=[0, 100], power=[0, 0], power_unit='w', ct=[0, 0]), # 0=No power and ct
                         windTurbines.powerCtFunction], # 1=Normal operation
    default_value=1)
    
    print(C)
    operating = np.ones((9,360,23)) # shape=(#wt,wd,ws)
    operating[C <= 0.5]=0
    
    wf_model = BastankhahGaussian(site, windTurbines,deflectionModel=JimenezWakeDeflection(),turbulenceModel=GCLTurbulence())

    # run wind farm simulation
    sim_res = wf_model(
        x_newsite, y_newsite, # wind turbine positions
        h=None, # wind turbine heights (defaults to the heights defined in windTurbines)
        wd=None, # Wind direction (defaults to site.default_wd (0,1,...,360 if not overriden))
        ws=None, # Wind speed (defaults to site.default_ws (3,4,...,25m/s if not overriden))
        operating=operating
   )
    
    for i in range(9):
        for l in range(360):
            for k in range(23):
                  if sim_res.TI_eff[i][l][k]-0.14 > 0 :
                      sim_res.Power[i][l][k]=sim_res.Power[i][l][k]-10000*(sim_res.TI_eff[i][l][k]-0.14)**2

    print(-float(np.sum(sim_res.Power))/1e+11)                
    return -float(np.sum(sim_res.Power)/1e+11) 

def optuna_hpo():
    t0 = time.perf_counter()
    
    num_trials = 300
    sampler = optuna.integration.SkoptSampler()
    
    study = optuna.create_study(sampler=sampler, direction="maximize")
    study.optimize(objective, n_trials=num_trials)
    
    print(f"Best params: {study.best_params}")
    print(f"Best value: {study.best_value}\n")
    
    print(f'elapse: {round(time.perf_counter() - t0)}s')  
    

# start
optuna_hpo()

问题是最初的猜测是 c ,它是一个数组(9,360,23)。但是当我运行以下代码时,我 print(f"Best params: {study.best_params}")只需要打印 9 个 c 值,9*360*23所以我认为它只是更改了这 9 个值,而不是所有c值。我也尝试过另一种写 c 的方法,如下所示:

for i in range(9*360*23):

            varname = f'c{i}'
            minv, maxv, stepv = 0, 1, 1
            c.append(trial.suggest_int(varname, minv, maxv, step=stepv))

但是这样一来,代码会在7,8次迭代后因为内存问题而停止。我也使用大学服务器完成了这项工作,所以我认为它会有问题。所以现在我想知道有没有办法c在优化中应用所有值?我的意思是,不仅仅是改变其中的 9 个值,而是改变所有这些值。

4

0 回答 0