Constraints allow you to specify relationships between the parameters you want to optimize, or just constrain the values that a parameter can take.
For example, you may want an optional parameter to always be enabled if another parameter is set to TRUE
, or you may want an IntParameter to be between 0 and 10, but never 3.
Each constraint is a string containing an expression written in a Javascript-like syntax, e.g. '( #x >= #y ) || ( #x == 5 )'
.
Make sure you specify an id
when creating a parameter that you want to use in a constraint. You can then reference it with a #
followed by the id.
library(optaas.client)
x <- IntParameter("int_x", id="x", minimum=0, maximum=20)
y <- IntParameter("int_y", id="y", minimum=0, maximum=20)
x_smaller_than_y <- '#x < #y'
The following operators can be used in the same way as R: < <= > >= == != + - * **
.
'( #x + #y ) == 25'
Don’t forget to leave a space between a parameter reference and an operator or bracket!
Use /
for division, //
for integer (floor) division, and %
for modulus.
'#y // 2 > #x'
You can use if ... then ...
to define a conditional constraint:
'if #x < 3 then #y != 2'
Use is_present
and is_absent
to create constraints based on whether an optional parameter is present in a configuration.
Please note: if a parameter z is absent, for any value/expression X, #z == X
will always evaluate to false and #z != X
will always evaluate to true.
z <- FloatParameter("float_z", id="z", minimum=0, maximum=1, optional=TRUE)
z_larger_than_x <- 'if #z is_present then #z >= #x'
z_absent <- 'if ( #x == 0 ) && ( #y == 0 ) then #z is_absent'
You can use is_present
and is_absent
with parameters that are part of a choice.
choice <- ChoiceParameter("choice_xy", choices=list(x, y), id="xy", default=y)
if_x_present_then_z_is_small <- 'if #x is_present then #z < 0.1'
You can also use ==
and !=
with choices:
if_x_chosen_then_z_is_small <- 'if #xy == #x then #z < 0.4'
if_z_big_then_x_not_chosen <- 'if #z > 0.9 then #xy != #x'
You can use ==
, !=
, is_present
and is_absent
with categoricals as well.
abc <- CategoricalParameter('cat', values=list('a', 'b', 'c'), id='abc')
if_b_then_x_is_0 <- 'if #abc == "b" then #x == 0'
All generated configurations will obey the constraints.
client <- OPTaaSClient$new("https://optaas.mindfoundry.ai", "Your OPTaaS API Key")
task <- client$create_task(
title="My Task With Constraints",
parameters=list(choice, z, abc),
constraints=list(
if_x_chosen_then_z_is_small,
if_z_big_then_x_not_chosen,
if_b_then_x_is_0
)
)
for (i in 1:20) {
config_values <- task$generate_configuration()$values
print(paste(names(config_values), config_values, sep = "=", collapse = ", "))
}
[1] "cat=a, choice_xy=list(int_y = 10), float_z=0.5" [1] "cat=a, choice_xy=list(int_y = 18), float_z=0.902627569044657" [1] "cat=c, choice_xy=list(int_y = 0), float_z=0.827720867024436" [1] "cat=c, choice_xy=list(int_x = 20), float_z=0.0222977344632128" [1] "cat=a, choice_xy=list(int_y = 15), float_z=0.188179531038473" [1] "cat=a, choice_xy=list(int_y = 5), float_z=0.181160629976" [1] "cat=a, choice_xy=list(int_x = 12), float_z=0.162485311634153" [1] "cat=c, choice_xy=list(int_x = 2), float_z=0.197240339464683" [1] "cat=a, choice_xy=list(int_y = 13), float_z=0.151935017118846" [1] "cat=c, choice_xy=list(int_y = 11), float_z=0.477303071059494" [1] "cat=a, choice_xy=list(int_x = 3), float_z=0.201273990324097" [1] "cat=a, choice_xy=list(int_x = 14), float_z=0.22243546751149" [1] "cat=c, choice_xy=list(int_y = 10), float_z=0.58467633766694" [1] "cat=a, choice_xy=list(int_y = 7), float_z=0.461023725568998" [1] "cat=c, choice_xy=list(int_x = 1), float_z=0.115643814806002" [1] "cat=b, choice_xy=list(int_x = 0), float_z=0.350506911704727" [1] "cat=a, choice_xy=list(int_y = 4), float_z=0.872235733126264" [1] "cat=a, choice_xy=list(int_y = 3), float_z=0.968979748575969" [1] "cat=c, choice_xy=list(int_y = 6), float_z=0.40612734790686" [1] "cat=c, choice_xy=list(int_x = 12), float_z=0.0341755517006327"