Knapsack Problem#
이강우 & 김정자. (2012). EXCEL 2010 경영과학. 한경사, 380.
Items | Weights (kg) | Values | Max weight (kg) |
---|---|---|---|
1 | 3 | 6 | 6 |
2 | 4 | 8 | |
3 | 2 | 3 |
단일품목 배낭문제의 최적 정수해를 구하기 위한 정수계획모형을 정식화하기 위하여 품목 1, 품목2, 품목 3을 각각 결정변수 $X_{1}$, $X_{2}$, $X_{3}$이라고 정의하고 다음과 같이 $0-1$변수로 정의하자.
\[\begin{split}X_{j} = \begin{cases}1: \text{if item $j$ is selected } (j=1,2,3)\\
0: \text{if item $j$ is not selected } (j=1,2,3)
\end{cases}\end{split}\]
위에서 정의한 결정변수를 이용하여 배낭에 넣어 갖고 갈 수 있는 품목의 효용을 최대화하는 목적함수와 배낭의 보관능력에 대한 제약식을 정식화하면 다음과 같다.
\[\begin{split}\begin{align*}
& \text{maximize } & Z=7&X_{1} + 8X_{2} + 3X_{3} \\
& \text{subject to } & \, 3&X_{1} + 4X_{2} + 2X_{3} \le 6 \\
& \text{and} & \, &X_{j} = 0 \text{ or } 1 (j=1,2,3)
\end{align*}\end{split}\]
import os
import sys
# Add the parent directory for importing custom library
sys.path.insert(0, os.path.abspath(os.path.join(os.getcwd(), os.pardir)))
Optimization with PuLP#
from pulp import *
from ortools.utils import output
# Define problem
prob = LpProblem('Knapsack Problem', LpMaximize)
# Create decision variables and non-negative constraint
x1 = LpVariable(name='X1', lowBound=0, cat='Binary')
x2 = LpVariable(name='X2', lowBound=0, cat='Binary')
x3 = LpVariable(name='X3', lowBound=0, cat='Binary')
# Set objective function
prob += 7*x1 + 8*x2 + 3*x3
# Set constraints
prob += 3*x1 + 4*x2 + 2*x3 <= 6
# Solving problem
prob.solve()
output(prob)
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[2], line 1
----> 1 from pulp import *
2 from ortools.utils import output
4 # Define problem
ModuleNotFoundError: No module named 'pulp'
from pulp import *
from ortools.utils import output
n_items = 3
weights = [3, 4, 2]
values = [7, 8, 3]
max_weight = 6
# Define problem
prob = LpProblem('Knapsack Problem', LpMaximize)
# Create decision variables
x = LpVariable.dicts('x', [i for i in range(n_items)], lowBound=0, cat='Binary')
# Set objective function
prob += lpSum([values[i]*x[i] for i in range(n_items)])
# Set constraints
prob += lpSum([weights[i]*x[i] for i in range(n_items)]) <= max_weight
# Solving problem
prob.solve()
output(prob)
Status: Optimal
Objective value: 11.0
Variables Values
----------- --------
x_0 0
x_1 1
x_2 1
Statistics:
- Number of variables: 3
- Number of constraints: 1
- Solve time: 0.006s
Optimization with GUROBI#
from gurobipy import *
from ortools.utils import set_gurobi, custom_callback, output
n_items = 3
weights = [3, 4, 2]
values = [7, 8, 3]
max_weight = 6
# Define problem
m = Model('Knapsack Problem')
# Create decision variables
x = [m.addVar(vtype=GRB.BINARY, name='X{}'.format(i)) for i in range(n_items)]
m.update()
# Set objective function
m.setObjective(quicksum(values[i]*x[i] for i in range(n_items)), GRB.MAXIMIZE)
# Set constraints
m.addConstr(quicksum(weights[i]*x[i] for i in range(n_items)) <= max_weight)
set_gurobi(m, verbose=False)
# Optimize model
m.optimize(custom_callback)
output(m)
Status: Optimal
Objective value: 11.0
Variables Values
----------- --------
X0 0
X1 1
X2 1
Statistics:
- Number of variables: 3
- Number of constraints: 1
- Solve time: 0.000s