-
Notifications
You must be signed in to change notification settings - Fork 32
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the Bug
Application of STRONG solver to minimizing the 2 dimensional Rosenbrock function from starting point (-1.2, 1.0) without supplying the gradients seems to terminate after 10 function evaluations without progress. recommended_solns only contains the initial value.
Steps To Reproduce
Run
import numpy as np
from scipy.optimize import rosen
from mrg32k3a.mrg32k3a import MRG32k3a
from simopt.base import Model, Problem, ConstraintType, VariableType
initial_solution = (-1.2, 1.0)
class ExampleModel(Model):
@property
def name(self) -> str: return "EXAMPLE"
@property
def n_rngs(self) -> int: return 1
@property
def n_responses(self) -> int: return 1
@property
def specifications(self) -> dict: return {"x": {"description": "point to evaluate", "datatype": tuple, "default": initial_solution}}
@property
def check_factor_list(self) -> dict: return {"x": self.check_x}
def __init__(self, fixed_factors=None): super().__init__(fixed_factors)
def check_x(self) -> bool: return True
def replicate(self, rng_list: list[MRG32k3a]) -> tuple[dict, dict]:
x = np.array(self.factors["x"])
return {"est_f(x)": rosen(x)}, {}
class ExampleProblem(Problem):
@property
def n_objectives(self) -> int: return 1
@property
def n_stochastic_constraints(self) -> int: return 0
@property
def minmax(self) -> tuple[int]: return (-1,)
@property
def constraint_type(self) -> ConstraintType: return ConstraintType.UNCONSTRAINED
@property
def variable_type(self) -> VariableType: return VariableType.CONTINUOUS
@property
def gradient_available(self) -> bool: return False
@property
def optimal_value(self) -> float: return 0.0
@property
def optimal_solution(self) -> tuple: return (0,) * self.dim
@property
def model_default_factors(self) -> dict: return {}
@property
def model_decision_factors(self) -> set: return {"x"}
@property
def check_factor_list(self) -> dict: return {"initial_solution": self.check_initial_solution, "budget": self.check_budget}
@property
def specifications(self) -> dict: return {"initial_solution": {"description": "initial solution", "datatype": tuple, "default": initial_solution}, "budget": {"description": "max # of replications", "datatype": int, "default": 10000}}
@property
def dim(self) -> int: return len(self.factors["initial_solution"])
@property
def lower_bounds(self) -> tuple: return (-np.inf,) * self.dim
@property
def upper_bounds(self) -> tuple: return (np.inf,) * self.dim
def __init__(self, name="EXAMPLE-1", fixed_factors=None, model_fixed_factors=None):
super().__init__(name=name, fixed_factors=fixed_factors, model_fixed_factors=model_fixed_factors, model=ExampleModel)
def vector_to_factor_dict(self, vector: tuple) -> dict: return {"x": vector}
def factor_dict_to_vector(self, factor_dict: dict) -> tuple: return tuple(factor_dict["x"])
def response_dict_to_objectives(self, response_dict: dict) -> tuple: return (response_dict["est_f(x)"],)
def response_dict_to_stoch_constraints(self, response_dict: dict) -> tuple: return ()
def get_random_solution(self, rand_sol_rng: MRG32k3a) -> tuple:
return tuple(rand_sol_rng.mvnormalvariate(mean_vec=np.zeros(self.dim), cov=np.eye(self.dim), factorized=False))
if __name__ == "__main__":
from simopt.solvers.strong import STRONG
problem = ExampleProblem()
solver = STRONG()
rng = [MRG32k3a()]
solver.attach_rngs(rng)
solver.solution_progenitor_rngs = [MRG32k3a()]
recommended_solns, budgets = solver.solve(problem)
print("budget=", budgets, "recommended_solns=", [sol.x for sol in recommended_solns])My output
budget= [10] recommended_solns= [(-1.2, 1.0)]
Expected Behavior
I would expect the solver to make some progress starting from the initial solution.
Environment
Please provide some details about your environment to help us replicate the bug:
- Operating System: macOS
- Python Version: 3.12.4
- SIMOPT version 1.1.0 (master version installed last week)
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working