Skip to content

Commit e4f564c

Browse files
committed
Updated solverwrapper to meet new requirements, ran black
1 parent 93e1e7e commit e4f564c

2 files changed

Lines changed: 153 additions & 118 deletions

File tree

pyomo/contrib/multistart/multi.py

Lines changed: 152 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,169 @@
1212

1313
from pyomo.common.config import (
1414
ConfigBlock,
15+
ConfigDict,
1516
ConfigValue,
1617
In,
1718
document_kwargs_from_configdict,
19+
document_class_CONFIG,
20+
document_configdict,
21+
ADVANCED_OPTION,
1822
)
23+
1924
from pyomo.common.modeling import unique_component_name
2025
from pyomo.common.dependencies import numpy as np
2126
from pyomo.contrib.multistart.high_conf_stop import should_stop
2227
from pyomo.contrib.multistart.reinit import reinitialize_variables, strategies
2328
from pyomo.core import Objective, Var, minimize, value
29+
from pyomo.contrib.solver.common.base import SolverBase
30+
from pyomo.contrib.solver.common.config import SolverConfig
2431
from pyomo.contrib.solver.common.factory import SolverFactory
2532
from pyomo.contrib.solver.common.results import SolutionStatus
33+
2634
from pyomo.common.dependencies.scipy import stats
2735
from pyomo.common.dependencies import numpy as np
2836

2937
logger = logging.getLogger('pyomo.contrib.multistart')
3038

3139

40+
@document_configdict()
41+
class MultistartConfig(SolverConfig):
42+
def __init__(
43+
self,
44+
description=None,
45+
doc=None,
46+
implicit=False,
47+
implicit_domain=None,
48+
visibility=0,
49+
):
50+
super().__init__(
51+
description=description,
52+
doc=doc,
53+
implicit=implicit,
54+
implicit_domain=implicit_domain,
55+
visibility=visibility,
56+
)
57+
58+
self.strategy = self.declare(
59+
"strategy",
60+
ConfigValue(
61+
default="rand",
62+
domain=In(strategies.keys()),
63+
description="Specify the restart strategy. Defaults to rand.",
64+
doc="""Specify the restart strategy.
65+
66+
- "rand": random choice between variable bounds
67+
- "rand_vector": random choice, vectorized approach with sampler
68+
- "midpoint_guess_and_bound": midpoint between current value and farthest bound
69+
- "rand_guess_and_bound": random choice between current value and farthest bound
70+
- "rand_distributed": random choice among evenly distributed values
71+
- "midpoint": exact midpoint between the bounds. If using this option, multiple iterations are useless.
72+
""",
73+
),
74+
)
75+
self.solver = self.declare(
76+
"solver",
77+
ConfigValue(
78+
default="ipopt",
79+
description="solver to use, defaults to ipopt"
80+
"Should also be able to accept solver objects. In progress",
81+
),
82+
)
83+
self.solver_args = self.declare(
84+
"solver_args",
85+
ConfigValue(
86+
default={},
87+
description="Dictionary of keyword arguments to pass to the solver.",
88+
),
89+
)
90+
self.iterations = self.declare(
91+
"iterations",
92+
ConfigValue(
93+
default=10,
94+
description="Specify the number of iterations, defaults to 10. "
95+
"If -1 is specified, the high confidence stopping rule will be used",
96+
),
97+
)
98+
self.stopping_mass = self.declare(
99+
"stopping_mass",
100+
ConfigValue(
101+
default=0.5,
102+
description="Maximum allowable estimated missing mass of optima.",
103+
doc="""Maximum allowable estimated missing mass of optima for the
104+
high confidence stopping rule, only used with the random strategy.
105+
The lower the parameter, the stricter the rule.
106+
Value bounded in (0, 1].""",
107+
),
108+
)
109+
self.stopping_delta = self.declare(
110+
"stopping_delta",
111+
ConfigValue(
112+
default=0.5,
113+
description="1 minus the confidence level required for the stopping rule.",
114+
doc="""1 minus the confidence level required for the stopping rule for the
115+
high confidence stopping rule, only used with the random strategy.
116+
The lower the parameter, the stricter the rule.
117+
Value bounded in (0, 1].""",
118+
),
119+
)
120+
# self.surpress_unbounded_warning = self.declare(
121+
# "suppress_unbounded_warning",
122+
# ConfigValue(
123+
# default=False,
124+
# domain=bool,
125+
# description="True to suppress warning for skipping unbounded variables.",
126+
# ),
127+
# )
128+
self.HCS_max_iterations = self.declare(
129+
"HCS_max_iterations",
130+
ConfigValue(
131+
default=1000,
132+
description="Maximum number of iterations before interrupting the high confidence stopping rule.",
133+
),
134+
)
135+
self.HCS_tolerance = self.declare(
136+
"HCS_tolerance",
137+
ConfigValue(
138+
default=0,
139+
description="Tolerance on HCS objective value equality. Defaults to Python float equality precision.",
140+
),
141+
)
142+
self.break_on_solution = self.declare(
143+
"break_on_solution",
144+
ConfigValue(
145+
default=False,
146+
description="Condition to break if a feasible or optimal solution is found. Defaults to False.",
147+
),
148+
)
149+
self.sampling_method = self.declare(
150+
"sampling_method",
151+
ConfigValue(
152+
default="random_uniform",
153+
description="Method for sampling random starting points for reinitialization step. "
154+
"Supported options are 'random_uniform', 'latin_hypercube', and 'sobol_sampling'. "
155+
"Only utilized when config.strategy is 'rand_vector'.",
156+
),
157+
)
158+
self.seed = self.declare(
159+
"seed",
160+
ConfigValue(
161+
default=None,
162+
description="Seed for reproducibility in random sampling methods.",
163+
),
164+
)
165+
self.rng = self.declare(
166+
"rng",
167+
ConfigValue(
168+
default=None,
169+
description="Random number generator for reproducibility in random sampling methods. \
170+
Preferred over seed.",
171+
),
172+
)
173+
174+
32175
@SolverFactory.register('multistart', doc='MultiStart solver for NLPs')
33-
@document_kwargs_from_configdict('CONFIG')
34-
class MultiStart:
176+
@document_class_CONFIG(methods=['solve'])
177+
class MultiStart(SolverBase):
35178
"""Solver wrapper that initializes at multiple starting points.
36179
37180
# TODO: also return appropriate duals
@@ -43,122 +186,7 @@ class MultiStart:
43186
44187
"""
45188

