Saving all material from last year in the archive.
This commit is contained in:
parent
9a6fa8b4ca
commit
a67287eeb7
81 changed files with 10 additions and 6 deletions
BIN
archive/2122/cases/case_2/case_2_description.docx
Normal file
BIN
archive/2122/cases/case_2/case_2_description.docx
Normal file
Binary file not shown.
196
archive/2122/cases/case_2/case_2_description.md
Normal file
196
archive/2122/cases/case_2/case_2_description.md
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
# Case 2: Optimizing network design to minimize costs
|
||||
|
||||
After successfully finishing your first engagement with Beanie Limited, Elisa
|
||||
has praised you enthusiastically in conversations with Charles Murray, Beanie
|
||||
Limited's COO (Chief Operations Officer). Charles is responsible for the entire
|
||||
manufacturing and supply chain organization of Beanie Limited in Europe and
|
||||
reports directly to Beanie Limited's CEO.
|
||||
|
||||
Given Charles role, he gets involved in larger, strategical and long-term
|
||||
decisions when we compare with Elisa's domain. One of the hot topics that is
|
||||
currently in Charles mind is the next plan for coffee beans reception in
|
||||
European docks. Charles' office has reached out to you to prepare a report to
|
||||
assist in this highly important decision by using optimisation techniques.
|
||||
|
||||
As you are probably aware of, coffee beans are not grown in Europe. World
|
||||
production is divided across South/Central America, Africa and South East Asia.
|
||||
Beanie Limited purchases all of its coffee beans from different providers in
|
||||
America, mainly in Brasil and Colombia (these two countries account for almost
|
||||
40% of the world production). Beanie Limited procurement teams execute
|
||||
purchases with local providers at those locations and then the coffee beans are
|
||||
shipped in container cargo ships to European docks.
|
||||
|
||||
Docks are a natural bottleneck in supply chains. Dock capacity in europe is
|
||||
limited, and both storage and handling (the activities related with loading and
|
||||
unloading goods on ships) in docks are expensive services. Charles thinks that
|
||||
Beanie Limited has not paid enough attention to this part of the supply chain
|
||||
since covid-19 radically changed the landscape (total costs for trans-oceanic
|
||||
freight of standard containers have seen five-fold increases during the
|
||||
pandemic) and wants to evaluate if the current way of working can be improved.
|
||||
|
||||
Currently, Beanie Limited takes a very simple approach: all the beans purchased
|
||||
in America reach Europe on the Rotterdam docks (the largest in Europe). The
|
||||
Amsterdam docks are used sparingly whenever there are high activity periods or
|
||||
the Rotterdam docks are under a lot of stress. Charles believes that there is
|
||||
an opportunity to reduce costs and make their supply chain more resilient if
|
||||
the company distributes their reception points across more docks in Europe.
|
||||
|
||||
Charles' team has initiated conversations with 8 different docks throughout
|
||||
Europe:
|
||||
|
||||
- Rotterdam
|
||||
- Antwerp
|
||||
- Hamburg
|
||||
- Amsterdam
|
||||
- Marseille
|
||||
- Algeciras
|
||||
- Valencia
|
||||
- Genoa
|
||||
|
||||
In the upcoming months, Charles' team must sign contracts with some of these
|
||||
docks to ensure incoming capacity for the coffee beans coming from America.
|
||||
This means they will agree with the docks on the expected handled volumes and
|
||||
thus they must decide with which docks they want to work and how much volume
|
||||
they will assign to each. The team has collected the details provided by the
|
||||
docks' companies for you to study. This information includes the capacity the
|
||||
docks could commit for Beanie Limited, as well as the prices for handling
|
||||
Beanie Limited's 40 feet containers through the dock.
|
||||
|
||||
Charles wants you to use your optimization skills to assess the different
|
||||
options and recommend the best decisions for the company regarding how much
|
||||
volume to put through each dock. He hopes you can come up with a plan where
|
||||
Beanie Limited ensures it will have enough capacity, while at the same time
|
||||
costs are as low as possible.
|
||||
|
||||
## Detailed task definition
|
||||
|
||||
- Below you will find four levels of questions. Levels 1 to 3 are compulsory.
|
||||
Level 4 is optional.
|
||||
- You need to write a report document where you answer the questions of the
|
||||
different levels. This report should be directed towards Charles, should give
|
||||
him clear recommendations and should justify these recommendations. It's
|
||||
important for you to reflect your methodology to back your proposals.
|
||||
- Each level is worth 2 points out of a total of 10. The 2 missing points will
|
||||
grade the clarity and structure of your report and code.
|
||||
- You need to use a Python notebook to solve all levels. A helper notebook is
|
||||
provided. Please attach a notebook that shows your
|
||||
solution/proposal/analysis.
|
||||
- For the areas of the report where you have built an optimization model,
|
||||
please provide a formal definition of the problem in mathematical terms. This
|
||||
sould include the target function, decision variables and constraints.
|
||||
- Include your team number, names and student IDs in all your deliverables.
|
||||
|
||||
## Data
|
||||
|
||||
A few facts:
|
||||
|
||||
- Charles' team estimates that Beanie Limited will need to receive 1,500,000
|
||||
metric tons of coffee beans in European docks during next year.
|
||||
- The category being negotiated is 40 feet containers. 40 feet containers have
|
||||
a capacity of 66 cubic meters.
|
||||
- One cubic meter of coffee beans weights approximately 450 kgrs.
|
||||
|
||||
Charles' team has shared with you a table (prices_and_capacities.csv) with the
|
||||
next year's prices proposed by the different docks for 40ft containers. You can
|
||||
also find the maximum capacity that the dock is willing to provide to Beanie
|
||||
Limited (the capacity is described as a count of 40ft containers).
|
||||
|
||||
## Notebook
|
||||
|
||||
A notebook with some helping code has been provided. The code contains examples
|
||||
on how to use `pulp`, a python package for modeling and solving optimization
|
||||
problems. You can use it to get familiar with how to solve linear, integer and
|
||||
mixed programming problems.
|
||||
|
||||
## Levels
|
||||
|
||||
### Level 1
|
||||
|
||||
Examine the data provided below and current proposals data. Do you think there
|
||||
is a chance to reduce costs? Why? And will next year's total cost lower?
|
||||
|
||||
You can assume that last year, around 80% of Beanie Limited's containers
|
||||
entered through Rotterdam and the remaining 20% through Amsterdam. Total volume
|
||||
was around 24000 40ft containers. Although they don't have more granular
|
||||
numbers at hand, Charles mentioned that they had a total expense of 13,700,00€
|
||||
on docks fees.
|
||||
|
||||
### Level 2
|
||||
|
||||
With the price and capacity data provided for each dock, Charles would like you
|
||||
to find out what is the optimal distribution across the different options for
|
||||
next year. He is expecting you to provide the exact numbers, as well as the
|
||||
expected costs that would result from your proposal.
|
||||
|
||||
### Level 3
|
||||
|
||||
As it tends to be in these projects, sometimes new information appears in the
|
||||
middle of the project. Charles' team has reached out to let you know that they
|
||||
have some additional details from the different ports.
|
||||
|
||||
The following docks have a sign-up fee. This means that, if Beanie Limited
|
||||
wants to do any business with them at all, they need to pay this fee. This fee
|
||||
is only paid once and is independent of the container volume that goes through
|
||||
the dock.
|
||||
|
||||
- Algeciras: 800,000€
|
||||
- Marseille: 500,000€
|
||||
- Antwerp: 1,000,000€
|
||||
|
||||
Also, after presenting your initial results from level 2, Charles is very happy
|
||||
with your work, although there is something bothering him. Even though your
|
||||
proposal sounds reasonable, he is concerned that splitting the operations
|
||||
between too many docks might make land logistics operations too complex and end
|
||||
up causing higher costs in their truck transportation that cancel the potential
|
||||
savings that could be obtained in docks operations.
|
||||
|
||||
Charles doesn't have numbers currently, so there is no way to tackle this
|
||||
properly in an empirical way. To have the necessary information to think about
|
||||
this in the future, he would like you to repeat your analysis with a new
|
||||
condition in place: to only use a maximum of 3 docks in your proposal. Charles
|
||||
wants to know what would be the optimal decision while restricting the used
|
||||
docks to that number.
|
||||
|
||||
Charles wants you to reassess the situation with the new data and provide the
|
||||
adequate solution with the new options. He also would like to understand how
|
||||
these changes impact the solution you provided for level 2 and the overall
|
||||
results for Beanie Limited.
|
||||
|
||||
### Level 4
|
||||
|
||||
Now that it seemed you finally had a proper proposal in place, Charles is
|
||||
calling again with more concerns and asking you to go the extra mile with a
|
||||
final assessment.
|
||||
|
||||
Apparently, some rumours have reached Charles ears. It seems that some new
|
||||
regulations in Spain might affect taxes related to dock activities. Charles
|
||||
believes this could have an impact on the prices in Valencia and Algeciras,
|
||||
putting pressure on them to increase their prices because additional taxes
|
||||
would increase their own costs. The issue is: Charles doesn't know for sure
|
||||
what will happen. His expert opinion is that the following is possible:
|
||||
|
||||
- For Valencia, Charles thinks the price can end up somewhere between today's
|
||||
price (310€/40ft) and 390€/40ft. He says the probability of any price is in
|
||||
that range is equal.
|
||||
- For Algeciras, Charles thinks the price can end up somewhere between today's
|
||||
price (280€/40ft) and 330€/40ft. Again, he says the probability of any price
|
||||
is in that range is equal.
|
||||
|
||||
Charles heard you did a great job by using simulation techniques with Elisa in
|
||||
your previous project. Charles' can't request you to do any simulation work as
|
||||
part of the current engagement, because that would be out of the scoped that
|
||||
was agreed upon. But nevertheless, he would appreciate if you could explain to
|
||||
him how would you use simulation to make the decision with these new
|
||||
uncertainty in place. What would be your methodology? What kind of results
|
||||
could you provide to him?
|
||||
|
||||
With that information, he might decide to spend some more money with Simiupf to
|
||||
pursue that stream of work. And that would definetely make your bosses very
|
||||
happy!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
archive/2122/cases/case_2/case_2_description.pdf
Normal file
BIN
archive/2122/cases/case_2/case_2_description.pdf
Normal file
Binary file not shown.
601
archive/2122/cases/case_2/case_2_student_notebook.ipynb
Normal file
601
archive/2122/cases/case_2/case_2_student_notebook.ipynb
Normal file
|
|
@ -0,0 +1,601 @@
|
|||
{
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"name": "case_2_student_notebook.ipynb",
|
||||
"provenance": [],
|
||||
"toc_visible": true,
|
||||
"collapsed_sections": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "python3",
|
||||
"display_name": "Python 3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
}
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# Introduction to PuLP\n",
|
||||
"\n",
|
||||
"For case 2, you will need to define and solve optimization problems. In this notebook, I'll help you understand how to use `pulp`, a Python package for modeling optimization problems. You might want to check the following links:\n",
|
||||
"\n",
|
||||
"- Documentation: https://coin-or.github.io/pulp/\n",
|
||||
"- Homepage: https://github.com/coin-or/pulp\n",
|
||||
"\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "eLvjUuJdzS7z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# Installing and checking all is in place"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "HFavOEVS0dbY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"The first thing you need to do is to install `pulp`. `pulp` is not in the standard available packages in Colab, so you need to run the following cell once. "
|
||||
],
|
||||
"metadata": {
|
||||
"id": "HgZwpjUG0PsK"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"!pip install pulp"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "ni6Q_YiO0nIm",
|
||||
"outputId": "405d3f57-4502-4ed5-dcb9-d3204b585bb8"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Collecting pulp\n",
|
||||
" Downloading PuLP-2.6.0-py3-none-any.whl (14.2 MB)\n",
|
||||
"\u001b[K |████████████████████████████████| 14.2 MB 8.9 MB/s \n",
|
||||
"\u001b[?25hInstalling collected packages: pulp\n",
|
||||
"Successfully installed pulp-2.6.0\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"After doing that, you can import the library."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "k9YI0Kzw0qLT"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"import pulp"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "hw6keX7x0tZ1"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"If all is good, running the following command will print a large log testing `pulp`. The last line should read \"OK\"."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "vD_rXehL1KXX"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"pulp.pulpTestAll()"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "Ney2a8mu1JqQ",
|
||||
"outputId": "a6b32d96-b163-4fc5-b4fc-3d5673e5a40a"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stderr",
|
||||
"text": [
|
||||
"ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.........."
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"\t Test that logic put in place for deprecation handling of indexs works\n",
|
||||
"\t Testing 'indexs' param continues to work for LpVariable.dicts\n",
|
||||
"\t Testing 'indexs' param continues to work for LpVariable.matrix\n",
|
||||
"\t Testing 'indices' argument works in LpVariable.dicts\n",
|
||||
"\t Testing 'indices' param continues to work for LpVariable.matrix\n",
|
||||
"\t Testing invalid status\n",
|
||||
"\t Testing continuous LP solution - export dict\n",
|
||||
"\t Testing export dict for LP\n",
|
||||
"\t Testing export dict MIP\n",
|
||||
"\t Testing maximize continuous LP solution\n",
|
||||
"\t Testing continuous LP solution - export JSON\n",
|
||||
"\t Testing continuous LP solution - export solver dict\n",
|
||||
"\t Testing continuous LP solution - export solver JSON\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stderr",
|
||||
"text": [
|
||||
".........."
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"\t Testing reading MPS files - binary variable, no constraint names\n",
|
||||
"\t Testing reading MPS files - integer variable\n",
|
||||
"\t Testing reading MPS files - maximize\n",
|
||||
"\t Testing invalid var names\n",
|
||||
"\t Testing logPath argument\n",
|
||||
"\t Testing makeDict general behavior\n",
|
||||
"\t Testing makeDict default value behavior\n",
|
||||
"\t Testing measuring optimization time\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stderr",
|
||||
"text": [
|
||||
"............."
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"\t Testing the availability of the function pulpTestAll\n",
|
||||
"\t Testing zero subtraction\n",
|
||||
"\t Testing inconsistent lp solution\n",
|
||||
"\t Testing continuous LP solution\n",
|
||||
"\t Testing maximize continuous LP solution\n",
|
||||
"\t Testing unbounded continuous LP solution\n",
|
||||
"\t Testing Long Names\n",
|
||||
"\t Testing repeated Names\n",
|
||||
"\t Testing zero constraint\n",
|
||||
"\t Testing zero objective\n",
|
||||
"\t Testing LpVariable (not LpAffineExpression) objective\n",
|
||||
"\t Testing Long lines in LP\n",
|
||||
"\t Testing LpAffineExpression divide\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stderr",
|
||||
"text": [
|
||||
"............."
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"\t Testing MIP solution\n",
|
||||
"\t Testing MIP solution with floats in objective\n",
|
||||
"\t Testing Initial value in MIP solution\n",
|
||||
"\t Testing fixing value in MIP solution\n",
|
||||
"\t Testing MIP relaxation\n",
|
||||
"\t Testing feasibility problem (no objective)\n",
|
||||
"\t Testing an infeasible problem\n",
|
||||
"\t Testing an integer infeasible problem\n",
|
||||
"\t Testing another integer infeasible problem\n",
|
||||
"\t Testing column based modelling\n",
|
||||
"\t Testing dual variables and slacks reporting\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stderr",
|
||||
"text": [
|
||||
"..........ssssssssssssssssssssssssssssssssssssssssssssssssssssss"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"\t Testing fractional constraints\n",
|
||||
"\t Testing elastic constraints (no change)\n",
|
||||
"\t Testing elastic constraints (freebound)\n",
|
||||
"\t Testing elastic constraints (penalty unchanged)\n",
|
||||
"\t Testing elastic constraints (penalty unbounded)\n",
|
||||
"\t Testing timeLimit argument\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stderr",
|
||||
"text": [
|
||||
"ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss\n",
|
||||
"----------------------------------------------------------------------\n",
|
||||
"Ran 840 tests in 15.681s\n",
|
||||
"\n",
|
||||
"OK (skipped=784)\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# Defining and solving problems\n",
|
||||
"\n",
|
||||
"The following cells show you the absolute minimum to model and solve a problem with `pulp`. The steps are:\n",
|
||||
"\n",
|
||||
"1. Define decision variables\n",
|
||||
"2. Define the target function\n",
|
||||
"3. Define the constraints\n",
|
||||
"4. Assemble the problem\n",
|
||||
"5. Solve it\n",
|
||||
"6. Examine results\n",
|
||||
"\n",
|
||||
"For more flexibility, options and interesting stuff, please check up the PuLP documentation."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "oiXz40NR1whf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Define decision variables"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "nq5bcQs03g0j"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"x = pulp.LpVariable(\n",
|
||||
" name=\"x\",\n",
|
||||
" cat=pulp.LpContinuous \n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"y = pulp.LpVariable(\n",
|
||||
" name=\"y\",\n",
|
||||
" cat=pulp.LpInteger # This will make the variable integer only\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"z = pulp.LpVariable(\n",
|
||||
" name=\"z\",\n",
|
||||
" cat=pulp.LpBinary # This will make the variable binary (only 0 or 1)\n",
|
||||
")"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "0SPhww4L3buh"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Define the target function"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "uhlbq2oO35kp"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"target_function = 10 * x - 5 * y + z"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "pu3Im9DH39CN"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Define constraints"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "lqD0dD474Izw"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"constraint_1 = x >= 0\n",
|
||||
"constraint_2 = y >= 0\n",
|
||||
"constraint_3 = x >= 10\n",
|
||||
"constraint_4 = y <= 50"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "5Cu51lYj4OUC"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Assemble the problem\n",
|
||||
"\n",
|
||||
"To put all the parts together, you need to declare a problem and specify if you want to minimize or maximize the target function.\n",
|
||||
"\n",
|
||||
"Once you have that:\n",
|
||||
"- First, you \"add\" the target function.\n",
|
||||
"- After, you \"add\" all the constraints you want to include."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "d5nq94IM4kSU"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"problem = pulp.LpProblem(\"my_silly_problem\", pulp.LpMinimize)\n",
|
||||
"\n",
|
||||
"problem += target_function\n",
|
||||
"\n",
|
||||
"for constraint in (\n",
|
||||
" constraint_1,\n",
|
||||
" constraint_2,\n",
|
||||
" constraint_3,\n",
|
||||
" constraint_4\n",
|
||||
" ):\n",
|
||||
" problem += constraint"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "yI-Oiwh64mRc"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Solve it\n",
|
||||
"\n",
|
||||
"The problem object is now unsolved. You can call the `solve` method on it to find a solution."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "RJTWfR8-5fBd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"f\"Status: {pulp.LpStatus[problem.status]}\"\n",
|
||||
"problem.solve()"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "4Fbltpbp5mRi",
|
||||
"outputId": "07f9c959-e9b0-4fe7-e7ea-c698703111ff"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "execute_result",
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"execution_count": 9
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Examine results\n",
|
||||
"\n",
|
||||
"After calling `solve` on a problem, you can access:\n",
|
||||
"- The status of the problem. It can be solved, but also it might show to be not feasible.\n",
|
||||
"- The values assigned to each decision variable.\n",
|
||||
"- The final value for the target function.\n",
|
||||
"\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "0pc9RmrO7FKo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"print(f\"Status: {pulp.LpStatus[problem.status]}\")\n",
|
||||
"for v in problem.variables():\n",
|
||||
" print(v.name, \"=\", v.varValue)\n",
|
||||
" \n",
|
||||
"print(pulp.value(problem.objective))"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "8U4xVvUg9W07",
|
||||
"outputId": "32a330f1-65ab-4903-f29b-368f2bacaf94"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Status: Optimal\n",
|
||||
"x = 10.0\n",
|
||||
"y = 50.0\n",
|
||||
"z = 0.0\n",
|
||||
"-150.0\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# Peanut Butter Example\n",
|
||||
"\n",
|
||||
"As an additional example, you can find below the model and solver for the Peanut Butter Sandwich example we discussed on lecture 6."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "I2lNaFm2XVK1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"pb = pulp.LpVariable(\n",
|
||||
" name=\"Peanut Butter grams\",\n",
|
||||
" cat=pulp.LpContinuous \n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"b = pulp.LpVariable(\n",
|
||||
" name=\"Bread grams\",\n",
|
||||
" cat=pulp.LpContinuous \n",
|
||||
" )"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "HI4E2dNoXVK4"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"target_function = 5.88 * pb + 2.87 * b"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "PfTxq8R0XVLB"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"no_negative_pb = pb >= 0\n",
|
||||
"no_negative_b = b >= 0\n",
|
||||
"max_pb_we_have = pb <= 200\n",
|
||||
"max_b_we_have = b <= 300\n",
|
||||
"doctors_dietary_restriction = pb <= 0.13 * b"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "2X1AzQM8XVLD"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"problem = pulp.LpProblem(\"sandwich_problem\", pulp.LpMaximize)\n",
|
||||
"\n",
|
||||
"problem += target_function\n",
|
||||
"\n",
|
||||
"for constraint in (\n",
|
||||
" no_negative_pb,\n",
|
||||
" no_negative_b,\n",
|
||||
" max_pb_we_have,\n",
|
||||
" max_b_we_have,\n",
|
||||
" doctors_dietary_restriction\n",
|
||||
" ):\n",
|
||||
" problem += constraint"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "3oEoQXebXVLE"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"f\"Status: {pulp.LpStatus[problem.status]}\"\n",
|
||||
"problem.solve()\n",
|
||||
"print(f\"Status: {pulp.LpStatus[problem.status]}\")\n",
|
||||
"for v in problem.variables():\n",
|
||||
" print(v.name, \"=\", v.varValue)\n",
|
||||
" \n",
|
||||
"print(f\"Final calories: {pulp.value(problem.objective)}\")"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"outputId": "d873d58d-6d9e-459e-d66f-127f436b1aab",
|
||||
"id": "u1vI73kiXVLF"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Status: Optimal\n",
|
||||
"Bread_grams = 300.0\n",
|
||||
"Peanut_Butter_grams = 39.0\n",
|
||||
"1090.32\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# Case 2\n",
|
||||
"\n",
|
||||
"You can use the rest of the notebook to work on the different parts of case 2."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "6kWgbTjU-LaN"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# Good luck!"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "aYzseTWh-Sal"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
archive/2122/cases/case_2/grading.xlsx
Normal file
BIN
archive/2122/cases/case_2/grading.xlsx
Normal file
Binary file not shown.
BIN
archive/2122/cases/case_2/grading_team_15.xlsx
Normal file
BIN
archive/2122/cases/case_2/grading_team_15.xlsx
Normal file
Binary file not shown.
BIN
archive/2122/cases/case_2/grading_team_4.xlsx
Normal file
BIN
archive/2122/cases/case_2/grading_team_4.xlsx
Normal file
Binary file not shown.
BIN
archive/2122/cases/case_2/grading_team_6.xlsx
Normal file
BIN
archive/2122/cases/case_2/grading_team_6.xlsx
Normal file
Binary file not shown.
BIN
archive/2122/cases/case_2/grading_team_7.xlsx
Normal file
BIN
archive/2122/cases/case_2/grading_team_7.xlsx
Normal file
Binary file not shown.
BIN
archive/2122/cases/case_2/grading_team_8.xlsx
Normal file
BIN
archive/2122/cases/case_2/grading_team_8.xlsx
Normal file
Binary file not shown.
BIN
archive/2122/cases/case_2/grading_team_9.xlsx
Normal file
BIN
archive/2122/cases/case_2/grading_team_9.xlsx
Normal file
Binary file not shown.
9
archive/2122/cases/case_2/prices_and_capacities.csv
Normal file
9
archive/2122/cases/case_2/prices_and_capacities.csv
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
dock,40_ft_container_price_eur,max_capacity
|
||||
Rotterdam,470,33000
|
||||
Antwerp,470,25000
|
||||
Hamburg,480,44000
|
||||
Amsterdam,610,11000
|
||||
Marseille,380,9000
|
||||
Algeciras,280,20000
|
||||
Valencia,310,11000
|
||||
Genoa,340,7500
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue