Packages
fixpoint
0.15.1
0.22.1
0.21.5
0.21.4
0.21.3
0.21.2
0.21.1
0.21.0
0.20.6
0.20.5
0.20.4
0.20.3
0.20.2
0.20.1
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.18.2
0.18.1
0.17.6
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.9
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.13.5
0.13.4
0.13.2
0.13.1
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.12.2
0.12.1
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.10.7
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.9.12
0.9.11
0.9.10
0.9.9
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.52
0.8.51
0.8.50
0.8.49
0.8.48
0.8.46
0.8.44
0.8.43
0.8.42
0.8.41
0.8.40
0.8.39
0.8.38
0.8.37
0.8.36
0.8.35
0.8.34
0.8.33
0.8.32
0.8.31
0.8.30
0.8.29
0.8.28
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.1.3
0.1.2
0.1.1
0.1.0
Constraint Programming Solver
Current section
Files
Jump to
Current section
Files
lib/solver/model/model.ex
defmodule CPSolver.Model do
alias CPSolver.Constraint
alias CPSolver.Propagator
alias CPSolver.IntVariable, as: Variable
alias CPSolver.Variable.Interface
alias CPSolver.Objective
defstruct [:name, :variables, :constraints, :propagators, :objective, :extra, :id]
@type t :: %__MODULE__{
id: reference(),
name: term(),
variables: [Variable.t()],
constraints: [Constraint.t()],
propagators: [Propagator.t()],
objective: Objective.t(),
extra: term()
}
def new(variables, constraints, opts \\ []) do
constraints =
normalize_constraints(constraints)
{all_variables, objective} = init_model(variables, constraints, opts[:objective])
%__MODULE__{
variables: all_variables,
constraints: constraints,
propagators: Enum.flat_map(constraints, fn c -> Constraint.post(c) end),
objective: objective,
id: Keyword.get(opts, :id, make_ref()),
name: opts[:name],
extra: opts[:extra]
}
end
defp init_model(variables, constraints, objective) do
safe_variables =
Enum.map(variables, fn v ->
(is_integer(v) && Variable.new(v)) || v
end)
variable_map =
Map.new(safe_variables, fn v ->
{Interface.id(v), Interface.variable(v)}
end)
## Additional variables may come from constraint definitions
## (example: LessOrEqual constraint, where the second argument is a constant value).
##
additional_variables =
constraints
|> extract_variables_from_constraints()
|> Enum.reject(fn c_var -> Map.has_key?(variable_map, c_var.id) end)
(safe_variables ++ additional_variables)
|> Enum.with_index(1)
|> Enum.map_reduce(objective, fn {var, idx}, obj_acc ->
{
Interface.update(var, :index, idx),
if obj_acc && Interface.id(var) == Interface.id(obj_acc.variable) do
obj_var = Interface.update(obj_acc.variable, :index, idx)
Map.put(objective, :variable, obj_var)
else
obj_acc
end
}
end)
end
defp extract_variables_from_constraints(constraints) do
constraints
|> Enum.map(&Constraint.extract_variables/1)
|> List.flatten()
|> Enum.uniq_by(fn var -> Map.get(var, :id) end)
end
defp normalize_constraints(constraints) do
List.flatten(constraints)
end
end