Created
April 18, 2024 16:44
-
-
Save Th1nhNg0/a6e83af0988034816dbab026724d5f36 to your computer and use it in GitHub Desktop.
flexible job shop scheduling problem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 74, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Solution 0, time = 0.004457 s, objective = 15\n", | |
"Solution 1, time = 0.006655 s, objective = 11\n", | |
"\n", | |
"solve status: OPTIMAL\n", | |
"Optimal objective value: 11\n", | |
"Statistics\n", | |
" - conflicts : 0\n", | |
" - branches : 0\n", | |
" - wall time : 0.012622 s\n" | |
] | |
} | |
], | |
"source": [ | |
"from ortools.sat.python import cp_model\n", | |
"import collections\n", | |
"\n", | |
"class SolutionPrinter(cp_model.CpSolverSolutionCallback):\n", | |
" \"\"\"Print intermediate solutions.\"\"\"\n", | |
"\n", | |
" def __init__(self):\n", | |
" cp_model.CpSolverSolutionCallback.__init__(self)\n", | |
" self.__solution_count = 0\n", | |
"\n", | |
" def on_solution_callback(self):\n", | |
" \"\"\"Called at each new solution.\"\"\"\n", | |
" print(\n", | |
" \"Solution %i, time = %f s, objective = %i\"\n", | |
" % (self.__solution_count, self.wall_time, self.objective_value)\n", | |
" )\n", | |
" self.__solution_count += 1\n", | |
"\n", | |
"\n", | |
"task_type = collections.namedtuple(\"task_type\", \"start end interval machine\")\n", | |
"\n", | |
"\n", | |
"machine = 5\n", | |
"tasks=[\n", | |
" {'id': 1, 'name': 'Job 1', 'machine': [5], 'duration': 4, 'dependent': [2]},\n", | |
" {'id': 2, 'name': 'Cheese', 'machine': [3,4], 'duration': 2, 'dependent': [3,4]},\n", | |
" {'id': 3, 'name': 'Milk', 'machine': [3,4], 'duration': 2, 'dependent': [5,6,7,8]},\n", | |
" {'id': 4, 'name': 'Milk', 'machine': [3,4], 'duration': 3, 'dependent': [5,6,7,8]},\n", | |
" {'id': 5, 'name': 'Wheat 1','machine': [1,2],'duration': 1,'dependent': []},\n", | |
" {'id': 6, 'name': 'Wheat 2','machine': [1,2],'duration': 1,'dependent': []},\n", | |
" {'id': 7, 'name': 'Wheat 3','machine': [1,2],'duration': 1,'dependent': []},\n", | |
" {'id': 8, 'name': 'Wheat 4','machine': [1,2],'duration': 1,'dependent': []}]\n", | |
"\n", | |
"duration = {task['id']: task['duration'] for task in tasks}\n", | |
"horizon = sum(task['duration'] for task in tasks)\n", | |
"times = range(horizon)\n", | |
"\n", | |
"model = cp_model.CpModel()\n", | |
"\n", | |
"all_tasks = {}\n", | |
"intervals_per_resources = collections.defaultdict(list)\n", | |
"\n", | |
"for task in tasks:\n", | |
" start_var = model.new_int_var(0, horizon, 'start_%i' % task['id'])\n", | |
" end_var = model.new_int_var(0, horizon, 'end_%i' % task['id'])\n", | |
" interval_var = model.new_interval_var(start_var, duration[task['id']], end_var, 'interval_%i' % task['id'])\n", | |
" machine_var = model.new_int_var_from_domain(cp_model.Domain.FromValues(task['machine']), 'machine_%i' % task['id'])\n", | |
" all_tasks[task['id']] = task_type(\n", | |
" start=start_var, end=end_var, interval=interval_var, machine=machine_var\n", | |
" )\n", | |
"\n", | |
" if len(task['machine']) == 1:\n", | |
" intervals_per_resources[task['machine'][0]].append(interval_var)\n", | |
" else:\n", | |
" l_presences = []\n", | |
" for machine_id in task['machine']:\n", | |
" l_presence = model.new_bool_var('presence_%i_%i' % (task['id'], machine_id))\n", | |
" l_start = model.new_int_var(0, horizon, 'start_%i_%i' % (task['id'], machine_id))\n", | |
" l_end = model.new_int_var(0, horizon, 'end_%i_%i' % (task['id'], machine_id)) \n", | |
" l_interval = model.new_optional_interval_var(l_start, duration[task['id']], l_end, l_presence, 'interval_%i_%i' % (task['id'], machine_id))\n", | |
" l_presences.append(l_presence)\n", | |
"\n", | |
" model.add(start_var == l_start).only_enforce_if(l_presence)\n", | |
" model.add(end_var == l_end).only_enforce_if(l_presence)\n", | |
" model.add(machine_var == machine_id).only_enforce_if(l_presence)\n", | |
" intervals_per_resources[machine_id].append(l_interval)\n", | |
" model.add_exactly_one(l_presences)\n", | |
"\n", | |
"for machine_id in range(machine):\n", | |
" intervals = intervals_per_resources[machine_id]\n", | |
" if len(intervals) > 1:\n", | |
" model.add_no_overlap(intervals)\n", | |
"\n", | |
"for task in tasks:\n", | |
" for dependency in task['dependent']:\n", | |
" model.Add(all_tasks[task['id']].start >= all_tasks[dependency].end)\n", | |
"\n", | |
"\n", | |
"\n", | |
"obj_var = model.new_int_var(0, horizon, 'makespan')\n", | |
"model.add_max_equality(obj_var, [all_tasks[task['id']].end for task in tasks])\n", | |
"model.minimize(obj_var)\n", | |
"solver = cp_model.CpSolver()\n", | |
"solution_printer = SolutionPrinter()\n", | |
"status = solver.solve(model,solution_printer)\n", | |
"print()\n", | |
"print(\"solve status: %s\" % solver.status_name(status))\n", | |
"print(\"Optimal objective value: %i\" % solver.objective_value)\n", | |
"print(\"Statistics\")\n", | |
"print(\" - conflicts : %i\" % solver.num_conflicts)\n", | |
"print(\" - branches : %i\" % solver.num_branches)\n", | |
"print(\" - wall time : %f s\" % solver.wall_time)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 75, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# solution to pandas dataframe\n", | |
"import pandas as pd\n", | |
"import numpy as np\n", | |
"\n", | |
"data = []\n", | |
"for task in tasks:\n", | |
" task_id = task['id']\n", | |
" task_name = task['name']\n", | |
" start = solver.Value(all_tasks[task_id].start)\n", | |
" end = solver.Value(all_tasks[task_id].end)\n", | |
" machine = solver.Value(all_tasks[task_id].machine)\n", | |
" data.append([task_id, task_name, start, end, machine])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 76, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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SZLNZlOfPn3O2zYmJsY1kul/ne29CQ0NVWZmZql9hYWFrns4l9OLtIeEhFwwDwAAqJlYUwoAAKAcGjZsqMsvv1xLly4tVWTZvXu31qxZowEDBpQ55uWXXy71/KWXXpIk9e/f/5zXyc3N1aZNm8762meffSbpzDS5oUOHKj09XfPmzSvT9o8LnV9IZGSkevXqpVdfffWsBaPff//dtT1gwABt3rxZW7duLfX6W2+9Vea45s2b68svvyy1b8GCBRccKdW5c2c1b95czz77rLKzs8+bBwAA1EyMlAIAACinOXPmqH///rr66qt15513Ki8vTy+99JLq1Kmj6dOnl2m/f/9+3XDDDerXr582bdqkN998U7feeqsuu+yyc14jNzdX11xzja666ir169dP0dHRyszM1Icffqj169e7Pu1Pkv785z/rjTfe0MSJE7V161b16NFDOTk5Wrt2re677z4NGjSoQvf38ssvq3v37urQoYPuuusuNWvWTEePHtWmTZv0yy+/aNeuXZKkhx9+WP/85z/Vr18/jR8/XoGBgVqwYIFiYmL07bffljrnmDFjdM8992jo0KFKSEjQrl27tHr1atWrV++8WaxWq1577TX1799f7dq10+jRo3XJJZfo119/VXJyskJCQvTxxx9X6P4AAIB7oSgFAABwDqdHG51ej6lPnz5atWqVpk2bpqlTp8pmsykuLk6zZ88uNU3vtHfeeUdTp07V5MmT5e3trfvvv19z5sw57zXr1q2rhQsX6tNPP9XixYt15MgReXl5qXXr1pozZ44eeOABV1svLy+tXLlSTz31lJYtW6YVK1YoPDzcVViqqLZt22r79u2aMWOGlixZouPHjysyMlKxsbGaOnWqq13Dhg2VnJyscePG6emnn1Z4eLjuueceRUVF6c477yx1zrvuukv79+/X66+/rlWrVqlHjx5KSkrStddee8E8vXr10qZNm/TEE09o3rx5ys7OVoMGDXTllVfq7rvvrvD9AQAA92JxVnRsNwAAQC0xd+5cjR8/Xvv27XOtcQQAAICqwZpSAAAA57Bt2zYFBga6FjkHAABA1WH6HgAAwB+sWLFCKSkpeuuttzRmzBh5e/MrEwAAQFVj+h4AAMAfNG3aVKdOndKQIUP097//XYGBgWZHAgAA8DgUpQAAAAAAAGA41pQCAAAAAACA4ShKAQAAAAAA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hebOnStvb28VFxebHREol4YNG6pt27al9rVp00YHDx40KRFQOZMmTdLkyZP1pz/9SR06dNDIkSP14IMPatasWWZHAyrt9N96/B1onquvvlqff/55qX1JSUm6+uqrTUpUeRSlUGk+Pj7q3LlzqS8Gh8Ohzz//vEZ+MaD2cjqduv/++/XBBx9o3bp1LKaLGuvaa6/Vf/7zH+3cudP16NKli0aMGKGdO3fKy8vL7IhAuXTr1k0//vhjqX179+5VTEyMSYmAysnNzZXVWvpPLi8vLzkcDpMSARevadOmatCgQam/A7OysrRlyxb+DjyL7Oxs1+9lUsmaXDt37nT9j5YTJ05o586d2rNnjyTpxx9/1M6dO0tNhfzzn/+sKVOmuJ6PHz9eq1at0nPPPacffvhB06dP1/bt23X//fcbd2NVhOl7uCgTJ07U7bffri5duqhr1676+9//rpycHNen8QE1wdixY7Vs2TL9+9//VnBwsOsHQJ06deTv729yOqD8goODy6yFFhgYqPDwcNZIQ43y4IMP6pprrtHMmTM1bNgwbd26VQsWLNCCBQvMjgZUyMCBA/XUU0+pcePGateunb755hs9//zzuuOOO8yOBpxXdna29u3b53p+upASFhamxo0ba8KECXryySfVsmVLNW3aVI899piioqI0ePBg80K7qe3btys+Pt71/PSn5t1+++1asmSJPvroo1J/P5/+9MJp06Zp+vTpkqSDBw+WKnBfc801WrZsmR599FH99a9/VcuWLfXhhx/WyN/3LE6n02l2CNRs8+bN05w5c3TkyBFdfvnlmjt3rq688kqzYwHlZrFYzrp/8eLFGjVqlLFhgCrWq1cvXX755fr73/9udhSgQj755BNNmTJFqampatq0qSZOnKi77rrL7FhAhZw6dUqPPfaYPvjgAx07dkxRUVEaPny4pk6dKh8fH7PjAeeUkpJSqpBy2ulCitPp1LRp07RgwQJlZmaqe/fu+sc//qFWrVqZkBY1GUUpAAAAAAAAGI41pQAAAAAAAGA4ilIAAAAAAAAwHEUpAAAAAAAAGI6iFAAAAAAAAAxHUQoAAAAAAACGoygFAAAAAAAAw1GUAgAAAAAAgOEoSgEAAHiQUaNGafDgwWbHAAAAuCBvswMAAACgfCwWy3lfnzZtml588UU5nU6DEgEAAFQeRSkAAIAa4rfffnNt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goICZ4MGDZxDhw517fvnP//ptFqtzvXr15fKMX/+fKck58aNG8/7Xk2dOtUpyRkYGOjs37+/86mnnnJ+/fXXZdotWrTIKcn5/PPPl3nt9D3v37/fKckZHh7uPHHihOv1f//7305Jzo8//ti179prr3V26NDBmZ+fX+o811xzjbNly5aufRMmTHBKcm7ZssW179ixY846deo4JTn379/v2i/JOW3atDL5YmJinLfffrvr+R/fb4fD4WzZsqWzb9++pf79cnNznU2bNnUmJCSc5Z0DAABVjZFSAADAowwbNkx5eXn65JNPdOrUKX3yySfnnLonSf7+/q7tjIwMnTx5Uj169NCOHTtc+z/88EM5HA5NnTpVVmvpX58sFkup523btlWPHj1czyMiItS6dWv99NNPF8weFBSk2267zfXcx8dHXbt2LXXsv/71L7Vp00aXXnqp0tPTXY/evXtLkpKTk897jRkzZmjZsmWKjY3V6tWr9be//U2dO3dWp06d9P3337varVixQvXq1dO4cePKnOOP93zLLbcoNDTU9fz0/Z/OfeLECa1bt07Dhg3TqVOnXJmPHz+uvn37KjU1Vb/++qskaeXKlbrqqqvUtWtX1/kiIiI0YsSI8795FbBz506lpqbq1ltv1fHjx115cnJydO211+rLL78863RBAABQtVjoHAAAeJSIiAj16dNHy5YtU25uroqLi3XTTTeds/0nn3yiJ598Ujt37iy1JtP/Fl7S0tJktVrVtm3bC16/cePGZfaFhoYqIyPjgsc2atSoTMEnNDRU3377ret5amqqvv/+e0VERJz1HOVZrHz48OEaPny4srKytGXLFi1ZskTLli3TwIEDtXv3bvn5+SktLU2tW7cutWD8ufzxnk8XqE7f8759++R0OvXYY4/pscceO2fuSy65RD///LOuvPLKMq+3bt36gjnKKzU1VZJ0++23n7PNyZMnSxXaAABA1aMoBQAAPM6tt96qu+66S0eOHFH//v1Vt27ds7Zbv369brjhBvXs2VP/+Mc/1LBhQ9lsNi1evFjLli2r1LW9vLzOut/pdFbJsQ6HQx06dNDzzz9/1rbR0dHlSFkiJCRECQkJSkhIkM1m09KlS7VlyxbFxcWV+xzlyX161NFDDz2kvn37nrVtixYtKnTN8ykuLj7v66fzzJkzR5dffvlZ2wQFBVVZHgAAcHYUpQAAgMcZMmSI7r77bm3evFnvvPPOOdutWLFCfn5+Wr16tXx9fV37Fy9eXKpd8+bN5XA4tGfPnnMWMYzSvHlz7dq1S9dee22ZUVUXo0uXLlq6dKl+++0313W2bNkiu90um812Uedu1qyZJMlms6lPnz7nbRsTE+MayfS/fvzxxzL7QkNDlZmZWWpfYWGh6x7OpXnz5pJKinIXygMAAKoPa0oBAACPExQUpFdeeUXTp0/XwIEDz9nOy8tLFoul1MiaAwcO6MMPPyzVbvDgwbJarXr88cfLrDVUnhFQVWnYsGH69ddftXDhwjKv5eXlKScn55zH5ubmatOmTWd97fQn/J2eJjd06FClp6dr3rx5ZdpW9J4jIyPVq1cvvfrqq2ctGP3++++u7QEDBmjz5s2lPgHv999/11tvvVXmuObNm+vLL78stW/BggUXHCnVuXNnNW/eXM8++6yys7PPmwcAAFQfRkoBAACPdL71gk677rrr9Pzzz6tfv3669dZbdezYMb388stq0aJFqXWcWrRoob/97W964okn1KNHD914443y9fXVtm3bFBUVpVmzZlXnrZQycuRIvfvuu7rnnnuUnJysbt26qbi4WD/88IPeffddrV69Wl26dDnrsbm5ubrmmmt01VVXqV+/foqOjlZmZqY+/PBDrV+/XoMHD1ZsbKwk6c9//rPeeOMNTZw4UVu3blWPHj2Uk5OjtWvX6r777tOgQYMqlPvll19W9+7d1aFDB911111q1qyZjh49qk2bNumXX37Rrl27JEkPP/yw/vnPf6pfv34aP368AgMDtWDBAsXExJT6N5GkMWPG6J577tHQoUOVkJCgXbt2afXq1apXr955s1itVr322mvq37+/2rVrp9GjR+uSSy7Rr7/+quTkZIWEhOjjjz+u0P0BAICKoygFAABqrd69e+v111/X008/rQkTJqhp06aaPXu2Dhw4UKYA8vjjj6tp06Z66aWX9Le//U0BAQHq2LGjRo4caWhmq9WqDz/8UC+88ILeeOMNffDBBwoICFCzZs00fvx4tWrV6pzH1q1bVwsXLtSnn36qxYsX68iRI/Ly8lLr1q01Z84cPfDAA662Xl5eWrlypZ566iktW7ZMK1asUHh4uKuwVFFt27bV9u3bNWPGDC1ZskTHjx9XZGSkYmNjNXXqVFe7hg0bKjk5WePGjdPT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RET4PsyjoqIUEhJicDqg9iIiImqshRYWFqbY2FjWSEOzcs8992jIkCF64okndO2112rNmjV65ZVX9MorrxgdDaiT8ePH6/HHH1dycrJ69OihjRs36i9/+YtuueUWo6MBP6ukpER79uzxPd+3b58yMjIUExOj5ORkTZs2TY899pi6dOmi1NRUPfzww0pMTPTdoQ+oLYpSOCvXXXedcnNzNXPmTGVlZalv37767LPPalRtgabsxRdflCQNGzas2v7XX39dN910k/8DAUALN2DAAC1atEgzZszQH//4R6WmpuqZZ55hcWg0O88//7wefvhh3XHHHcrJyVFiYqJ+97vfaebMmUZHA37WunXrNHz4cN/z6dOnS5ImT56s+fPn6/7775fD4dBtt92mgoICXXDBBfrss89Y09JP2rRpEzDTJ00ej8djdAgAAAAAAIBAZjKZtGjRotOOKNu/f79SU1O1ceNG9e3b92fPc91116m0tFQff/yxb9+QIUPUu3fvZrfQOSOlAAAAAAAAGsGZpkLm5+crMzNTR44ckSTfmopt2rTxjXz69a9/rXbt2vluknD33Xfr4osv1tNPP63LLrtM7777rtatW9csp7kzUgoAAAAAAKARLF++vNpUyJNOToWcP3/+addknjVrlh555BFJ3mVGUlJSNH/+fN/rCxYs0EMPPaT9+/erS5cueuqppzRu3LjGuoxGQ1EKAAAAAAAAfmc+8yEAAAAAAABAw6IoBQAAAAAAAL+jKAUAAAAAAAC/oygFAAAAAAAAv6MoBQAAAAAAAL+jKAUAABBAbrrpJk2YMMHoGAAAAGdkNToAAAAAasdkMv3s67NmzdKzzz4rj8fjp0QAAAD1R1EKAACgmTh69Khv+7333tPMmTO1c+dO377w8HCFh4cbEQ0AAKDOmL4HAADQTLRp08b3iIqKkslkqrYvPDy8xvS9YcOG6c4779S0adMUHR2thIQE/e1vf5PD4dDNN9+siIgIde7cWUuWLKn2tbZs2aKxY8cqPDxcCQkJmjRpkvLy8vx8xQAAIJBRlAIAAAhwb7zxhuLi4rRmzRrdeeeduv3223XNNddoyJAh2rBhg0aPHq1JkyaptLRUklRQUKARI0YoLS1N69at02effabs7Gxde+21Bl8JAAAIJBSlAAAAAlyfPn300EMPqUuXLpoxY4bsdrvi4uL029/+Vl26dNHMmTN17Ngxff/995KkefPmKS0tTU888YS6deumtLQ0vfbaa/ryyy+1a9cug68GAAAECtaUAgAACHC9e/f2bVssFsXGxqpXr16+fQkJCZKknJwcSdKmTZv05ZdfnnZ9qh9++EFdu3Zt5MQAAKAloCgFAAAQ4Gw2W7XnJpOp2r6Td/Vzu92SpJKSEo0fP15z586tca62bds2YlIAANCSUJQCAABANf369dO///1vpaSkyGrlx0UAANA4WFMKAAAA1UyZMkX5+fmaOHGi1q5dqx9++EFLly7VzTffLJfLZXQ8AAAQIChKAQAAoJrExER98803crlcGj16tHr16qVp06apVatWMpv58REAADQMk8fj8RgdAgAAAAAAAC0Lf+oCAAAAAACA31GUAgAAAAAAgN9RlAIAAAAAAIDfUZQCAAAAAACA31GUAgAAAAAAgN9RlAIAAAAAAIDfUZQCAAAAAACA31GUAgAAAAAAgN9RlAIAAAAAAIDfUZQCAAAAAACA31GUAgAAAAAAgN9RlAIAAAAAAIDf/T+wgNrHI1Rk6AAAAABJRU5ErkJggg==", | |
"text/plain": [ | |
"<Figure size 1200x800 with 2 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"import matplotlib.pyplot as plt\n", | |
"import matplotlib as mpl\n", | |
"\n", | |
"def visualize(data):\n", | |
" df = pd.DataFrame(data, columns=['id', 'task_name', 'start', 'end', 'machine'])\n", | |
" TASKS = sorted(list(df[\"task_name\"].unique()))\n", | |
" MACHINES = sorted(list(df[\"machine\"].unique()))\n", | |
" makespan = df[\"end\"].max()\n", | |
" df.sort_values(by=['task_name','start'])\n", | |
" df.set_index(['task_name','machine'], inplace=True)\n", | |
"\n", | |
"\n", | |
" bar_style = {\"alpha\": 1.0, \"lw\": 25, \"solid_capstyle\": \"butt\"}\n", | |
" text_style = {\"color\": \"white\", \"weight\": \"bold\", \"ha\": \"center\", \"va\": \"center\"}\n", | |
" colors = mpl.cm.Dark2.colors\n", | |
"\n", | |
" fig, ax = plt.subplots(2, 1, figsize=(12, 5 + (len(TASKS ) + len(MACHINES)) / 4))\n", | |
" for jdx, j in enumerate(TASKS, 1):\n", | |
" for mdx, m in enumerate(MACHINES, 1):\n", | |
" if (j, m) in df.index:\n", | |
" xs = df.loc[(j, m), \"start\"]\n", | |
" xf = df.loc[(j, m), \"end\"]\n", | |
" ax[0].plot([xs, xf], [jdx] * 2, c=colors[mdx % 7], **bar_style)\n", | |
" ax[0].text((xs + xf) / 2, jdx, m, **text_style)\n", | |
" ax[1].plot([xs, xf], [mdx] * 2, c=colors[jdx % 7], **bar_style)\n", | |
" ax[1].text((xs + xf) / 2, mdx, j, **text_style)\n", | |
" ax[0].set_title(\"Job Schedule\")\n", | |
" ax[0].set_ylabel(\"Job\")\n", | |
" ax[1].set_title(\"Machine Schedule\")\n", | |
" ax[1].set_ylabel(\"Machine\")\n", | |
"\n", | |
" for idx, s in enumerate([TASKS, MACHINES]):\n", | |
" ax[idx].set_ylim(0.5, len(s) + 0.5)\n", | |
" ax[idx].set_yticks(range(1, 1 + len(s)))\n", | |
" ax[idx].set_yticklabels(s)\n", | |
" ax[idx].text(\n", | |
" makespan,\n", | |
" ax[idx].get_ylim()[0] - 0.2,\n", | |
" \"{0:0.1f}\".format(makespan),\n", | |
" ha=\"center\",\n", | |
" va=\"top\",\n", | |
" )\n", | |
" ax[idx].plot([makespan] * 2, ax[idx].get_ylim(), \"r--\")\n", | |
" ax[idx].set_xlabel(\"Time\")\n", | |
" ax[idx].grid(True)\n", | |
"\n", | |
" fig.tight_layout()\n", | |
"visualize(data)" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "me", | |
"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.8.19" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment