Serial Solver Execution¶
You may want to run the solver several times iteratively when evaluating performance. Also, some solvers are more likely to find a good solution by running several iterations with a short timeout than by running a single iteration with a long timeout.Amplify SDK allows running the same combinatorial optimization problem multiple times in a row with the same solver for such needs.
See also
Parallel Solver Execution may be more appropriate for obtaining statistics from multiple runs for formulation, solver performance studies, etc.
Example of multiple runs¶
First, create a model and solver client as in a usual solve()
function execution.
from amplify import VariableGenerator, one_hot, FixstarsClient, solve
from datetime import timedelta
gen = VariableGenerator()
q = gen.array("Binary", 3)
objective = q[0] * q[1]  q[2]
constraint = one_hot(q)
model = objective + constraint
client = FixstarsClient()
# client.token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
client.parameters.timeout = timedelta(milliseconds=1000)
By passing an integer as the num_solves
keyword argument to solve()
, the solver is executed iteratively for num_solves
times.
result = solve(model, client, num_solves=3)
As in a usual solve()
call, the solver returns an instance of the Result
class. The return value contains the results of the num_solves iterations.
>>> len(result)
3
Using the best
attribute, you can obtain the best solution among those returned by the num_solves
runs.
>>> print(f"objective = {result.best.objective}, q = {q.evaluate(result.best.values)}")
objective = 1.0, q = [0. 0. 1.]
Fetching results¶
When solve()
is called with the num_solves
keyword, the return value is an instance of the Result
class, as usual.
The Amplify SDK determines the number of times of the solver executions by the num_solves
attribute of the Result
class. This attribute usually yields the same value as the value specified to solve()
as the num_solves
keyword argument. Still, it may be less than the value specified as the num_solves
keyword argument, if some of the solver runs, fail for some reason.
>>> result.num_solves
3
Index or iteration access allows you to aggregate all the solutions the solver returns for the num_solves
runs. By default, the Amplify SDK sorts them in order of preferred solution, and there is no distinction regarding the number of executions the solution was found.
>>> print(f"objective = {result[0].objective}, q = {q.evaluate(result[0].values)}")
objective = 1.0, q = [0. 0. 1.]
Use the split
property to get only the solutions returned by a particular run.
>>> first_result = result.split[0] # extract only the part of the `result` that was obtained at the first run
>>> type(first_result)
<class 'amplify.Result'>
>>> len(first_result)
1
>>> print(f"objective = {first_result.best.objective}, q = {q.evaluate(first_result.best.values)}")
objective = 1.0, q = [0. 0. 1.]
The following are included for each property of the Result
object returned by solve()
when num_solves
is specified, and the Result
object represents the result of the i
th run obtained by using the split
property on it.
Property name 


The best solution for the 
The best solution for the 

All solutions obtained for the 
All solutions obtained for the 

Same as usual 
Same as usual 

Same as usual 
Same as usual 

Property obtained for the first run 
Property obtained for the 

The sum of the 
Property obtained for the 

The sum of the 
Property obtained for the 

Time from the start to the end of 
Time used for the 