Packages
fixpoint
0.21.3
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/examples/hakank/assignment.ex
#
# Assignment problems in Elixir.
#
# Different assignments problem, both minimization and maximization.
# See the sources of the problem below.
# Compare to the following MiniZinc models, from which these problems
# are taken:
# * http://www.hakank.org/minizinc/assignment.mzn
# * http://www.hakank.org/minizinc/assignment2.mzn
# * http://www.hakank.org/minizinc/assignment2_2.mzn
# * http://www.hakank.org/minizinc/assignment3.mzn
# * http://www.hakank.org/minizinc/assignment5.mzn
# * http://www.hakank.org/minizinc/assignment6.mzn
# This program was created by Hakan Kjellerstrand, hakank@gmail.com
# See also my Elixir page: http://www.hakank.org/elxir/
#
defmodule CPSolver.Examples.Hakank.Assignment do
alias CPSolver.IntVariable
# alias CPSolver.Constraint.AllDifferent.FWC, as: AllDifferent
alias CPSolver.Constraint.Sum
alias CPSolver.Constraint.LessOrEqual
# alias CPSolver.Constraint.NotEqual
# alias CPSolver.Constraint.Equal
alias CPSolver.Model
alias CPSolver.Objective
import CPSolver.Constraint.Factory
import CPSolver.Variable.View.Factory
import Hakank.CPUtils
#
# Data from
# Winston "Operations Research", Assignment Problems, page 393f
# I added the fifth column
#
def problem(1) do
op = :minimize
cost = [[14, 5, 8, 7, 15],
[ 2, 12, 6, 5, 3],
[ 7, 8, 3, 9, 7],
[ 2, 4, 6, 10, 1]]
[op,cost]
end
#
# Winston "Operations Research", page 398, swimming team example
# (original version]
# See http://www.hakank.org/minizinc/assignment2.mzn
#
def problem(2) do
op = :minimize
cost = [[54, 54, 51, 53],
[51, 57, 52, 52],
[50, 53, 54, 56],
[56, 54, 55, 53]]
[op,cost]
end
#
# Winston "Operations Research", page 398, swimming team example
# See http://www.hakank.org/minizinc/assignment2_2.mzn
# expanded version
#
def problem(3) do
op = :minimize
cost = [[54, 54, 51, 53, 50,60,70,80,90,100],
[51, 57, 52, 52, 40,50,60,70,80, 90],
[50, 53, 54, 56, 40,50,60,80,93, 69],
[56, 54, 55, 53, 60,80,40,60,50,100]]
[op,cost]
end
#
# Winston "Operations Research", page 399
#
# """
# Tom Cruise, Freddy Prinze Jr, Harrison Ford, and Matt LeBlanc
# are marooned on a desert island with Jennifer Anniston,
# Courtney Cos, Gwynneth Paltrow, and Julia Roberts.
# The 'compatibility matrix' in Table 52 indicate how much happiness
# each couple would experience if the spend all their time toghether.
# The happiness earned by a couple is proportional to the fraction
# of time the spend toghether.
# ...
# The optimal solution requires that that each person send all their
# time with one person of the opposite sex, so this result is often
# referred to as the Marriage Theorem.
# """
#
# See http://www.hakank.org/minizinc/assignment3.mzn
# males:
# 1 "Tom Cruise"
# 2 "Freddie Prinz Jr"
# 3 "Harrison Ford"
# 4 "Mark LeBlanc"
#
# females:
# 1 "Jennifer Anniston"
# 2 "Courtney Cox"
# 3 "Gwynneth Paltrow"
# 4 "Julia Roberts"
def problem(4) do
op = :maximize
cost = [[7, 5, 8, 2],
[7, 8, 9, 4],
[3, 5, 7, 9],
[5, 5, 6, 7]]
[op,cost]
end
# From
# "SAS OR 9.1 User's Guide Mathematical Programming"
# """
# Consider assigning five programmers to five programming jobs. Each
# programmer prefers specific programming job over others. [...]
# Suppose you ask each programmer to rank the jobs according to preference
# (using 1 for the most preferred job and 5 for the least preffered job].
# PROC ASSIGN maximizes the total preference of the group by minimizing the
# sum of the preferences.
#
# PROGRAMMER JOB1 JOB2 JOB3 JOB4 JOB5
# PROGRAMMER1 4 1 3 5 2
# 2 2 1 3 4 5
# 3 3 2 4 1 5
# 4 2 3 4 5 1
# 5 4 2 3 1 5
#
# """
#
# See http://www.hakank.org/minizinc/assignment5.mzn
#
def problem(5) do
op = :minimize
cost = [[4, 1, 3, 5, 2],
[2, 1, 3, 4, 5],
[3, 2, 4, 1, 5],
[2, 3, 4, 5, 1],
[4, 2, 3, 1, 5]]
[op,cost]
end
#
# From GLPK:s example assign.mod:
# """
# The assignment problem is one of the fundamental combinatorial
# optimization problems.
#
# In its most general form, the problem is as follows:
#
# There are a number of agents and a number of tasks. Any agent can be
# assigned to perform any task, incurring some cost that may vary
# depending on the agent-task assignment. It is required to perform all
# tasks by assigning exactly one agent to each task in such a way that
# the total cost of the assignment is minimized.
#
# (From Wikipedia, the free encyclopedia.]
# """
#
# """
# These data correspond to an example from [Christofides].
# """
#
# See http://www.hakank.org/minizinc/assignment6.mzn
#
## Boris Okner: modified to sync with the latest API,
## change naming and result handling.
##
def problem(6) do
op = :minimize
cost = [[13, 21, 20, 12, 8, 26, 22, 11],
[12, 36, 25, 41, 40, 11, 4, 8],
[35, 32, 13, 36, 26, 21, 13, 37],
[34, 54, 7, 8, 12, 22, 11, 40],
[21, 6, 45, 18, 24, 34, 12, 48],
[42, 19, 39, 15, 14, 16, 28, 46],
[16, 34, 38, 3, 34, 40, 22, 24],
[26, 20, 5, 17, 45, 31, 37, 43]]
[op,cost]
end
def run() do
for p <- 1..6 do
IO.puts("\nProblem #{p}")
[op,cost] = problem(p)
assignment(op, cost)
end
end
def assignment(op, cost) do
rows = length(cost)
cols = length(Enum.at(cost,0))
# Who to assign to what task
x = for i <- 0..rows-1 do
for j <- 0..cols-1 do
IntVariable.new(0..1, name: "x[#{i},#{j}]")
end
end
x_flatten = x |> List.flatten
total_cost = IntVariable.new(0..Enum.sum(cost |> List.flatten), name: "total_cost")
# exacly one assignment per row, all rows must be assigned
row_constraints = for i <- 0..rows-1 do
Sum.new(1,for j <- 0..cols-1 do mat_at(x,i,j) end)
end
# zero or one assignments per column
column_constraints = for j <- 0..cols-1 do
{c_var,c_cons} = sum(for i <- 0..rows-1 do mat_at(x,i,j) end)
less_cons = LessOrEqual.new(c_var,1)
[c_cons,less_cons]
end
# calculate total_cost
total_cost_constraint = Sum.new(total_cost, for i <- 0..rows-1, j <- 0..cols-1 do
mul(mat_at(x,i,j),mat_at(cost,i,j))
end)
model = Model.new(x_flatten ++ [total_cost],
(row_constraints ++ column_constraints ++ [total_cost_constraint]) |> List.flatten,
objective: if op == :minimize do Objective.minimize(total_cost) else Objective.maximize(total_cost) end
)
Logger.configure(level: :info)
opts = [
search: {:first_fail, :indomain_min},
#search: {:input_order, :indomain_min},
# search: {:first_fail, :indomain_random},
timeout: :infinity,
# stop_on: {:max_solutions, 2},
]
{:ok, res} = CPSolver.solve(model,
opts
)
# IO.inspect(res.statistics)
sol = res.solutions |> List.last
total_cost_val = Enum.at(sol,rows*cols)
IO.puts("total_cost: #{total_cost_val}")
mat = Enum.take(sol,rows*cols)
print_matrix(mat,rows,cols)
for i <- 0..rows-1, j <- 0..cols-1, Enum.at(mat,i*cols+j) == 1 do j end
|> IO.inspect(label: "assigned")
end
end