View source: R/analysis_solution.R
| solution_unique | R Documentation |
Return a reduced solutionset-class object containing one
representative from each group of equivalent solutions.
Solutions can be considered equivalent according to either their decision vectors or their objective values.
solution_unique(
x,
by = c("decisions", "objectives"),
keep = c("first", "last"),
objectives = NULL,
tolerance = sqrt(.Machine$double.eps)
)
x |
A |
by |
Character. Definition of uniqueness. One of
|
keep |
Character. Which representative to retain from each group of
equivalent solutions. If |
objectives |
Optional character vector of objective names to compare
when |
tolerance |
Non-negative numeric tolerance used when comparing
objective values. It is only used when |
solution_unique() is a solution-set management function. It removes
repeated solutions while consistently filtering the run table, design table,
stored run-level solutions, and summary tables.
Two definitions of uniqueness are supported:
by = "decisions" compares the complete stored decision vector
of each solution. Two solutions are considered equivalent when their
decision vectors are identical. This identifies repeated planning-unit or
planning-unit/action configurations, even when they were generated by
different runs or multi-objective parameter combinations.
by = "objectives" compares the selected objective values.
Two solutions are considered equivalent when all compared objective values
are equal within the specified numerical tolerance. Such solutions
may still have different decision vectors.
Consequently, uniqueness in objective space and uniqueness in decision space are not equivalent. Two spatially different solutions may produce the same objective values, while repeated runs may generate exactly the same decision vector.
Only runs with a stored solution_id can be assessed. Runs without a
stored solution, such as infeasible runs, are preserved unchanged. This
retains the full run history while removing only duplicated stored
solutions.
The function does not renumber run_id or solution_id. The
representative retained from each duplicate group keeps its original
identifiers, preserving traceability to the original run design.
For by = "objectives", numerical equality is assessed using a
relative comparison:
|a-b| \leq \epsilon \max(1, |a|, |b|),
where \epsilon is specified by tolerance. This avoids treating
insignificant floating-point differences as distinct objective points.
A new solutionset-class object containing one
representative from each group of equivalent stored solutions, together
with any runs that did not produce a stored solution.
solution_filter,
solution_append,
get_objectives,
# Load a complete simulated planning problem.
example_data <- load_sim_multiaction()
problem <- create_problem(
pu = example_data$planning_units,
features = example_data$features,
dist_features = example_data$dist_features,
cost = "cost"
) |>
add_actions(
example_data$actions,
cost = example_data$action_costs
) |>
add_effects(
example_data$effect_assumptions
) |>
add_constraint_targets_relative(0.05) |>
add_objective_min_cost(alias = "cost", include_pu_cost = FALSE) |>
add_objective_max_effect(alias = "benefit") |>
set_method_weighted_sum(
aliases = c("cost", "benefit"),
runs = set_runs_grid(n = 3),
normalize_weights = TRUE
)
if (requireNamespace("rcbc", quietly = TRUE)) {
problem <- set_solver_cbc(
problem,
verbose = FALSE
)
solutions <- solve(problem)
# Keep one representative for each distinct decision vector
unique_decisions <- solution_unique(
solutions,
by = "decisions"
)
# Keep one representative for each distinct objective point
unique_objectives <- solution_unique(
solutions,
by = "objectives"
)
# Compare only selected objectives
unique_cost_benefit <- solution_unique(
solutions,
by = "objectives",
objectives = c("cost", "benefit")
)
# Keep the last representative of each duplicate group
unique_last <- solution_unique(
solutions,
by = "decisions",
keep = "last"
)
# Compare the number of stored solutions
sum(!is.na(get_runs(solutions)$solution_id))
sum(!is.na(get_runs(unique_decisions)$solution_id))
sum(!is.na(get_runs(unique_objectives)$solution_id))
# Typical cleaning workflow
if (requireNamespace("moocore", quietly = TRUE)) {
clean_solutions <- solutions |>
solution_filter(
feasible_only = TRUE,
nondominated = TRUE
) |>
solution_unique(
by = "decisions"
)
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.