Add constraints to a project prioritization problem()
to ensure
that specific actions are prioritized for funding in the solution. For
example, it may be desirable to lock in actions for conserving culturally or
taxonomically important species.
add_locked_in_constraints(x, locked_in)
# S4 method for ProjectProblem,numeric
add_locked_in_constraints(x, locked_in)
# S4 method for ProjectProblem,logical
add_locked_in_constraints(x, locked_in)
# S4 method for ProjectProblem,character
add_locked_in_constraints(x, locked_in)
ProjectProblem object.
Object that determines which planning units that should be locked in. See the Details section for more information.
ProjectProblem object with the constraints added to it.
The locked actions can be specified in several different ways:
integer
vector
of indices pertaining to which
actions should be locked in the solution (i.e. row numbers of the
actions in the argument to actions
in problem()
).
logical
vector
containing logical
(i.e. TRUE
and/or FALSE
values) that indicate which
actions should be locked in the solution. These logical
values should correspond to each row in the argument to actions
in problem()
).
character
column name that indicates if actions
units should be locked in the solution. This argument
should denote a column in the argument to actions
in problem()
which contains logical
(i.e. TRUE
and/or FALSE
values) to indicate
which actions should be locked.
# load data
data(sim_projects, sim_features, sim_actions)
# print action data
print(sim_actions)
#> # A tibble: 6 × 4
#> name cost locked_in locked_out
#> <chr> <dbl> <lgl> <lgl>
#> 1 F1_action 94.4 FALSE FALSE
#> 2 F2_action 101. FALSE FALSE
#> 3 F3_action 103. TRUE FALSE
#> 4 F4_action 99.2 FALSE FALSE
#> 5 F5_action 99.9 FALSE TRUE
#> 6 baseline_action 0 FALSE FALSE
# build problem with maximum richness objective and $150 budget
p1 <- problem(sim_projects, sim_actions, sim_features,
"name", "success", "name", "cost", "name") %>%
add_max_richness_objective(budget = 150) %>%
add_binary_decisions()
# print problem
print(p1)
#> Project Prioritization Problem
#> actions F1_action, F2_action, F3_action, ... (6 actions)
#> projects F1_project, F2_project, F3_project, ... (6 projects)
#> features F1, F2, F3, ... (5 features)
#> action costs: min: 0, max: 103.22583
#> project success: min: 0.81379, max: 1
#> objective: Maximum richness objective [budget (150)]
#> targets: none
#> weights: default
#> decisions Binary decision
#> constraints: <none>
#> solver: default
# build another problem, and lock in the 3rd action using numeric inputs
p2 <- p1 %>%
add_locked_in_constraints(c(3))
# print problem
print(p2)
#> Project Prioritization Problem
#> actions F1_action, F2_action, F3_action, ... (6 actions)
#> projects F1_project, F2_project, F3_project, ... (6 projects)
#> features F1, F2, F3, ... (5 features)
#> action costs: min: 0, max: 103.22583
#> project success: min: 0.81379, max: 1
#> objective: Maximum richness objective [budget (150)]
#> targets: none
#> weights: default
#> decisions Binary decision
#> constraints: <Locked in actions [1 locked units]>
#> solver: default
# build another problem, and lock in the actions using logical inputs from
# the sim_actions table
p3 <- p1 %>%
add_locked_in_constraints(sim_actions$locked_in)
# print problem
print(p3)
#> Project Prioritization Problem
#> actions F1_action, F2_action, F3_action, ... (6 actions)
#> projects F1_project, F2_project, F3_project, ... (6 projects)
#> features F1, F2, F3, ... (5 features)
#> action costs: min: 0, max: 103.22583
#> project success: min: 0.81379, max: 1
#> objective: Maximum richness objective [budget (150)]
#> targets: none
#> weights: default
#> decisions Binary decision
#> constraints: <Locked in actions [1 locked units]>
#> solver: default
# build another problem, and lock in the actions using the column name
# "locked_in" in the sim_actions table
# the sim_actions table
p4 <- p1 %>%
add_locked_in_constraints("locked_in")
# print problem
print(p4)
#> Project Prioritization Problem
#> actions F1_action, F2_action, F3_action, ... (6 actions)
#> projects F1_project, F2_project, F3_project, ... (6 projects)
#> features F1, F2, F3, ... (5 features)
#> action costs: min: 0, max: 103.22583
#> project success: min: 0.81379, max: 1
#> objective: Maximum richness objective [budget (150)]
#> targets: none
#> weights: default
#> decisions Binary decision
#> constraints: <Locked in actions [1 locked units]>
#> solver: default
# \dontrun{
# solve problems
s1 <- solve(p1)
#> Set parameter Username
#> Set parameter TimeLimit to value 2147483647
#> Set parameter MIPGap to value 0
#> Set parameter NumericFocus to value 3
#> Set parameter Presolve to value 2
#> Set parameter Threads to value 1
#> Set parameter PoolSolutions to value 1
#> Set parameter PoolSearchMode to value 2
#> Academic license - for non-commercial use only - expires 2025-04-21
#> Gurobi Optimizer version 11.0.2 build v11.0.2rc0 (linux64 - "Ubuntu 22.04.4 LTS")
#>
#> CPU model: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz, instruction set [SSE2|AVX|AVX2|AVX512]
#> Thread count: 4 physical cores, 8 logical processors, using up to 1 threads
#>
#> Optimize a model with 47 rows, 47 columns and 102 nonzeros
#> Model fingerprint: 0xf97d9094
#> Variable types: 0 continuous, 42 integer (42 binary)
#> Semi-Variable types: 5 continuous, 0 integer
#> Coefficient statistics:
#> Matrix range [9e-02, 1e+02]
#> Objective range [1e+00, 1e+00]
#> Bounds range [1e+00, 1e+00]
#> RHS range [1e+00, 2e+02]
#> Found heuristic solution: objective 1.4456093
#> Presolve removed 16 rows and 12 columns
#> Presolve time: 0.00s
#> Presolved: 31 rows, 35 columns, 65 nonzeros
#> Variable types: 0 continuous, 35 integer (35 binary)
#> Root relaxation presolved: 31 rows, 35 columns, 65 nonzeros
#>
#>
#> Root relaxation: objective 1.680145e+00, 11 iterations, 0.00 seconds (0.00 work units)
#>
#> Nodes | Current Node | Objective Bounds | Work
#> Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
#>
#> * 0 0 0 1.6801450 1.68015 0.00% - 0s
#>
#> Explored 1 nodes (11 simplex iterations) in 0.00 seconds (0.00 work units)
#> Thread count was 1 (of 8 available processors)
#>
#> Solution count 1: 1.68015
#> No other solutions better than 1.68015
#>
#> Optimal solution found (tolerance 0.00e+00)
#> Best objective 1.680145013696e+00, best bound 1.680145013696e+00, gap 0.0000%
s2 <- solve(p2)
#> Set parameter Username
#> Set parameter TimeLimit to value 2147483647
#> Set parameter MIPGap to value 0
#> Set parameter NumericFocus to value 3
#> Set parameter Presolve to value 2
#> Set parameter Threads to value 1
#> Set parameter PoolSolutions to value 1
#> Set parameter PoolSearchMode to value 2
#> Academic license - for non-commercial use only - expires 2025-04-21
#> Gurobi Optimizer version 11.0.2 build v11.0.2rc0 (linux64 - "Ubuntu 22.04.4 LTS")
#>
#> CPU model: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz, instruction set [SSE2|AVX|AVX2|AVX512]
#> Thread count: 4 physical cores, 8 logical processors, using up to 1 threads
#>
#> Optimize a model with 47 rows, 47 columns and 102 nonzeros
#> Model fingerprint: 0xaace6374
#> Variable types: 0 continuous, 42 integer (42 binary)
#> Semi-Variable types: 5 continuous, 0 integer
#> Coefficient statistics:
#> Matrix range [9e-02, 1e+02]
#> Objective range [1e+00, 1e+00]
#> Bounds range [1e+00, 1e+00]
#> RHS range [1e+00, 2e+02]
#> Found heuristic solution: objective 1.4456093
#> Presolve removed 42 rows and 41 columns
#> Presolve time: 0.00s
#> Presolved: 5 rows, 6 columns, 10 nonzeros
#> Variable types: 0 continuous, 6 integer (6 binary)
#>
#> Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)
#> Thread count was 1 (of 8 available processors)
#>
#> Solution count 1: 1.44561
#> No other solutions better than 1.44561
#>
#> Optimal solution found (tolerance 0.00e+00)
#> Best objective 1.445609277954e+00, best bound 1.445609277954e+00, gap 0.0000%
s3 <- solve(p3)
#> Set parameter Username
#> Set parameter TimeLimit to value 2147483647
#> Set parameter MIPGap to value 0
#> Set parameter NumericFocus to value 3
#> Set parameter Presolve to value 2
#> Set parameter Threads to value 1
#> Set parameter PoolSolutions to value 1
#> Set parameter PoolSearchMode to value 2
#> Academic license - for non-commercial use only - expires 2025-04-21
#> Gurobi Optimizer version 11.0.2 build v11.0.2rc0 (linux64 - "Ubuntu 22.04.4 LTS")
#>
#> CPU model: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz, instruction set [SSE2|AVX|AVX2|AVX512]
#> Thread count: 4 physical cores, 8 logical processors, using up to 1 threads
#>
#> Optimize a model with 47 rows, 47 columns and 102 nonzeros
#> Model fingerprint: 0xaace6374
#> Variable types: 0 continuous, 42 integer (42 binary)
#> Semi-Variable types: 5 continuous, 0 integer
#> Coefficient statistics:
#> Matrix range [9e-02, 1e+02]
#> Objective range [1e+00, 1e+00]
#> Bounds range [1e+00, 1e+00]
#> RHS range [1e+00, 2e+02]
#> Found heuristic solution: objective 1.4456093
#> Presolve removed 42 rows and 41 columns
#> Presolve time: 0.00s
#> Presolved: 5 rows, 6 columns, 10 nonzeros
#> Variable types: 0 continuous, 6 integer (6 binary)
#>
#> Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)
#> Thread count was 1 (of 8 available processors)
#>
#> Solution count 1: 1.44561
#> No other solutions better than 1.44561
#>
#> Optimal solution found (tolerance 0.00e+00)
#> Best objective 1.445609277954e+00, best bound 1.445609277954e+00, gap 0.0000%
s4 <- solve(p4)
#> Set parameter Username
#> Set parameter TimeLimit to value 2147483647
#> Set parameter MIPGap to value 0
#> Set parameter NumericFocus to value 3
#> Set parameter Presolve to value 2
#> Set parameter Threads to value 1
#> Set parameter PoolSolutions to value 1
#> Set parameter PoolSearchMode to value 2
#> Academic license - for non-commercial use only - expires 2025-04-21
#> Gurobi Optimizer version 11.0.2 build v11.0.2rc0 (linux64 - "Ubuntu 22.04.4 LTS")
#>
#> CPU model: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz, instruction set [SSE2|AVX|AVX2|AVX512]
#> Thread count: 4 physical cores, 8 logical processors, using up to 1 threads
#>
#> Optimize a model with 47 rows, 47 columns and 102 nonzeros
#> Model fingerprint: 0xaace6374
#> Variable types: 0 continuous, 42 integer (42 binary)
#> Semi-Variable types: 5 continuous, 0 integer
#> Coefficient statistics:
#> Matrix range [9e-02, 1e+02]
#> Objective range [1e+00, 1e+00]
#> Bounds range [1e+00, 1e+00]
#> RHS range [1e+00, 2e+02]
#> Found heuristic solution: objective 1.4456093
#> Presolve removed 42 rows and 41 columns
#> Presolve time: 0.00s
#> Presolved: 5 rows, 6 columns, 10 nonzeros
#> Variable types: 0 continuous, 6 integer (6 binary)
#>
#> Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)
#> Thread count was 1 (of 8 available processors)
#>
#> Solution count 1: 1.44561
#> No other solutions better than 1.44561
#>
#> Optimal solution found (tolerance 0.00e+00)
#> Best objective 1.445609277954e+00, best bound 1.445609277954e+00, gap 0.0000%
# print the actions selected for funding in each of the solutions
print(s1[, sim_actions$name])
#> # A tibble: 1 × 6
#> F1_action F2_action F3_action F4_action F5_action baseline_action
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 0 1 0 0 0 1
print(s2[, sim_actions$name])
#> # A tibble: 1 × 6
#> F1_action F2_action F3_action F4_action F5_action baseline_action
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 0 0 1 0 0 1
print(s3[, sim_actions$name])
#> # A tibble: 1 × 6
#> F1_action F2_action F3_action F4_action F5_action baseline_action
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 0 0 1 0 0 1
print(s4[, sim_actions$name])
#> # A tibble: 1 × 6
#> F1_action F2_action F3_action F4_action F5_action baseline_action
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 0 0 1 0 0 1
# }