Meta.Problem (TP I v0.1.0) View Source
Definition of an arbitrary optimization problem to be solved using meta-heuristics.
To use a problem definition you must provide the variables
list and the objective
function.
The objective
arity must match the variables
length and must be placed in a sorted order as the function must be called.
This module also acknowledges some common functions around Problem solving.
Link to this section Summary
Functions
Applies the objective
function with variables
and yields a Solution
struct with the function result and the variables used, useful for logging or history registry.
Compares two solutions and returns if the first is better than the second, based on the problem's type (:minimization
or :maximization
).
Seeds a variable value
field if its nil, generating a random variable value respecting its constraint definitions.
If the variable already has a value, nothing is changed, hence the maybe name.
Tweak a variable value, to a maximum of a matching variable name in noise_sizes
.
The constraints of the variable are respected, so the maximum delta change may be lower than the noise_size
found.
Flattens a solution map to a one-dimensional for serialiation purpose.
Tweak a variable value, to a maximum of a noise_size
.
The constraints of the variable are respected, so the maximum delta change may be lower than the noise_size
found.
Link to this section Types
Specs
t() :: %Meta.Problem{ objective: (... -> float()), solution: Meta.Problem.Solution.t() | nil, type: :minimization | :maximization, variables: [Meta.Problem.Variable.t()] }
Link to this section Functions
Specs
fetch_solution((... -> float()), [Meta.Problem.Variable.t()]) :: Meta.Problem.Solution.t()
Applies the objective
function with variables
and yields a Solution
struct with the function result and the variables used, useful for logging or history registry.
# Examples
iex> fetch_solution(&Meta.Functions.simple_example/1, [%Meta.Problem.Variable{name: :x, value: 3, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 100}}])
%Meta.Problem.Solution{value: 9, variables: [%Meta.Problem.Variable{name: :x, value: 3, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 100}}]}
iex> fetch_solution(&Meta.Functions.example_one/2, [%Meta.Problem.Variable{name: :x, value: 10, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 100}}, %Meta.Problem.Variable{name: :y, value: 4, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 100}}])
%Meta.Problem.Solution{value: 32.99060735569487, variables: [%Meta.Problem.Variable{name: :x, value: 10, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 100}}, %Meta.Problem.Variable{name: :y, value: 4, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 100}}]}
Specs
is_better?( Meta.Problem.Solution.t(), Meta.Problem.Solution.t(), :minimization | :maximization ) :: boolean()
Compares two solutions and returns if the first is better than the second, based on the problem's type (:minimization
or :maximization
).
# Examples
iex> is_better?(%Meta.Problem.Solution{value: 2, variables: []}, %Meta.Problem.Solution{value: 1, variables: []}, :minimization)
false
iex> is_better?(%Meta.Problem.Solution{value: 2, variables: []}, %Meta.Problem.Solution{value: 1, variables: []}, :maximization)
true
Specs
maybe_generate_random_variable_value(Meta.Problem.Variable.t()) :: Meta.Problem.Variable.t()
Seeds a variable value
field if its nil, generating a random variable value respecting its constraint definitions.
If the variable already has a value, nothing is changed, hence the maybe name.
# Examples
iex> :rand.seed(:exsplus, {101, 102, 103})
iex> maybe_generate_random_variable_value(%Meta.Problem.Variable{name: :x, value: nil, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}})
%Meta.Problem.Variable{name: :x, value: 1.489738081165117, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}
iex> maybe_generate_random_variable_value(%Meta.Problem.Variable{name: :x, value: 1, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}})
%Meta.Problem.Variable{name: :x, value: 1, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}
Tweak a variable value, to a maximum of a matching variable name in noise_sizes
.
The constraints of the variable are respected, so the maximum delta change may be lower than the noise_size
found.
The variable is only tweaked if a probability check passes (a random float between 0 and 1 is lower than the probability
argument).
It raises an Error if the probability
is not between 0 and 1
# Examples
iex> :rand.seed(:exsplus, {101, 102, 103})
iex> maybe_tweak_variable(%Meta.Problem.Variable{name: :x, value: 1, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}, 1, [x: 0.25])
%Meta.Problem.Variable{name: :x, value: 0.978631679333307, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}
iex> maybe_tweak_variable(%Meta.Problem.Variable{name: :x, value: 1, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}, 0, [x: 0.25])
%Meta.Problem.Variable{name: :x, value: 1, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}
iex> :rand.seed(:exsplus, {101, 102, 103})
iex> maybe_tweak_variable(%Meta.Problem.Variable{name: :x, value: 1, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}, 1, [x: 5000])
%Meta.Problem.Variable{name: :x, value: 0.9145267173332277, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}
Specs
serialize(Meta.Problem.Solution.t()) :: map()
Flattens a solution map to a one-dimensional for serialiation purpose.
The key value
of solution is passed on along each variable name as key and its corresponding values as value.
Examples
iex> serialize(%Meta.Problem.Solution{value: 5, variables: [%Meta.Problem.Variable{name: :x, value: 0.25}, %Meta.Problem.Variable{name: :y, value: 0.5}]})
%{value: 5, x: 0.25, y: 0.5}
Specs
tweak_variable(Meta.Problem.Variable.t(), float()) :: Meta.Problem.Variable.t()
Tweak a variable value, to a maximum of a noise_size
.
The constraints of the variable are respected, so the maximum delta change may be lower than the noise_size
found.
# Examples
iex> :rand.seed(:exsplus, {101, 102, 103})
iex> tweak_variable(%Meta.Problem.Variable{name: :x, value: 1, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}, 0.25)
%Meta.Problem.Variable{name: :x, value: 1.1224345202912793, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}
iex> :rand.seed(:exsplus, {101, 102, 103})
iex> tweak_variable(%Meta.Problem.Variable{name: :x, value: 1, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}, 5000)
%Meta.Problem.Variable{name: :x, value: 1.489738081165117, constraint: %Meta.Problem.Constraint{lower_boundary: 0, higher_boundary: 2}}