Skip to content

Instantly share code, notes, and snippets.

@etrepum
Created November 1, 2018 04:28
Show Gist options
  • Save etrepum/76c0fcaf0e19c6cf071a87ac007d01a0 to your computer and use it in GitHub Desktop.
Save etrepum/76c0fcaf0e19c6cf071a87ac007d01a0 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Max orders for three digits of wings: 7.0\n"
]
}
],
"source": [
"from ortools.linear_solver import pywraplp\n",
"\n",
"COUNTS = [\n",
" 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, \n",
" 24, 25, 26, 27, 28, 29, 30, 35, 40, 45, 50, 60, 70, 75, 80, 90, 100, 125, \n",
" 150, 200\n",
"]\n",
" \n",
"# PRICES = dict(\n",
"# zip(\n",
"# wingCounts,\n",
"# [\n",
"# 4.55, 5.70, 6.80, 7.95, 9.10, 10.20, 11.35, 12.50, 13.60, 14.75, 15.90, 17.00, \n",
"# 18.15, 19.30, 20.40, 21.55, 22.70, 23.80, 24.95, 26.10, 27.25, 27.80, 28.95, \n",
"# 30.10, 31.20, 32.35, 33.50, 39.15, 44.80, 50.50, 55.60, 67.00, 78.30, 83.45, \n",
"# 89.10, 100.45, 111.25, 139.00, 166.85, 222.50\n",
"# ]\n",
"# )\n",
"# )\n",
"\n",
"def solver_for_wings(n):\n",
" solver = pywraplp.Solver(\n",
" 'SolveIntegerProblem',\n",
" pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING\n",
" )\n",
" objective = solver.Objective()\n",
" constraint = solver.Constraint(n, n)\n",
" for count in COUNTS:\n",
" xn = solver.IntVar(0, n, 'x%d' % count)\n",
" objective.SetCoefficient(xn, 1)\n",
" constraint.SetCoefficient(xn, count)\n",
" objective.SetMinimization()\n",
" result_status = solver.Solve()\n",
" assert result_status == pywraplp.Solver.OPTIMAL\n",
" return solver\n",
"\n",
"solvers = [solver_for_wings(n) for n in range(100, 1000)]\n",
"solutions = [solver.Objective().Value() for solver in solvers]\n",
"\n",
"print('Max orders for three digits of wings: {}'.format(max(solutions)))"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"import matplotlib\n",
"import matplotlib.pyplot as plt\n",
"fig, ax = plt.subplots()\n",
"ax.set_xlabel('Orders')\n",
"ax.set_ylabel('Frequency')\n",
"ax.hist(solutions)\n",
"None"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 x 4 wings\n",
"1 x 27 wings\n",
"1 x 150 wings\n",
"4 x 200 wings\n",
"= 981 wings\n"
]
}
],
"source": [
"solver = [solver for solver, solution in zip(solvers, solutions) if solution == 7][0]\n",
"n = 0\n",
"for count in COUNTS:\n",
" xn = solver.LookupVariable('x%d' % count)\n",
" c = int(xn.solution_value())\n",
" if c > 0:\n",
" print('{} x {} wings'.format(c, count))\n",
" n += count * c\n",
"print('= {} wings'.format(n))"
]
}
],
"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.6.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment