Sunday, October 18, 2015

SurvivOR Puzzle / Knapsack Problem

Julia SurvivOR

The SurvivOR Puzzle

http://puzzlor.com/2010-06_SurvivOR.html

Solved as a 0-1 Integer Program using Julia / JuMP
In [1]:
# 
#  The Cbc Solver was added when Clp Solver was added via Pkg.add('Clp')
#
using JuMP
m = Model()
Out[1]:
$$ \begin{alignat*}{1}\min\quad & 0\\ \text{Subject to} \quad\end{alignat*} $$
In [2]:
# x is a binary variable
# x_r,i = 1   If the i_th item on resource row r is selected
# x_r,i = 0   Otherwise
@defVar(m, x[r=1:4,i=1:3], Bin)
Out[2]:
$$ x_{r,i} \in \{0,1\} \quad\forall r \in \{1,2,3,4\}, i \in \{1,2,3\} $$
In [3]:
# Model Data
survival = [ 10 20 25; 
             10 20 25; 
              5 15 20; 
              5 15 20]

weight = [ 5 8 12; 
           3 5  8; 
           5 8 12; 
           1 2  3]

capacity = 25
Out[3]:
25
In [4]:
# set the Objective Function : Maximize survival points
@setObjective(m,Max,sum{survival[r,i]*x[r,i], r=1:4, i=1:3})
Out[4]:
$$ 10 x_{1,1} + 20 x_{1,2} + 25 x_{1,3} + 10 x_{2,1} + 20 x_{2,2} + 25 x_{2,3} + 5 x_{3,1} + 15 x_{3,2} + 20 x_{3,3} + 5 x_{4,1} + 15 x_{4,2} + 20 x_{4,3} $$
In [5]:
# add the Weight Limit constraint
@addConstraint(m, sum{weight[r,i]*x[r,i], r=1:4, i=1:3} <= capacity)
Out[5]:
$$ 5 x_{1,1} + 8 x_{1,2} + 12 x_{1,3} + 3 x_{2,1} + 5 x_{2,2} + 8 x_{2,3} + 5 x_{3,1} + 8 x_{3,2} + 12 x_{3,3} + x_{4,1} + 2 x_{4,2} + 3 x_{4,3} \leq 25 $$
In [6]:
# add a constraint for each resource row: only 1 item may be selected from each row
for r = 1:4
    @addConstraint(m, sum{x[r,i], i=1:3} == 1)
end
In [7]:
# Solve and print the model
status = solve(m)
print(m)
Max 10 x[1,1] + 20 x[1,2] + 25 x[1,3] + 10 x[2,1] + 20 x[2,2] + 25 x[2,3] + 5 x[3,1] + 15 x[3,2] + 20 x[3,3] + 5 x[4,1] + 15 x[4,2] + 20 x[4,3]
Subject to
 5 x[1,1] + 8 x[1,2] + 12 x[1,3] + 3 x[2,1] + 5 x[2,2] + 8 x[2,3] + 5 x[3,1] + 8 x[3,2] + 12 x[3,3] + x[4,1] + 2 x[4,2] + 3 x[4,3] ≤ 25
 x[1,1] + x[1,2] + x[1,3] = 1
 x[2,1] + x[2,2] + x[2,3] = 1
 x[3,1] + x[3,2] + x[3,3] = 1
 x[4,1] + x[4,2] + x[4,3] = 1
 x[r,i] ∈ {0,1} ∀ r ∈ {1,2,3,4}, i ∈ {1,2,3}
In [8]:
# Print the solution
println("Objective is: ",m.objVal)
println("Solution is:")
for r = 1:4, i = 1:3
    println(" row ", r, " item ", i ," = ", getValue(x[r,i]))
end
Objective is: 75.0
Solution is:
 row 1 item 1 = 0.0
 row 1 item 2 = 1.0
 row 1 item 3 = 0.0
 row 2 item 1 = 0.0
 row 2 item 2 = 1.0
 row 2 item 3 = 0.0
 row 3 item 1 = 0.0
 row 3 item 2 = 1.0
 row 3 item 3 = 0.0
 row 4 item 1 = 0.0
 row 4 item 2 = 0.0
 row 4 item 3 = 1.0