{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#import sys\n", "#!{sys.executable} -m pip install ortools \n", "\n", "import pandas as pd\n", "import numpy as np\n", "import time\n", "import random\n", "from ortools.linear_solver import pywraplp" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "InputData = pd.read_excel(\"Nutrition Info.xlsx\", sep=\"\\t\")\n", "InputData" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "PrefData = pd.read_excel(\"Nutrition Preferences.xlsx\", sep=\"\\t\")\n", "PrefData" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Determine the start time\n", "StartTime = time.process_time()\n", "\n", "# Define our Linear Program\n", "Solver = pywraplp.Solver('Solver', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)\n", "\n", "# Define the Preference Coefficient P[i,j] for Shiva, for Ingredient i used for Meal j\n", "n=19\n", "m=5\n", "\n", "P = np.zeros(shape=(n, m), dtype=int)\n", "blocks = [\"MON\", \"TUE\", \"WED\", \"THU\", \"FRI\"]\n", "\n", "for j in range(m):\n", " for i in range(n):\n", " P[i,j] = PrefData[\"Shiva\"][i]\n", " \n", "# Define the variable X[i,j], which will equal the number of times Ingredient i is used for Meal j\n", "# No ingredient can be used more than twice.\n", "X = {}\n", "for i in range(n):\n", " for j in range(m):\n", " X[i,j] = Solver.IntVar(0, 2, 'X[%d, %d]' % (i,j))\n", " \n", "# Set up our Happiness Function for SHIVA, which maximizes the total number of Happiness Points\n", "HappinessFunction = Solver.Sum(P[i,j]*X[i,j] for i in range(n) for j in range(m))\n", "Solver.Maximize(HappinessFunction)\n", "\n", "# Include our first constraint: Each meal must have at least 700 calories\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Calories\"][i]*X[i,j] for i in range(n)]) >=\n", " InputData[\"Calories\"][19] )\n", " \n", "# Include our second constraint: Each meal must have at most 24 grams of fat\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Fat\"][i]*X[i,j] for i in range(n)]) <=\n", " InputData[\"Fat\"][19] )\n", " \n", "# Include our third constraint: Each meal must have at most 3 grams of sodium\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Sodium\"][i]*X[i,j] for i in range(n)]) <=\n", " InputData[\"Sodium\"][19] )\n", "\n", "# Include our fourth constraint: Each meal must have at least 90 grams of carbs\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Carbs\"][i]*X[i,j] for i in range(n)]) >=\n", " 1*InputData[\"Carbs\"][19] )\n", " \n", "# Include our fifth constraint: Each meal must have at least 8 grams of dietary fiber\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Fiber\"][i]*X[i,j] for i in range(n)]) >=\n", " 1*InputData[\"Fiber\"][19] )\n", "\n", "# Include our sixth constraint: Each meal must have at least 17 grams of protein\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Protein\"][i]*X[i,j] for i in range(n)]) >=\n", " 1*InputData[\"Protein\"][19] )\n", "\n", "# Include our seventh constraints: no beef, no ham, no salami,\n", "# and also, at most one serving of chicken in any two day stretch\n", "\n", "Solver.Add(X[11,0]+X[12,0]+X[15,0]==0)\n", "Solver.Add(X[11,1]+X[12,1]+X[15,1]==0)\n", "Solver.Add(X[11,2]+X[12,2]+X[15,2]==0)\n", "Solver.Add(X[11,3]+X[12,3]+X[15,3]==0)\n", "Solver.Add(X[11,4]+X[12,4]+X[15,4]==0)\n", "Solver.Add(X[13,0]+X[14,0]+X[13,1]+X[14,1]<=1)\n", "Solver.Add(X[13,1]+X[14,1]+X[13,2]+X[14,2]<=1)\n", "Solver.Add(X[13,2]+X[14,2]+X[13,3]+X[14,3]<=1)\n", "Solver.Add(X[13,3]+X[14,3]+X[13,4]+X[14,4]<=1)\n", "\n", "\n", "\n", "# Include our final constraint: Each meal must have at least 6 ingredients and at most 10 \n", "for j in range(m):\n", " Solver.Add(Solver.Sum([X[i,j] for i in range(n)]) >= 6)\n", " Solver.Add(Solver.Sum([X[i,j] for i in range(n)]) <= 10)\n", "\n", "# Solve the Integer Linear program\n", "Output = Solver.Solve()\n", "TotalPoints = round(Solver.Objective().Value())\n", "\n", "# Determine the total time of running the program.\n", "TotalTime = round(time.process_time() - StartTime, 4)\n", "\n", "# Output one of the possible optimal solutions.\n", "print(\"Python returns a solution with\", TotalPoints, \"Total Happiness Points in\",\n", " TotalTime, \"seconds\")\n", "print()\n", "print(\"Shiva's menu\")\n", "for j in range(m):\n", " print()\n", " for i in range(n):\n", " if X[i,j].solution_value()==1:\n", " print(\"The meal on\", blocks[j], \"will have one serving of\", \n", " InputData[\"Ingredient\"][i], \"with score\", P[i,j])\n", " if X[i,j].solution_value()==2:\n", " print(\"The meal on\", blocks[j], \"will have two servings of\", \n", " InputData[\"Ingredient\"][i], \"with score\", P[i,j])\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Determine the start time\n", "StartTime = time.process_time()\n", "\n", "# Define our Linear Program\n", "Solver = pywraplp.Solver('Solver', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)\n", "\n", "# Define the Preference Coefficient P[i,j] for DP, for Ingredient i used for Meal j\n", "n=19\n", "m=5\n", "\n", "P = np.zeros(shape=(n, m), dtype=int)\n", "blocks = [\"MON\", \"TUE\", \"WED\", \"THU\", \"FRI\"]\n", "\n", "for j in range(m):\n", " for i in range(n):\n", " P[i,j] = PrefData[\"DP\"][i]\n", " \n", "# Define the variable X[i,j], which will equal the number of times Ingredient i is used for Meal j\n", "# No ingredient can be used more than twice.\n", "X = {}\n", "for i in range(n):\n", " for j in range(m):\n", " X[i,j] = Solver.IntVar(0, 2, 'X[%d, %d]' % (i,j))\n", " \n", "# Set up our Happiness Function for DP, which maximizes the total number of Happiness Points\n", "HappinessFunction = Solver.Sum(P[i,j]*X[i,j] for i in range(n) for j in range(m))\n", "Solver.Maximize(HappinessFunction)\n", "\n", "# Include our first constraint: Each meal must have at least 700 calories\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Calories\"][i]*X[i,j] for i in range(n)]) >=\n", " InputData[\"Calories\"][19] )\n", " \n", "# Include our second constraint: Each meal must have at most 24 grams of fat\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Fat\"][i]*X[i,j] for i in range(n)]) <=\n", " InputData[\"Fat\"][19] )\n", " \n", "# Include our third constraint: Each meal must have at most 3 grams of sodium\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Sodium\"][i]*X[i,j] for i in range(n)]) <=\n", " InputData[\"Sodium\"][19] )\n", "\n", "# Include our fourth constraint: Each meal must have at least 90 grams of carbs\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Carbs\"][i]*X[i,j] for i in range(n)]) >=\n", " 1*InputData[\"Carbs\"][19] )\n", " \n", "# Include our fifth constraint: Each meal must have at least 8 grams of dietary fiber\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Fiber\"][i]*X[i,j] for i in range(n)]) >=\n", " 1*InputData[\"Fiber\"][19] )\n", "\n", "# Include our sixth constraint: Each meal must have at least 17 grams of protein\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([InputData[\"Protein\"][i]*X[i,j] for i in range(n)]) >=\n", " 1*InputData[\"Protein\"][19] )\n", "\n", "# Include our seventh constraints: one serving of fries on Wednesday and Friday, \n", "# no spinach and cabbage together, and no chicken on Fridays\n", "for j in range(m):\n", " Solver.Add(X[17,2]==1)\n", " Solver.Add(X[17,4]==1)\n", " Solver.Add(X[1,j]+X[4,j]<=1)\n", " Solver.Add(X[13,4]+X[14,4]==0)\n", " \n", "# Include our final constraint: Each meal must have at least 6 ingredients and at most 10.\n", "for j in range(m):\n", " Solver.Add(Solver.Sum([X[i,j] for i in range(n)]) >= 6)\n", " Solver.Add(Solver.Sum([X[i,j] for i in range(n)]) <= 10)\n", " \n", "\n", "# Solve the Integer Linear program\n", "Output = Solver.Solve()\n", "TotalPoints = round(Solver.Objective().Value())\n", "\n", "# Determine the total time of running the program.\n", "TotalTime = round(time.process_time() - StartTime, 4)\n", "\n", "# Output one of the possible optimal solutions.\n", "print(\"Python returns a solution with\", TotalPoints, \"Total Happiness Points in\",\n", " TotalTime, \"seconds\")\n", "print()\n", "print(\"DP's menu\")\n", "for j in range(m):\n", " print()\n", " for i in range(n):\n", " if X[i,j].solution_value()==1:\n", " print(\"The meal on\", blocks[j], \"will have one serving of\", \n", " InputData[\"Ingredient\"][i], \"with score\", P[i,j])\n", " if X[i,j].solution_value()==2:\n", " print(\"The meal on\", blocks[j], \"will have two servings of\", \n", " InputData[\"Ingredient\"][i], \"with score\", P[i,j])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }