% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/add_profit.R
\name{add_profit}
\alias{add_profit}
\title{Add profit to a planning problem}
\usage{
add_profit(x, profit = NULL)
}
\arguments{
\item{x}{A \code{Problem} object created with \code{\link{create_problem}}. It
must already contain feasible actions and an action catalogue; run
\code{\link{add_actions}} first.}

\item{profit}{Profit specification. One of:
\itemize{
\item \code{NULL}: profit is set to 0 for all feasible
\code{(pu, action)} pairs,
\item a numeric scalar: recycled to all feasible pairs,
\item a named numeric vector: names are action ids and values define
action-level profit,
\item a \code{data.frame(action, profit)} defining action-level profit,
\item a \code{data.frame(pu, action, profit)} defining pair-specific
profit.
}}
}
\value{
An updated \code{Problem} object with a stored profit table created
or replaced. The stored table contains columns \code{pu}, \code{action},
\code{profit}, \code{internal_pu}, and \code{internal_action}, and
includes only rows with non-zero profit.
}
\description{
Define economic profit values for feasible planning unit--action pairs and
store them in a profit table.

Profit is stored separately from ecological effects. In particular,
\code{profit} is not the same as ecological \code{benefit} or
\code{loss} as represented in \code{\link{add_effects}}. This separation
allows the package to distinguish economic returns from ecological
consequences when building objectives, constraints, and reporting summaries.
}
\details{
\strong{When to use \code{add_profit()}.}

Use this function when economic returns, penalties, or other action-specific
financial values are part of the planning problem. Typical downstream uses
include objectives such as \code{\link{add_objective_max_profit}} and
\code{\link{add_objective_max_net_profit}}.

Let \eqn{\mathcal{I}} denote the set of planning units and
\eqn{\mathcal{A}} the set of actions. Let
\eqn{\mathcal{D} \subseteq \mathcal{I} \times \mathcal{A}} denote the set of
feasible planning unit--action pairs currently stored in the problem.

This function assigns to each feasible pair \eqn{(i,a) \in \mathcal{D}} a
numeric profit value \eqn{\pi_{ia} \in \mathbb{R}} and stores the result in a
profit table.

Thus, the stored table can be interpreted as a mapping
\deqn{
\pi : \mathcal{D} \to \mathbb{R},
}
where \eqn{\pi_{ia}} represents the economic return associated with selecting
action \eqn{a} in planning unit \eqn{i}.

Profit values may be positive, zero, or negative. Positive values represent
gains or revenues, zero represents no net profit contribution, and negative
values can be used to encode penalties or net economic losses.

The stored table contains:
\itemize{
\item \code{pu}: external planning-unit id,
\item \code{action}: action id,
\item \code{profit}: numeric profit value,
\item \code{internal_pu}: internal planning-unit index,
\item \code{internal_action}: internal action index.
}

\strong{Supported input formats}

The \code{profit} argument may be specified in several ways:
\itemize{
\item \code{NULL}: assign profit 0 to all feasible \code{(pu, action)}
pairs,
\item a numeric scalar: assign the same profit value to all feasible pairs,
\item a named numeric vector: names are action ids, assigning one global
profit value per action,
\item a \code{data.frame(action, profit)}: assign one global profit value
per action,
\item a \code{data.frame(pu, action, profit)}: assign pair-specific profit
values.
}

When action-level profit is supplied, the same profit value is assigned to
all feasible planning units for that action. When pair-specific profit is
supplied, only the listed \code{(pu, action)} pairs receive explicit values;
unmatched feasible pairs are interpreted as zero-profit pairs.

\strong{Storage behaviour}

This function stores only rows with non-zero profit values. Feasible pairs
whose final profit is zero are omitted from the stored profit table.
Missing values produced during matching or joins are treated as zero before
this filtering step. Therefore, the resulting table is a sparse
representation of economic returns over the feasible decision space.

\strong{Data-only behaviour}

This function is purely data-oriented. It does not build or modify the
optimization model, and it does not change feasibility. It simply assigns
profit values to rows already present in the feasible action table.

In particular:
\itemize{
\item it does not add new feasible \code{(pu, action)} pairs,
\item it does not remove infeasible pairs,
\item it does not apply solver-side filtering such as dropping locked-out
decisions,
\item it does not modify ecological effect tables.
}

Any such filtering is expected to occur later when model-ready tables are
prepared, typically during the build stage invoked by \code{solve()}.

\strong{Use in optimization}

Profit values stored by this function can later be used in objectives such as
\code{\link{add_objective_max_profit}} or
\code{\link{add_objective_max_net_profit}}, in derived budget expressions, or
in reporting and summary functions.

For example, if \eqn{x_{ia} \in \{0,1\}} denotes whether action \eqn{a} is
selected in planning unit \eqn{i}, then a profit-maximization objective
typically takes the form
\deqn{
\max \sum_{(i,a) \in \mathcal{D}} \pi_{ia} x_{ia}.
}
}
\examples{
# Minimal problem
pu <- data.frame(
  id = 1:4,
  cost = c(2, 3, 1, 4)
)

features <- data.frame(
  id = 1:2,
  name = c("sp1", "sp2")
)

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

p <- create_problem(
  pu = pu,
  features = features,
  dist_features = dist_features
)

p <- add_actions(
  x = p,
  actions = data.frame(id = c("harvest", "restoration"))
)

# 1) Constant profit for every feasible (pu, action)
p1 <- add_profit(p, profit = 10)
p1$data$dist_profit

# 2) Profit per action using a named vector
pr <- c(harvest = 50, restoration = -5)
p2 <- add_profit(p, profit = pr)
p2$data$dist_profit

# 3) Profit per action using a data frame
pr_df <- data.frame(
  action = c("harvest", "restoration"),
  profit = c(40, 15)
)
p3 <- add_profit(p, profit = pr_df)
p3$data$dist_profit

# 4) Profit per (pu, action) pair
pr_pair <- data.frame(
  pu = c(1, 2, 3),
  action = c("harvest", "harvest", "restoration"),
  profit = c(100, 80, 30)
)
p4 <- add_profit(p, profit = pr_pair)
p4$data$dist_profit

}
\seealso{
\code{\link{add_actions}},
\code{\link{add_objective_max_profit}},
\code{\link{add_objective_max_net_profit}},
\code{\link{add_effects}}
}
