% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/set_method_augmecon.R
\name{set_method_augmecon}
\alias{set_method_augmecon}
\title{Set the AUGMECON multi-objective method}
\usage{
set_method_augmecon(
  x,
  primary,
  aliases = NULL,
  grid = NULL,
  n_points = 10,
  include_extremes = TRUE,
  lexicographic = TRUE,
  lexicographic_tol = 1e-09,
  augmentation = 0.001,
  slack_upper_bound = 1e+06
)
}
\arguments{
\item{x}{A \code{Problem} object.}

\item{primary}{Character string giving the alias of the primary objective,
that is, the objective optimized directly in the AUGMECON formulation.}

\item{aliases}{Optional character vector of objective aliases to include in
the method. If \code{NULL}, all registered objective aliases are used. The
value of \code{primary} must be included in \code{aliases}.}

\item{grid}{Optional named list defining manual epsilon levels for the
secondary objectives. Each name must correspond to a secondary objective
alias, and each element must be a non-empty numeric vector of finite
values. If \code{NULL}, the grid is generated automatically.}

\item{n_points}{Number of automatically generated epsilon levels per
secondary objective when \code{grid = NULL}. Must be at least 2. Ignored
when \code{grid} is supplied.}

\item{include_extremes}{Logical. If \code{TRUE}, automatically generated
grids include extreme values of each secondary objective.}

\item{lexicographic}{Logical. If \code{TRUE}, use lexicographic anchoring
when computing extreme points for automatic grid construction.}

\item{lexicographic_tol}{Non-negative numeric tolerance used in
lexicographic anchoring.}

\item{augmentation}{Positive numeric augmentation coefficient
\eqn{\rho}. The effective coefficient of each secondary slack is computed
internally as \eqn{\rho / R_k}, where \eqn{R_k} is the payoff-table range
of the corresponding secondary objective.}

\item{slack_upper_bound}{Positive numeric upper bound imposed on the explicit
non-negative slack variables associated with the secondary objectives.}
}
\value{
The updated \code{Problem} object with the AUGMECON method
configuration stored in \code{x$data$method}.
}
\description{
Configure a \code{Problem} object to be solved with the augmented
epsilon-constraint method (AUGMECON).

AUGMECON is an exact multi-objective optimization method in which one
objective is treated as the primary objective and the remaining objectives
are converted into \eqn{\varepsilon}-constraints. In the augmented formulation,
each secondary objective is associated with a non-negative slack variable,
and the primary objective is augmented with a small reward term based on the
normalized slacks. This augmentation is used to avoid weakly efficient
solutions, following Mavrotas (2009).

This function does not solve the problem directly. It stores the AUGMECON
configuration in \code{x$data$method}, to be used later by
\code{\link{solve}}.
}
\details{
Use this method when one objective should be optimized directly, the
remaining objectives should be controlled through epsilon levels, and weakly
efficient solutions should be reduced through the augmented formulation.

\strong{General idea}

Suppose that \eqn{m \ge 2} objective functions have already been registered
in the problem:
\deqn{
f_1(x), f_2(x), \dots, f_m(x).
}

AUGMECON selects one of them as the primary objective, say
\eqn{f_p(x)}, and treats the remaining \eqn{m - 1} objectives as secondary
objectives.

For a fixed combination of epsilon levels, the method solves a sequence of
single-objective subproblems of the form:

\deqn{
\max \; f_p(x) + \rho \sum_{k \in \mathcal{S}} \frac{s_k}{R_k}
}

subject to

\deqn{
f_k(x) - s_k = \varepsilon_k, \qquad k \in \mathcal{S},
}

\deqn{
s_k \ge 0, \qquad k \in \mathcal{S},
}

together with all original feasibility constraints of the planning problem.

Here:
\itemize{
\item \eqn{f_p(x)} is the primary objective,
\item \eqn{\mathcal{S}} is the set of secondary objectives,
\item \eqn{\varepsilon_k} is the imposed level for secondary objective
\eqn{k},
\item \eqn{s_k} is a non-negative slack variable,
\item \eqn{R_k} is the payoff-table range used to normalize objective
\eqn{k},
\item \eqn{\rho > 0} is a small augmentation coefficient.
}

In the original AUGMECON formulation of Mavrotas (2009), the augmentation
term ensures that, among solutions with the same primary objective value, the
solver prefers those with larger normalized slack, thereby avoiding weakly
efficient points and improving Pareto-front generation.

\strong{Secondary-objective equalities and slacks}

The key difference between standard epsilon-constraint and AUGMECON is that
the secondary objectives are written as equalities with slacks rather than as
simple inequalities. For a maximization-type secondary objective, this takes
the form:

\deqn{
f_k(x) - s_k = \varepsilon_k, \qquad s_k \ge 0.
}

This implies:
\deqn{
f_k(x) \ge \varepsilon_k,
}

while explicitly measuring the excess above the imposed epsilon level through
\eqn{s_k}. The augmentation term then rewards such excess in normalized form.

In implementation terms, the exact sign convention for each objective depends
on whether it is internally treated as a minimization or maximization
objective, but the method always preserves the same AUGMECON principle:
\itemize{
\item one objective is optimized directly,
\item all others are turned into constrained objectives,
\item non-negative slacks measure controlled deviation from the imposed
epsilon levels,
\item the primary objective is augmented with a small slack-based reward.
}

\strong{Manual and automatic epsilon grids}

AUGMECON requires a grid of epsilon levels for each secondary objective.

If \code{grid} is supplied, it must be a named list with one numeric vector
per secondary objective. Each vector defines the exact epsilon levels to be
explored for that objective.

If \code{grid = NULL}, the grid is generated automatically later during
\code{\link{solve}}. In that case, the method first computes extreme points
and payoff-table ranges for the secondary objectives, and then generates
\code{n_points} levels for each one.

If \code{include_extremes = TRUE}, the automatic grid includes the extreme
values of each secondary objective.

If \code{lexicographic = TRUE}, extreme points are computed using
lexicographic anchoring, which can improve payoff-table quality when
objectives are tightly competing. The tolerance used for lexicographic
anchoring is controlled by \code{lexicographic_tol}.

\strong{Normalization and augmentation}

The augmentation term is scaled using the payoff-table ranges of the
secondary objectives. If \eqn{R_k} denotes the range of secondary objective
\eqn{k}, then the effective coefficient applied to the slack is:

\deqn{
\frac{\rho}{R_k},
}

where \eqn{\rho = \code{augmentation}}.

This normalization is important because different objectives may be measured
on very different numerical scales. Without normalization, a slack belonging
to a large-scale objective could dominate the augmentation term simply due to
units.

In this implementation, the user supplies \code{augmentation} as the base
coefficient \eqn{\rho}, while the normalized slack coefficients are computed
internally at solve time using the corresponding payoff-table ranges.

\strong{Stored configuration}

This function stores the method definition in \code{x$data$method} with:
\itemize{
\item \code{name = "augmecon"},
\item the primary objective alias,
\item the full set of participating aliases,
\item the set of secondary aliases,
\item either a manual grid or the information required to generate one
automatically,
\item augmentation and slack-bound parameters.
}

The actual payoff table, grid construction, and subproblem solution loop are
performed later by \code{\link{solve}}.
}
\examples{
# Small toy problem
pu_tbl <- data.frame(
  id = 1:4,
  cost = c(1, 2, 3, 4)
)

feat_tbl <- data.frame(
  id = 1:2,
  name = c("feature_1", "feature_2")
)

dist_feat_tbl <- data.frame(
  pu = c(1, 1, 2, 3, 4),
  feature = c(1, 2, 2, 1, 2),
  amount = c(5, 2, 3, 4, 1)
)

actions_df <- data.frame(
  id = c("conservation", "restoration"),
  name = c("conservation", "restoration")
)

effects_df <- data.frame(
  pu = c(1, 2, 3, 4, 1, 2, 3, 4),
  action = c("conservation", "conservation", "conservation", "conservation",
             "restoration", "restoration", "restoration", "restoration"),
  feature = c(1, 1, 1, 1, 2, 2, 2, 2),
  benefit = c(2, 1, 0, 1, 3, 0, 1, 2),
  loss = c(0, 0, 1, 0, 0, 1, 0, 0)
)

x <- create_problem(
  pu = pu_tbl,
  features = feat_tbl,
  dist_features = dist_feat_tbl,
  cost = "cost"
) |>
  add_actions(actions_df, cost = c(conservation = 1, restoration = 2)) |>
  add_effects(effects_df) |>
  add_objective_max_benefit(alias = "benefit") |>
  add_objective_min_cost(alias = "cost") |>
  add_objective_min_loss(alias = "loss")

# Automatic epsilon grids generated later during solve()
x1 <- set_method_augmecon(
  x,
  primary = "benefit",
  aliases = c("benefit", "cost"),
  n_points = 5,
  include_extremes = TRUE,
  lexicographic = TRUE,
  augmentation = 1e-3
)

x1$data$method

# Manual epsilon grids for two secondary objectives
x2 <- set_method_augmecon(
  x,
  primary = "benefit",
  aliases = c("benefit", "cost", "loss"),
  grid = list(
    cost = c(4, 6, 8),
    loss = c(0, 1)
  ),
  augmentation = 1e-3,
  slack_upper_bound = 1e6
)

x2$data$method

}
\references{
Mavrotas, G. (2009). Effective implementation of the
\eqn{\varepsilon}-constraint method in multi-objective mathematical programming
problems. \emph{Applied Mathematics and Computation}, 213(2), 455--465.
}
\seealso{
\code{\link{set_method_epsilon_constraint}},
\code{\link{set_method_weighted_sum}},
\code{\link{solve}}
}
