提交 d7d11150 编写于 作者: S stevenj

add set_max_objective to automate the sign flip for maximization

darcs-hash:20100405071650-c8de0-c7d3b05da048406f5004a4c9c46dccd6d2a41100.gz
上级 98a131d2
......@@ -130,6 +130,13 @@ namespace nlopt {
void set_min_objective(func *f) {
set_min_objective(myfunc, f);
}
void set_max_objective(nlopt_func f, void *f_data) {
nlopt_result ret = nlopt_set_max_objective(o, f, f_data);
mythrow(ret);
}
void set_max_objective(func *f) {
set_max_objective(myfunc, f);
}
// Nonlinear constraints:
......
......@@ -38,6 +38,7 @@ struct nlopt_opt_s {
unsigned n; /* the dimension of the problem (immutable) */
nlopt_func f; void *f_data; /* objective function to minimize */
int maximize; /* nonzero if we are maximizing, not minimizing */
double *lb, *ub; /* lower and upper bounds (length n) */
......@@ -50,7 +51,7 @@ struct nlopt_opt_s {
nlopt_constraint *h; /* equality constraints, length p_alloc */
/* stopping criteria */
double minf_max; /* stop when f < minf_max */
double stopval; /* stop when f reaches stopval or better */
double ftol_rel, ftol_abs; /* relative/absolute f tolerances */
double xtol_rel, *xtol_abs; /* rel/abs x tolerances */
int maxeval; /* max # evaluations */
......
......@@ -135,7 +135,7 @@ typedef enum {
NLOPT_INVALID_ARGS = -2,
NLOPT_OUT_OF_MEMORY = -3,
NLOPT_ROUNDOFF_LIMITED = -4,
NLOPT_STOPVAL_REACHED = 2,
NLOPT_SUCCESS = 1, /* generic success code */
NLOPT_MINF_MAX_REACHED = 2,
NLOPT_FTOL_REACHED = 3,
......@@ -144,6 +144,7 @@ typedef enum {
NLOPT_MAXTIME_REACHED = 6
} nlopt_result;
#define NLOPT_MINF_MAX_REACHED NLOPT_STOPVAL_REACHED
NLOPT_EXTERN void nlopt_srand(unsigned long seed);
NLOPT_EXTERN void nlopt_srand_time(void);
......@@ -173,6 +174,8 @@ NLOPT_EXTERN nlopt_result nlopt_optimize(nlopt_opt opt, double *x,
NLOPT_EXTERN nlopt_result nlopt_set_min_objective(nlopt_opt opt, nlopt_func f,
void *f_data);
NLOPT_EXTERN nlopt_result nlopt_set_max_objective(nlopt_opt opt, nlopt_func f,
void *f_data);
NLOPT_EXTERN nlopt_algorithm nlopt_get_algorithm(const nlopt_opt opt);
NLOPT_EXTERN unsigned nlopt_get_dimension(const nlopt_opt opt);
......@@ -204,7 +207,7 @@ NLOPT_EXTERN nlopt_result nlopt_add_equality_constraint(nlopt_opt opt,
/* stopping criteria: */
NLOPT_EXTERN nlopt_result nlopt_set_stopval(nlopt_opt opt, double minf_max);
NLOPT_EXTERN nlopt_result nlopt_set_stopval(nlopt_opt opt, double stopval);
NLOPT_EXTERN double nlopt_get_stopval(const nlopt_opt opt);
NLOPT_EXTERN nlopt_result nlopt_set_ftol_rel(nlopt_opt opt, double tol);
......
......@@ -69,8 +69,6 @@ typedef struct {
const double *lb, *ub;
} nlopt_data;
#include "praxis.h"
static double f_bound(int n, const double *x, void *data_)
{
int i;
......@@ -142,7 +140,8 @@ static int finite_domain(unsigned n, const double *lb, const double *ub)
(nlopt_stochastic_population > 0 ? \
nlopt_stochastic_population : (defaultpop)))
nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *minf)
/* unlike nlopt_optimize() below, only handles minimization case */
static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
{
const double *lb, *ub;
nlopt_algorithm algorithm;
......@@ -152,8 +151,9 @@ nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *minf)
nlopt_data d;
nlopt_stopping stop;
if (!opt || !x || !minf || !opt->f) return NLOPT_INVALID_ARGS;
if (!opt || !x || !minf || !opt->f
|| opt->maximize) return NLOPT_INVALID_ARGS;
/* copy a few params to local vars for convenience */
n = opt->n;
ni = (int) n; /* most of the subroutines take "int" arg */
......@@ -162,7 +162,7 @@ nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *minf)
f = opt->f; f_data = opt->f_data;
if (n == 0) { /* trivial case: no degrees of freedom */
*minf = f(n, x, NULL, f_data);
*minf = opt->f(n, x, NULL, opt->f_data);
return NLOPT_SUCCESS;
}
......@@ -183,7 +183,7 @@ nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *minf)
return NLOPT_INVALID_ARGS;
stop.n = n;
stop.minf_max = opt->minf_max;
stop.minf_max = opt->stopval;
stop.ftol_rel = opt->ftol_rel;
stop.ftol_abs = opt->ftol_abs;
stop.xtol_rel = opt->xtol_rel;
......@@ -512,6 +512,55 @@ nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *minf)
/*********************************************************************/
typedef struct {
nlopt_func f;
void *f_data;
} f_max_data;
/* wrapper for maximizing: just flip the sign of f and grad */
static double f_max(unsigned n, const double *x, double *grad, void *data)
{
f_max_data *d = (f_max_data *) data;
double val = d->f(n, x, grad, d->f_data);
if (grad) {
unsigned i;
for (i = 0; i < n; ++i)
grad[i] = -grad[i];
}
return -val;
}
nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *opt_f)
{
nlopt_func f; void *f_data;
f_max_data fmd;
int maximize;
nlopt_result ret;
if (!opt || !opt_f || !opt->f) return NLOPT_INVALID_ARGS;
f = opt->f; f_data = opt->f_data;
/* for maximizing, just minimize the f_max wrapper, which
flips the sign of everything */
if ((maximize = opt->maximize)) {
fmd.f = f; fmd.f_data = f_data;
opt->f = f_max; opt->f_data = &fmd;
opt->stopval = -opt->stopval;
}
ret = nlopt_optimize_(opt, x, opt_f);
if (maximize) { /* restore original signs */
opt->stopval = -opt->stopval;
opt->f = f; opt->f_data = f_data;
*opt_f = -*opt_f;
}
return ret;
}
/*********************************************************************/
nlopt_result nlopt_optimize_limited(nlopt_opt opt, double *x, double *minf,
int maxeval, double maxtime)
{
......
......@@ -56,6 +56,7 @@ nlopt_opt nlopt_create(nlopt_algorithm algorithm, unsigned n)
opt->algorithm = algorithm;
opt->n = n;
opt->f = NULL; opt->f_data = NULL;
opt->maximize = 0;
opt->lb = opt->ub = NULL;
opt->m = opt->m_alloc = 0;
......@@ -63,7 +64,7 @@ nlopt_opt nlopt_create(nlopt_algorithm algorithm, unsigned n)
opt->p = opt->p_alloc = 0;
opt->h = NULL;
opt->minf_max = -HUGE_VAL;
opt->stopval = -HUGE_VAL;
opt->ftol_rel = opt->ftol_abs = 0;
opt->xtol_rel = 0; opt->xtol_abs = NULL;
opt->maxeval = 0;
......@@ -158,6 +159,21 @@ nlopt_result nlopt_set_min_objective(nlopt_opt opt, nlopt_func f, void *f_data)
{
if (opt && f) {
opt->f = f; opt->f_data = f_data;
opt->maximize = 0;
if (nlopt_isinf(opt->stopval) && opt->stopval > 0)
opt->stopval = -HUGE_VAL;
return NLOPT_SUCCESS;
}
return NLOPT_INVALID_ARGS;
}
nlopt_result nlopt_set_max_objective(nlopt_opt opt, nlopt_func f, void *f_data)
{
if (opt && f) {
opt->f = f; opt->f_data = f_data;
opt->maximize = 1;
if (nlopt_isinf(opt->stopval) && opt->stopval < 0)
opt->stopval = +HUGE_VAL;
return NLOPT_SUCCESS;
}
return NLOPT_INVALID_ARGS;
......@@ -323,7 +339,7 @@ nlopt_result nlopt_add_equality_constraint(nlopt_opt opt,
#define GETSET(param, T, arg) GET(param, T, arg) SET(param, T, arg)
GETSET(stopval, double, minf_max)
GETSET(stopval, double, stopval)
GETSET(ftol_rel, double, ftol_rel)
GETSET(ftol_abs, double, ftol_abs)
......
......@@ -91,6 +91,7 @@ nlopt_result auglag_minimize(int n, nlopt_func f, void *f_data,
ret = nlopt_set_min_objective(sub_opt, auglag, &d); if (ret<0) return ret;
ret = nlopt_set_lower_bounds(sub_opt, lb); if (ret<0) return ret;
ret = nlopt_set_upper_bounds(sub_opt, ub); if (ret<0) return ret;
ret = nlopt_set_stopval(sub_opt, stop->minf_max); if (ret<0) return ret;
ret = nlopt_remove_inequality_constraints(sub_opt); if (ret<0) return ret;
ret = nlopt_remove_equality_constraints(sub_opt); if (ret<0) return ret;
for (i = 0; i < m; ++i) {
......
......@@ -231,6 +231,7 @@ nlopt_result mma_minimize(int n, nlopt_func f, void *f_data,
nlopt_set_min_objective(dual_opt, dual_func, &dd);
nlopt_set_lower_bounds(dual_opt, dual_lb);
nlopt_set_upper_bounds(dual_opt, dual_ub);
nlopt_set_stopval(dual_opt, -HUGE_VAL);
while (1) { /* outer iterations */
double fprev = fcur;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册