-
Notifications
You must be signed in to change notification settings - Fork 591
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add AGS global solver #194
Conversation
fca7b8f
to
886d963
Compare
d702ae0
to
8c9a836
Compare
PR is done, but may be I missed some tricky integration moments. |
8c9a836
to
7743d22
Compare
doc/docs/NLopt_Algorithms.md
Outdated
@@ -31,7 +31,7 @@ Better yet, run some algorithm for a really long time until the minimum *f*<sub> | |||
Global optimization | |||
------------------- | |||
|
|||
All of the global-optimization algorithms currently require you to specify bound constraints on all the optimization parameters. Of these algorithms, only ISRES and ORIG_DIRECT support nonlinear inequality constraints, and only ISRES supports nonlinear equality constraints. (However, any of them can be applied to nonlinearly constrained problems by combining them with the [augmented Lagrangian method](#Augmented_Lagrangian_algorithm.md) below.) | |||
All of the global-optimization algorithms currently require you to specify bound constraints on all the optimization parameters. Of these algorithms, only ISRES, AGS and ORIG_DIRECT support nonlinear inequality constraints, and only ISRES supports nonlinear equality constraints. (However, any of them can be applied to nonlinearly constrained problems by combining them with the [augmented Lagrangian method](#Augmented_Lagrangian_algorithm.md) below.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add serial comma after AGS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't know that, used rules from Russian :)
doc/docs/NLopt_Algorithms.md
Outdated
AGS can handle arbitrary objectives and nonlinear inequality constraints. Also bound constraints are required for this method. To guarantee convergence, objectives and constraints should satisfy the Lipschitz condition on the specified hyperrectangle. | ||
AGS is derivative-free and employs the Hilbert curve to reduce the source problem to the univariate one. The algorithm divides the univariate space into intervals, generating new points by using posterior probabilities. On each trial AGS tries to evaluate the constraints consequently one by one. If some constraint is violated at this point, the next ones won't be evaluated. If all constraints are preserved, i.e. the trial point is feasible, AGS will evaluate the objective. Thus, some of constraints (except the first one) and objective can be partially undefined inside the search hyperrectangle. Current implementation of AGS doesn't support vector constraints. | ||
|
||
Limitations of the machine arithmetic don't allow to build a tight approximation for Hilbert when the space dimension is greater than 5, so this implementation of AGS is restricted in that sense. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is just slightly less reliable for dimensions > 5, it is probably worth allowing it to be used there so that people can experiment… or does the code not work at all in higher dimensions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, increased the limit to 10, added a warning that sometimes the method can stop early for high-dimensional problems.
src/api/options.c
Outdated
@@ -437,7 +437,8 @@ static int inequality_ok(nlopt_algorithm algorithm) { | |||
|| AUGLAG_ALG(algorithm) | |||
|| algorithm == NLOPT_GN_ISRES | |||
|| algorithm == NLOPT_GN_ORIG_DIRECT | |||
|| algorithm == NLOPT_GN_ORIG_DIRECT_L); | |||
|| algorithm == NLOPT_GN_ORIG_DIRECT_L | |||
|| algorithm == NLOPT_GN_AGS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indenting
Overall, this looks great, modulo minor comments, though I haven't tried out your code myself yet. |
I got these warnings compiling with -Wall, you might want to fix them:
|
If I modify test/t_python.py to use AGS:
I've got:
and same bounds with LD_MMA:
Does that look ok? |
I've fixed the warnings. If I reduce the bounds to opt.set_lower_bounds([-8, 0])
opt.set_upper_bounds([8, 8]) output will be OK
The result is slightly imprecise because of the Hilbert curve, but usually the global solution is coarse and can be used as a starting point for a fast local optimizer. Result of
Evals counter is seems to be broken. |
Yes, the eval counter is always 0 with AGS maybe your |
I fixed the counter in the last commit by adding |
Yes, it's ok now. |
tst.cc should be moved to /tests and added to the testsuite |
I've meant |
It's fine to add it to the common test as you did. |
I dont see AGS in inequality_ok function (src/api/options.c:~432), did you test inequality constraints ? |
It's on the line 441, after || algorithm == NLOPT_GN_ORIG_DIRECT_L
|| algorithm == NLOPT_GN_AGS); |
I looked at the wrong branch, sorry |
Why do you need c++11 again ? You're using c++, but you don't even seem to instanciate objects: all your functions could be marked as static and attributes are used as class attributes. I may be wrong but plain C might as well be used. |
Yes, one can use plain pointers in public interface and write sufficient wrappers for nlopt functions. |
Ok, dont change your code, cxx11 is fine by me. It's just that it did not look very c++-ish at first glance, so I had to ask. |
What am I supposed to do next to get this merged? |
Whoops, I just noticed you are missing a license and readme file. I assume it is the same as in https://github.com/sovrasov/glob_search_nlp_solver and will copy the license file from there. |
Thanks for merge! I"ll add them soon in the next PR. |
I just added them in 174ed18 … submit a PR to edit them as needed. |
Your version is ok for me. |
I just pushed a fix for the numevals counter in ORIG_DIRECT |
|
||
ags::SolverParameters params; | ||
params.r = ags_r; | ||
params.itersLimit = stop->maxeval != 0 ? stop->maxeval : 5000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wrong — maxeval == 0
denotes no maximum, not 5000 iterations. If you must set it to a specific value, use INT_MAX
.
@sovrasov, it doesn't look like you support the For example, see how CRS does it: Lines 135 to 138 in 24fc75f
forced_stop is especially important for languages like Python, because it is how we handle exceptions thrown by the objective function. |
Related to #192
This PR adds AGS global solver. Unlike most other global methods presented in NLOpt it can handle nonlinear inequality constraints.