class BestValue(object): """ BestValue holds a parameter set and a best objective value, which is used by the PADDS Algorithm. Updates are done within the algorithm """ def __init__(self, para_func, obj_value): self.para_func = para_func self.parameters = ParameterSet(self.para_func()) self.best_obj_val = obj_value self.best_rep = 0 def copy(self): to_copy = BestValue(self.parameters.copy(), self.best_obj_val) to_copy.best_rep = self.best_rep return to_copy def __str__(self): return "BestValue(best_obj_val = " + str(self.best_obj_val) + ", best_rep = " + str(self.best_rep) + ", " \ + str(self.parameters) + ")" def reset_rep(self): self.best_rep = 0 def fix_format(self): start_params = ParameterSet(self.para_func()) start_params.set_by_array([j for j in self.parameters]) self.parameters = start_params
def __init__(self, *args, **kwargs): """ Input ---------- spot_setup: class model: function Should be callable with a parameter combination of the parameter-function and return an list of simulation results (as long as evaluation list) parameter: function When called, it should return a random parameter combination. Which can be e.g. uniform or Gaussian objectivefunction: function Should return the objectivefunction for a given list of a model simulation and observation. evaluation: function Should return the true values as return by the model. dbname: str * Name of the database where parameter, objectivefunction value and simulation results will be saved. dbformat: str * ram: fast suited for short sampling time. no file will be created and results are saved in an array. * csv: A csv file will be created, which you can import afterwards. parallel: str * seq: Sequentiel sampling (default): Normal iterations on one core of your cpu. * mpi: Message Passing Interface: Parallel computing on cluster pcs (recommended for unix os). save_sim: boolean * True: Simulation results will be saved * False: Simulation results will not be saved :param r: neighborhood size perturbation parameter (r) that defines the random perturbation size standard deviation as a fraction of the decision variable range. Default is 0.2. :type r: float """ try: self.r = kwargs.pop("r") except KeyError: self.r = 0.2 # default value super(dds, self).__init__(*args, **kwargs) self.np_random = np.random self.status.params = ParameterSet(self.parameter()) # self.generator_repetitions will be set in `sample` and is needed to generate a # generator which sends back actual parameter s_test self.generator_repetitions = -1 self.dds_generator = DDSGenerator(self.np_random)
def calc_initial_para_configuration(self, initial_iterations, trial, repetitions, x_initial): #max_bound, min_bound = self.status.params_max.maxbound, self.status.params_max.minbound parameter_bound_range = self.max_bound - self.min_bound number_of_parameters = len(parameter_bound_range) discrete_flag = ParameterSet(self.parameter()).as_int params_max = x_initial objectivefunction_max = -1e308 # Calculate the initial Solution, if `initial_iterations` > 1 otherwise the user defined a own one. # If we need to find an initial solution we iterating initial_iterations times to warm um the algorithm # by trying which randomized generated input matches best # initial_iterations is the number of function evaluations to initialize the DDS algorithm solution if initial_iterations > 1: print('Finding best starting point for trial ' + str(trial + 1) + ' using ' + str(initial_iterations) + ' random samples.') repetions_left = repetitions - initial_iterations # use this to reduce number of fevals in DDS loop if repetions_left <= 0: raise ValueError( '# Initialization samples >= Max # function evaluations.') starting_generator = ((rep, [ self.np_random.randint(np.int(self.min_bound[j]), np.int(self.max_bound[j]) + 1) if discrete_flag[j] else self.min_bound[j] + parameter_bound_range[j] * self.np_random.rand() for j in range(number_of_parameters) ]) for rep in range(int(initial_iterations))) for rep, x_curr, simulations in self.repeat(starting_generator): like = self.postprocessing( rep, x_curr, simulations) # get obj function value # status setting update if like > objectivefunction_max: objectivefunction_max = like params_max = list(x_curr) params_max = self.fix_status_params_format(params_max) else: # now initial_iterations=1, using a user supplied initial solution. Calculate obj func value. repetions_left = repetitions - 1 # use this to reduce number of fevals in DDS loop rep, x_test_param, simulations = self.simulate( (0, x_initial)) # get from the inputs like = self.postprocessing(rep, x_test_param, simulations) if like > objectivefunction_max: objectivefunction_max = like params_max = list(x_test_param) params_max = self.fix_status_params_format(params_max) return params_max, repetions_left, objectivefunction_max
def fix_format(self): start_params = ParameterSet(self.para_func()) start_params.set_by_array([j for j in self.parameters]) self.parameters = start_params
def __init__(self, para_func, obj_value): self.para_func = para_func self.parameters = ParameterSet(self.para_func()) self.best_obj_val = obj_value self.best_rep = 0
def fix_status_params_format(self): start_params = ParameterSet(self.parameter()) start_params.set_by_array([j for j in self.status.params]) self.status.params = start_params
def fix_status_params_format(self, params_max): start_params = ParameterSet(self.parameter()) start_params.set_by_array([j for j in params_max]) return start_params