46-
CONFIG = ConfigBlock("MultiStart")
47-
CONFIG.declare(
48-
"strategy",
49-
ConfigValue(
50-
default="rand",
51-
domain=In(strategies.keys()),
52-
description="Specify the restart strategy. Defaults to rand.",
53-
doc="""Specify the restart strategy.
54-
55-
- "rand": random choice between variable bounds
56-
- "rand_vector": random choice, vectorized approach with sampler
57-
- "midpoint_guess_and_bound": midpoint between current value and farthest bound
58-
- "rand_guess_and_bound": random choice between current value and farthest bound
59-
- "rand_distributed": random choice among evenly distributed values
60-
- "midpoint": exact midpoint between the bounds. If using this option, multiple iterations are useless.
61-
""",
62-
),
63-
)
64-
CONFIG.declare(
65-
"solver",
66-
ConfigValue(
67-
default="ipopt",
68-
description="solver to use, defaults to ipopt"
69-
"Should also be able to accept solver objects. In progress",
70-
),
71-
)
72-
CONFIG.declare(
73-
"solver_args",
74-
ConfigValue(
75-
default={},
76-
description="Dictionary of keyword arguments to pass to the solver.",
77-
),
78-
)
79-
CONFIG.declare(
80-
"iterations",
81-
ConfigValue(
82-
default=10,
83-
description="Specify the number of iterations, defaults to 10. "
84-
"If -1 is specified, the high confidence stopping rule will be used",
85-
),
86-
)
87-
CONFIG.declare(
88-
"stopping_mass",
89-
ConfigValue(
90-
default=0.5,
91-
description="Maximum allowable estimated missing mass of optima.",
92-
doc="""Maximum allowable estimated missing mass of optima for the
93-
high confidence stopping rule, only used with the random strategy.
94-
The lower the parameter, the stricter the rule.
95-
Value bounded in (0, 1].""",
96-
),
97-
)
98-
CONFIG.declare(
99-
"stopping_delta",
100-
ConfigValue(
101-
default=0.5,
102-
description="1 minus the confidence level required for the stopping rule.",
103-
doc="""1 minus the confidence level required for the stopping rule for the
104-
high confidence stopping rule, only used with the random strategy.
105-
The lower the parameter, the stricter the rule.
106-
Value bounded in (0, 1].""",
107-
),
108-
)
109-
CONFIG.declare(
110-
"suppress_unbounded_warning",
111-
ConfigValue(
112-
default=False,
113-
domain=bool,
114-
description="True to suppress warning for skipping unbounded variables.",
115-
),
116-
)
117-
CONFIG.declare(
118-
"HCS_max_iterations",
119-
ConfigValue(
120-
default=1000,
121-
description="Maximum number of iterations before interrupting the high confidence stopping rule.",
122-
),
123-
)
124-
CONFIG.declare(
125-
"HCS_tolerance",
126-
ConfigValue(
127-
default=0,
128-
description="Tolerance on HCS objective value equality. Defaults to Python float equality precision.",
129-
),
130-
)
131-
CONFIG.declare(
132-
"break_on_solution",
133-
ConfigValue(
134-
default=False,
135-
description="Condition to break if a feasible or optimal solution is found. Defaults to False.",
136-
),
137-
)
138-
CONFIG.declare(
139-
"sampling_method",
140-
ConfigValue(
141-
default="random_uniform",
142-
description="Method for sampling random starting points for reinitialization step. "
143-
"Supported options are 'random_uniform', 'latin_hypercube', and 'sobol_sampling'. "
144-
"Only utilized when config.strategy is 'rand_vector'.",
145-
),
146-
)
147-
CONFIG.declare(
148-
"seed",
149-
ConfigValue(
150-
default=None,
151-
description="Seed for reproducibility in random sampling methods.",
152-
),
153-
)
154-
CONFIG.declare(
155-
"rng",
156-
ConfigValue(
157-
default=None,
158-
description="Random number generator for reproducibility in random sampling methods. \
159-
Preferred over seed.",
160-
),
161-
)
189+
CONFIG = MultistartConfig()
162190

163191
def available(self, exception_flag=True):
164192
"""Check if solver is available.
@@ -169,6 +197,12 @@ def available(self, exception_flag=True):
169197
"""
170198
return True
171199

200+
def version(self):
201+
"""Get solver version
202+
TODO: This is a solver wrapper, unsure how to define version in this case."""
203+
204+
return
205+
172206
def license_is_valid(self):
173207
return True
174208

pyomo/devel/initialization/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
initialize_with_LP_approximation,
1212
initialize_with_piecewise_linear_approximation,
1313
initialize_with_global_opt,
14+
initialize_with_multistart_opt,
1415
)

0 commit comments

Comments
 (0)