{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "8L33m5E2PzNX" }, "source": [ "# Job Shop Scheduling: Basics and State Space Search\n", "\n", "The **job shop scheduling** problem is a classic AI planning, scheduling and combinatorial optimisation problem. It has many real-world applications in Industry 4.0, such as intelligent supply chain management, manufacturing and cloud computing. \n", "\n", "In this tutorial, we will introduce the **basics of job shop scheduling problem** and a simple **state space search** in AI planning to solve it.\n", "\n", "-----------\n", "\n", "# Table of Contents\n", "\n", "1. [Job, Operation, Machine, Schedule](#concepts)\n", "2. [State Space Search](#search)\n", " 1. [Environment](#env)\n", " 2. [State](#state)\n", " 3. [Action](#action)\n", " 4. [Overall Search Algorithm](#overall)\n", " 5. [Computational Complexity](#complexity)\n", "3. [Case Study in Car Manufacturing](#case)\n", "4. [Display Schedule](#display)\n", "5. [Jobs with Different Operation Sequences](#diffop)" ] }, { "cell_type": "markdown", "metadata": { "id": "MZiJGnUdPzNc" }, "source": [ "-----------\n", "\n", "## 1. Job, Operation, Machine, Schedule \n", "\n", "Let's consider a car manufacturing factory. It receives **jobs** to build cars. For the sake of simplicity, we consider that building a car consists of the following a **sequence** of three main **operations**:\n", "\n", "1. **Add Engine**: This is to add the engine to the car by an **Engine Hoist**;\n", "2. **Add Wheels**: This is to add the wheels to the car by a **Wheel Station**;\n", "3. **Inspect**: After the car has been built, it has to be inspected by an **Inspector**.\n", "\n", "\n", "\n", "Each operation of each job has a **duration (processing time)**, and the required **machine/resource** to process it. For example, the `add_engine` operation requires the `engine_hoist` to process it, and the `inspect` operation is required to be processed by the `inspector`.\n", "\n", "There are two constraints that a job shop schedule must satisfy:\n", "\n", "1. **Resource Constraint**: each machine can process at most one operation at a time.\n", "2. **Precedence Constraint**: each operation cannot start processing until its precedent operation in the same job has been completed (e.g., `add_wheels` cannot start until `add_engine` is completed). The first operation of a job can be started at time 0 (the job is already at the shop floor).\n", "\n", "The goal of job shop scheduling is to find a schedule with the minimal **makespan** (the completion time of the last completed job), subject to the above resource and precedence constraints.\n", "\n", "In the above car manufacturing example, let's assume that the factory has one `engine_hoist`, one `wheel_station` and one `inspector`, and there are two jobs described as follows:\n", "\n", "| Job | Operation | Machine | Duration |\n", "| --- | --------- | ------- | --------- |\n", "| 1 | `add_engine_1` | `engine_hoist` | 30 |\n", "| | `add_wheels_1` | `wheel_station` | 30 |\n", "| | `inspect_1` | `inspector` | 10 |\n", "| 2 | `add_engine_2` | `engine_hoist` | 60 |\n", "| | `add_wheels_2` | `wheel_station` | 15 |\n", "| | `inspect_2` | `inspector` | 10 |\n", "\n", "Below shows the gantt chart of two possible feasible schedules. The first schedule has a makespan of 115, while the second one has a makespan of 130.\n", "\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "id": "tYK9G0mePzNd" }, "source": [ "While `machine` can be defined straightforwardly, `operation` contains a number of properties. To wrap these properties, we can define an `operation` class in Python as follows." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "executionInfo": { "elapsed": 333, "status": "ok", "timestamp": 1646728803495, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "F2jXayMyPzNe" }, "outputs": [], "source": [ "class Operation:\n", " '''\n", " Construct an operation, including the following properties.\n", " - name of the operation\n", " - machine\n", " - duration (processing time)\n", " - prec (preceding operation)\n", " - succ (succeeding operation)\n", " '''\n", " def __init__(self, name, machine, duration, prec, succ):\n", " self.name = name\n", " self.machine = machine\n", " self.duration = duration\n", " self.prec = prec\n", " self.succ = succ" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A `job` consists of a sequence/list of operations. It might also have other properties such as `arrival_time`, `due_date`, `weight` that reflects its importance/urgency, etc. To wrap the job attributes, we define a `job` class in Python as follows." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "class Job:\n", " '''\n", " Construct a job, including the following properties.\n", " - job name\n", " - list of operations\n", " - arrival time, default to be 0\n", " - due date, default to be infinity\n", " - weight, default to be 1\n", " '''\n", " def __init__(self, name, operations):\n", " self.name = name\n", " self.operations = operations\n", " self.arrival_time = 0\n", " self.due_date = float('inf')\n", " self.weight = 1" ] }, { "cell_type": "markdown", "metadata": { "id": "wF3DBNFnPzNf" }, "source": [ "A job shop can then be represented as a list of `machines` and a list of `jobs`." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "class JobShop:\n", " '''\n", " Construct a job shop environment, including a list of machines and a list of jobs.\n", " '''\n", " def __init__(self, machines, jobs): \n", " self.machines = machines\n", " self.jobs = jobs\n", " \n", " # We also create a hash map to quickly access operations if needed\n", " self.operations = {}\n", " for job in jobs:\n", " for op in job.operations:\n", " self.operations[op.name] = op" ] }, { "cell_type": "markdown", "metadata": { "id": "EBMXm42VPzNg" }, "source": [ "----------\n", "\n", "## 2. State Space Search \n", "\n", "Following the AI planning paradigm, the **state space search** for schedules needs to define the (1) initial state, (2) goal states, and (3) set of actions. In addition, the search is in a job shop environment with a number of machines and jobs to be processed. To this end, we need to define **environment**, **state** and **action** for the state space search." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.A. Environment \n", "\n", "The job shop environment consists of a number of machines and jobs. Each job has a sequencing of operations. This includes all the static information that remain unchanged during the search. In other words, the environment stores the attributes that are not changed by the actions.\n", "\n", "Here, the job shop environment can be directly represented by the `JobShop` class defined above, as all the information there is not changed during the search." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.B. State \n", "\n", "A job shop state should include the temporal states of each operation and each machine during the search, such as whether a machine is busy or idle, and when it will complete the current operation if it's busy, whether an operation is ready to be processed (i.e., its precedent operation has been completed) or not, etc. It should also include the current time and the schedule so far.\n", "\n", "Here, we define the job shop **state** with the following attributes:\n", "\n", "1. `machine_idle_time`: **the idle time of each machine**. If the idle time of a machine is earlier than the current time, then the machine is idle. Otherwise, the machine is busy with processing some operation. It will complete its operation and become idle again at its `machine_idle_time`.\n", "2. `operation_ready_time`: **the ready time of each operation**. For the first operation of each job (with no precedent operation), its ready time is set to the job arrival time. Other operations are not ready yet, and their ready time can be treated as undefined (or $\\infty$). Then, once an operation has been completed, the ready time of its next operation is updated with the completion time of the operation.\n", "3. `schedule`: **the schedule so far**. It is initialised as empty (no operation has been scheduled). A complete schedule should have all the operations completed.\n", "4. `completed`: **the list of completed operations**. In the initial state, no operation is completed. In a goal state, all the operation are completed.\n", "\n", "We can define the `State` class in Python as follows." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "executionInfo": { "elapsed": 5, "status": "ok", "timestamp": 1646728803979, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "ypMjk6ek7X0z" }, "outputs": [], "source": [ "class State:\n", " '''\n", " Initialise the state with the job shop, i.e., a list of machines and a list of operations.\n", " '''\n", " def __init__(self, job_shop):\n", " # 1. Initially, the idle time of all the machines are 0.\n", " self.machine_idle_time = {}\n", " for machine in job_shop.machines:\n", " self.machine_idle_time[machine] = 0 \n", " \n", " # 2. Initially, all the operations except the first operations of the jobs are not ready.\n", " # Their ready time are undefined, so not added into the operation_ready_time.\n", " self.operation_ready_time = {}\n", " for job in job_shop.jobs:\n", " self.operation_ready_time[job.operations[0].name] = job.arrival_time\n", " \n", " # 3. Initial schedule is empty\n", " self.schedule = []\n", " \n", " # 4. Initially, no operation is completed, and the list is empty.\n", " self.completed = []" ] }, { "cell_type": "markdown", "metadata": { "id": "Wt5sj_TSPzNh" }, "source": [ "Based on the above definition of state, we have the following definitions of **initial state** and **goal state**.\n", "\n", "#### Initial State\n", "\n", "The **initial state** has the following variable values:\n", "\n", "- The **machine idle time** is 0 for all the machines;\n", "- The **operation ready time** is the job arrival time for the first operation of all the jobs, and undefined (infinity) for all the other operations;\n", "- The **schedule** is empty;\n", "- The **list of completed jobs** is empty.\n", "\n", "The initial state is generated by the above `State(job_shop)` construction method.\n", "\n", "#### Goal State\n", "\n", "A **goal state** satisfies the following condition:\n", "- The **list of completed jobs** contains all the operations in the problem.\n", "\n", "There can be many different goal states, each corresponding to a different schedule. To find the best schedule with the minimal makespan, we need to examine *ALL* the possible goal states and their schedule makespan." ] }, { "cell_type": "markdown", "metadata": { "id": "sDMDJ4vUPzNi" }, "source": [ "### 2.C. Action \n", "\n", "An **action** in the state space search is to **start processing** an `operation` by a `machine` at a specific `time`. \n", "\n", "It can be denoted as `Process(operation, machine, time)`. For example, we may have `Process(add_engine_1, engine_hoist, 0)` and `Process(add_engine_2, engine_hoist, 60)` for the previous car manufacturing problem. \n", "\n", "For each action, the **precondition** (i.e., in which states the action is applicable) and **effect** (i.e., how the action updates the state when being applied) are given as follows.\n", "\n", "#### Precondition\n", "\n", "- `operation` is uncompleted, and is ready at `time`, i.e., `operation_ready_time[operation] <= time`.\n", "- `machine` is idle at `time`, i.e., `machine_idle_time[machine] <= time`.\n", "\n", "#### Effect\n", "\n", "- `operation` becomes completed, i.e., `completed[operation] = True`.\n", "- `machine` becomes busy, and its idle time is updated to `machine_idle_time[machine] = time + duration[operation]`.\n", "- If `operation` is not the last operation in the job, then its next operation becomes ready once it is completed, i.e., `operation_ready_time[next[operation]] = time + duration[operation]`.\n", "\n", "We can define the `Process` action class in Python as follows." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "executionInfo": { "elapsed": 6, "status": "ok", "timestamp": 1646728803980, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "GiciG-DUPzNj" }, "outputs": [], "source": [ "import copy\n", "\n", "class Process:\n", " '''\n", " Construct a process with an operation, a machine and a time\n", " '''\n", " def __init__(self, operation, machine, time):\n", " self.operation = operation\n", " self.machine = machine\n", " self.time = time\n", " \n", " '''\n", " Check its precondition to see if it is applicable in a state.\n", " '''\n", " def is_applicable(self, state):\n", " # Check if the operation is completed or not.\n", " if self.operation.name in state.completed:\n", " return False\n", " \n", " # Check if the operation is ready now or not.\n", " if state.operation_ready_time[self.operation.name] > self.time:\n", " return False\n", " \n", " # Check if the machine is idle now or not.\n", " if state.machine_idle_time[self.machine] > self.time:\n", " return False\n", "\n", " return True\n", " \n", " '''\n", " Apply the processing action to a state, and return the resultant state.\n", " '''\n", " def apply(self, state):\n", " new_state = copy.deepcopy(state)\n", " \n", " # Add this process action to the schedule\n", " new_state.schedule.append(self)\n", " \n", " # The operation becomes completed\n", " new_state.completed.append(self.operation.name)\n", " \n", " # Delete the operation from operation_ready_time, since it is completed\n", " new_state.operation_ready_time.pop(self.operation.name)\n", " \n", " completion_time = self.time + self.operation.duration\n", " \n", " # The machine becomes busy, and will be idle again after the operation is completed\n", " new_state.machine_idle_time[self.machine] = completion_time\n", " \n", " # If the operation is not the last operation of the job, then its next operation becomes ready\n", " if self.operation.succ != None:\n", " new_state.operation_ready_time[self.operation.succ.name] = completion_time\n", " \n", " return new_state" ] }, { "cell_type": "markdown", "metadata": { "id": "fH0NGSVbPzNk" }, "source": [ "### 2.D. Overall Search Algorithm \n", "\n", "After designing the **state** and **action**, we now describe how to search for the best schedule in the state space.\n", "\n", "Note that the space space can be seen as a graph, where each state is a node, and each action is an edge/link to connect the nodes/states. Here, we follow the general **graph search** process which maintains a **fringe** of states that represents the current frontier during the search process. At each step, we pick one state from the fringe (i.e., visit a branch) to continue the search. The search stops after all the possible solutions have been found, and the fringe becomes empty. \n", "\n", "The pseudo code of the state space search can be described as follows.\n", "\n", "---------\n", "\n", "```python\n", "Generate an initial state, best_state = None, best_makespan = infinity\n", "# Initialise the fringe with the initial state\n", "fringe = [initial_state]\n", "\n", "# Search by expanding a branch at each step\n", "while fringe is not empty:\n", " Pick a state from fringe\n", " \n", " if state is a goal state:\n", " if state.schedule has a smaller makespan than best_makespan:\n", " best_state = state, best_makespan = makespan\n", " \n", " Find the applicable actions at state\n", " \n", " for action in applicable_actions:\n", " Apply action to state to generate next_state\n", " Add next_state into fringe\n", "\n", " remove state from fringe\n", "return best_state.schedule\n", "```\n", "\n", "-------------\n", "\n", "> Another commonly used graph search paradigm is based on recursion (e.g., recursively calling the search method at each node). Here we adopt the fringe-based graph search to facilitate other branching algorithms to be described later.\n", "\n", "#### Applicable Actions for State\n", "\n", "During the search process, an important step is to find the **applicable actions** for a state. By definition, a process action includes three components: `operation`, `machine` and `time`. While the first two components `operation` and `machine` are relatively straightforward from the ready operations and idle machines, the processing start `time` is not trivially defined. Specifically, we can start processing an operation with a machine any time after the operation is ready and the machine is idle. For example, if `operation` is ready at time 30 and `machine` is idle at time 40, then we can start processing `operation` by `machine` any time after time 40. This leads to infinite number of actions. \n", "\n", "To address this issue, we follow the common **non-delay** scheme, which means that no delay is allowed to process operations. In the above example where `operation` is ready at time 30 and `machine` is idle at time 40, there is *ONLY* one action `Process(operation, machine, 40)` under the non-delay scheme.\n", "\n", "We can use the `Process.is_applicable()` method in the above `Process` class to check whether an action is applicable to a state.\n", "\n", "The Python code for finding all the applicable actions for a state in a job shop environment can be written as follows." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "executionInfo": { "elapsed": 335, "status": "ok", "timestamp": 1646728804310, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "gZG5SpfgPzNk" }, "outputs": [], "source": [ "def applicable_actions(state, job_shop):\n", " actions = []\n", " \n", " # Enumerate all the operations in the operation_ready_time map.\n", " # For efficiency, this map ignores the operations whose ready time are still infinity \n", " # (they are not applicable anyway).\n", " for opname in state.operation_ready_time.keys():\n", " op = job_shop.operations[opname]\n", " \n", " time = state.operation_ready_time[opname]\n", " \n", " if time < state.machine_idle_time[op.machine]:\n", " time = state.machine_idle_time[op.machine]\n", " \n", " action = Process(op, op.machine, time)\n", " \n", " if action.is_applicable(state):\n", " actions.append(action)\n", " \n", " return actions" ] }, { "cell_type": "markdown", "metadata": { "id": "27WN3sXIPzNl" }, "source": [ "#### Goal State Check\n", "\n", "A state is a goal state if all the operations have been completed. This can be easily checked by\n", "```python\n", "if len(state.completed) == len(operations)\n", "```\n", "\n", "#### Schedule Makespan Calculation\n", "\n", "For each found goal state, we need to compare the corresponding schedule with the best schedule found so far. Specifically, we need to calculate the makespan of the schedule. Here, **a schedule is represented as a list of processing actions (the start time for processing each operation)**. The makespan is calculated as the maximal completion time of all the operations as follows." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "executionInfo": { "elapsed": 11, "status": "ok", "timestamp": 1646728804311, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "31OVzJijPzNl" }, "outputs": [], "source": [ "def makespan(schedule):\n", " makespan = 0\n", " \n", " for action in schedule:\n", " completion_time = action.time + action.operation.duration\n", " \n", " if completion_time > makespan:\n", " makespan = completion_time\n", " \n", " return makespan" ] }, { "cell_type": "markdown", "metadata": { "id": "2MVMOlOKPzNm" }, "source": [ "Taking the above into account, the Python code of the overall state space search algorithm is given as follows." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "executionInfo": { "elapsed": 12, "status": "ok", "timestamp": 1646728804312, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "PX95WGAaPzNm" }, "outputs": [], "source": [ "def state_space_search(job_shop):\n", " # Initialise the state and fringe\n", " init_state = State(job_shop)\n", " best_state = None\n", " best_makespan = float('inf')\n", " fringe = [init_state]\n", " \n", " while len(fringe) > 0:\n", " state = fringe[0] # arbitrarily pick the first state in the fringe\n", " \n", " # We have found a new goal state\n", " if len(state.completed) == len(job_shop.operations):\n", " new_makespan = makespan(state.schedule)\n", " \n", " if new_makespan < best_makespan:\n", " best_state = state\n", " best_makespan = new_makespan\n", " \n", " actions = applicable_actions(state, job_shop)\n", " for a in actions:\n", " next_state = a.apply(state)\n", " fringe.append(next_state)\n", " \n", " fringe.remove(state)\n", " \n", " return best_state.schedule" ] }, { "cell_type": "markdown", "metadata": { "id": "jwVYDzKuyGh2" }, "source": [ "### 2.E. Computational Complexity \n", "\n", "Assume that there are $N$ jobs and $M$ machines. Each job has $M$ operations, each to be processed by a different machine. There are $NM$ operations in total.\n", "\n", "At each state, there can be at most $N$ applicable actions, as each job can have an operation ready. In other words, each node in the search tree has $O(N)$ branches. \n", "\n", "Each action completes an operation. Thus, it takes $NM$ actions from the initial state to a goal state. In other words, the depth of the tree is $NM$.\n", "\n", "Therefore, to enumerate all the leaf nodes (goal states) of the search tree, one has to visit all the nodes in the search tree, which has a computational complexity of \n", "\n", "$$\n", "O(1 + N + N^2 + \\dots + N^{NM}) \\approx O(N^{NM}).\n", "$$" ] }, { "cell_type": "markdown", "metadata": { "id": "XZr98rXjPzNn" }, "source": [ "--------------------\n", "\n", "## 3. Case Study in Car Manufacturing \n", "\n", "Now, let's test this `state_space_search()` method to the above car manufacturing problem with two jobs. First, we input the problem data as follows." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "executionInfo": { "elapsed": 11, "status": "ok", "timestamp": 1646728804312, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "f7R0sFw6PzNn" }, "outputs": [], "source": [ "machines = ['engine_hoist', 'wheel_station', 'inspector']\n", "\n", "add_engine_1 = Operation('add_engine_1', 'engine_hoist', 30, None, None)\n", "add_wheels_1 = Operation('add_wheels_1', 'wheel_station', 30, add_engine_1, None)\n", "inspect_1 = Operation('inspect_1', 'inspector', 10, add_wheels_1, None)\n", "add_engine_2 = Operation('add_engine_2', 'engine_hoist', 60, None, None)\n", "add_wheels_2 = Operation('add_wheels_2', 'wheel_station', 15, add_engine_2, None)\n", "inspect_2 = Operation('inspect_2', 'inspector', 10, add_wheels_2, None)\n", "\n", "add_engine_1.succ = add_wheels_1\n", "add_wheels_1.succ = inspect_1\n", "add_engine_2.succ = add_wheels_2\n", "add_wheels_2.succ = inspect_2\n", "\n", "job_1 = Job('job_1', [add_engine_1, add_wheels_1, inspect_1])\n", "job_2 = Job('job_2', [add_engine_2, add_wheels_2, inspect_2])\n", "\n", "job_shop = JobShop(machines, [job_1, job_2])" ] }, { "cell_type": "markdown", "metadata": { "id": "_hEdlncYPzNn" }, "source": [ "Then we run the `state_space_search()` method to obtain the `schedule`." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 12, "status": "ok", "timestamp": 1646728804313, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "4Dyic2ltPzNn", "outputId": "85d5b756-1889-40c1-a445-22c2e36d8940" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "======= start printing state schedule ======\n", "add_engine_1: 0 --> 30\n", "add_engine_2: 30 --> 90\n", "add_wheels_1: 30 --> 60\n", "add_wheels_2: 90 --> 105\n", "inspect_1: 60 --> 70\n", "inspect_2: 105 --> 115\n", "======= finish printing state schedule ======\n", "makespan = 115\n" ] } ], "source": [ "schedule = state_space_search(job_shop)\n", "print(\"======= start printing state schedule ======\")\n", "for a in schedule:\n", " print(f'{a.operation.name}: {a.time} --> {a.time + a.operation.duration}')\n", "print(\"======= finish printing state schedule ======\")\n", "print(f'makespan = {makespan(schedule)}')" ] }, { "cell_type": "markdown", "metadata": { "id": "8u3ypiS5PzNo" }, "source": [ "-------------\n", "\n", "## 4. Display Schedule \n", "\n", "Now we want to display the schedule. To this end, we first convert the schedule into a Pandas data frame, which is easy to process. To this end, we design the following `schedule_data_frame()` method to convert a schedule to a corresponding data frame." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "executionInfo": { "elapsed": 9, "status": "ok", "timestamp": 1646728804313, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "ZOMN_oqHPzNp" }, "outputs": [], "source": [ "import pandas as pd\n", "\n", "def schedule_data_frame(schedule):\n", " # Convert each action to dictionary\n", " schedule_dict = []\n", " for action in schedule:\n", " a_dict = {\n", " 'Operation': action.operation.name,\n", " 'Machine': action.machine,\n", " 'Start': action.time,\n", " 'Duration': action.operation.duration,\n", " 'Finish': action.time + action.operation.duration\n", " }\n", " schedule_dict.append(a_dict)\n", " \n", " return pd.DataFrame(schedule_dict)" ] }, { "cell_type": "markdown", "metadata": { "id": "-o_fIm3sPzNp" }, "source": [ "### Data Frame Display\n", "\n", "After converting to data frame, a straightforward display is to directly show the data frame in different orders, such as **schedule by operation** and **schedule by machine**. Below is the example of the two display methods." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 329, "status": "ok", "timestamp": 1646728804634, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "bW4j4eFOPzNp", "outputId": "75dec8b3-f3d7-43e6-98b7-97f95783824d" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Schedule by Operation\n", " Start Duration Finish\n", "Operation Machine \n", "add_engine_1 engine_hoist 0 30 30\n", "add_engine_2 engine_hoist 30 60 90\n", "add_wheels_1 wheel_station 30 30 60\n", "add_wheels_2 wheel_station 90 15 105\n", "inspect_1 inspector 60 10 70\n", "inspect_2 inspector 105 10 115\n", "\n", "Schedule by Machine\n", " Start Duration Finish\n", "Machine Operation \n", "engine_hoist add_engine_1 0 30 30\n", " add_engine_2 30 60 90\n", "inspector inspect_1 60 10 70\n", " inspect_2 105 10 115\n", "wheel_station add_wheels_1 30 30 60\n", " add_wheels_2 90 15 105\n" ] } ], "source": [ "def display(schedule):\n", " df = schedule_data_frame(schedule)\n", "\n", " print('\\nSchedule by Operation')\n", " print(df.sort_values(by=['Operation','Start']).set_index(['Operation', 'Machine']))\n", "\n", " print('\\nSchedule by Machine')\n", " print(df.sort_values(by=['Machine','Start']).set_index(['Machine', 'Operation']))\n", "\n", "display(schedule)" ] }, { "cell_type": "markdown", "metadata": { "id": "Icpg8nxEPzNp" }, "source": [ "### Gantt Chart Plot\n", "\n", "A better visualisation method is to draw the gantt chart of the schedule. For this purpose, we need to use the `matplotlib` Python library. We first install this library." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 4389, "status": "ok", "timestamp": 1646728809020, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "jQt8kxEuPzNq", "outputId": "b48822e4-95da-46cc-c781-f30d79d79a91" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: matplotlib in /Users/yimei/miniforge3/lib/python3.9/site-packages (3.5.1)\n", "Requirement already satisfied: cycler>=0.10 in /Users/yimei/miniforge3/lib/python3.9/site-packages (from matplotlib) (0.11.0)\n", "Requirement already satisfied: packaging>=20.0 in /Users/yimei/miniforge3/lib/python3.9/site-packages (from matplotlib) (21.3)\n", "Requirement already satisfied: pillow>=6.2.0 in /Users/yimei/miniforge3/lib/python3.9/site-packages (from matplotlib) (9.0.1)\n", "Requirement already satisfied: numpy>=1.17 in /Users/yimei/miniforge3/lib/python3.9/site-packages (from matplotlib) (1.21.2)\n", "Requirement already satisfied: kiwisolver>=1.0.1 in /Users/yimei/miniforge3/lib/python3.9/site-packages (from matplotlib) (1.3.2)\n", "Requirement already satisfied: pyparsing>=2.2.1 in /Users/yimei/miniforge3/lib/python3.9/site-packages (from matplotlib) (3.0.6)\n", "Requirement already satisfied: python-dateutil>=2.7 in /Users/yimei/miniforge3/lib/python3.9/site-packages (from matplotlib) (2.8.2)\n", "Requirement already satisfied: fonttools>=4.22.0 in /Users/yimei/miniforge3/lib/python3.9/site-packages (from matplotlib) (4.29.1)\n", "Requirement already satisfied: six>=1.5 in /Users/yimei/miniforge3/lib/python3.9/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "pip install matplotlib" ] }, { "cell_type": "markdown", "metadata": { "id": "hgx35sViPzNq" }, "source": [ "Then we design the following `visualise()` method to plot the gantt chart of the schedule." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 531 }, "executionInfo": { "elapsed": 841, "status": "ok", "timestamp": 1646728809849, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "uWfDzGJsPzNq", "outputId": "caa0d262-c2dd-4e6f-847f-273c1bc63f31" }, "outputs": [ { "data": { "image/png": "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6e5dKqwkIiIiIiLSiFTnh4Z3eJrA6FURcDTwLPB8bQQlIiIiIiKN1/Je8Ww5cmC4w6iRvUmw4t19PGDuvszdbwNOqp2wRERERESksVp4QDKbThkW7jBqZG8Wuci3wK+ELTCzy4FVUC9/XFlERKTO2ph4Pv1PejrcYYhIHdX/2D/R/9j6t3T5XsvNDXcENbY3I1hXAgnAFcBg4Dzg/NoISkREREREGrETTwxs9dDerCI4Ofg0G7iwdsIRERERERGpv6pMsMzs3cqOu/spoQtHRERERESk/qrOCNZQYAXwEvA9YLUakYiIiIiISD1VnQSrNXAscDbwa+AD4CV3n12bgYmIiIiIiNQ3VSZY7l4MfAx8bGaxBBKtTDO73d0frO0ARURERESkkbnggnBHUGPVWuQimFidRCC5SgceAN6qvbBERERERKTRasgJlpk9C/QDPgRud/dZtR6ViIiIiIg0Xhs2BB6bNw9vHDVQnRGsc4EcAr+DdYVZ6RoXBri7p9RSbCIiIiIi0hidfnrgMTMzrGHURHXuwdqbHyMWERERERFptJQ8iYiIiIiIhIgSLBERERERkRBRgiUiIiIiIhIi1VqmXUREREREZL/5/e/DHUGNKcESEREREZG65cwzwx1BjWmKoIiIiIiI1C0rVgS2ekgjWCIiIiIiUrecd17gsR7+DpZGsEREREREREJECZaIiIiIiEiIKMESEREREREJESVYIiIiIiIiIaJFLkREREREpG655ppwR1BjSrBERERERKRuGTUq3BHUmKYIioiIiIhI3TJvXmCrhzSCJSIiIiIidcullwYe9TtYIiIiIiIijZcSLBERERERkRBRgiUiIiIiIhIiSrBERERERERCRItciIiIiIhI3XLzzeGOoMaUYImIiIiISN0yYkS4I6gxTREUEREREZG6ZcaMwFYPaQRLRERERETqlquuCjzqd7BEREREREQaLyVYIiIiIiIiIaIES0REREREJESUYImIiIiIiISIFrkQEREREZG65e67wx1BjSnBEhERERGRuuWww8IdQY1piqCIiIiIiNQt334b2OohjWBJOcnTn2H+2OHhDkNCrC0wf2y4o9g/5gx8hG+Xtw13GPvNh++8H+4QpBboujZMjeW6jji+O8eN7BnuMKS+u+mmwKN+B0tERERERKTxUoIlIiIiIiISIkqwRERERERE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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "import matplotlib as mpl\n", "\n", "def visualise(schedule):\n", " schedule = schedule_data_frame(schedule)\n", " \n", " JOBS = sorted(list(schedule['Operation'].unique()))\n", " MACHINES = sorted(list(schedule['Machine'].unique()))\n", " makespan = schedule['Finish'].max()\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", " schedule.sort_values(by=['Operation', 'Start'])\n", " schedule.set_index(['Operation', 'Machine'], inplace=True)\n", "\n", " fig, ax = plt.subplots(2,1, figsize=(12, 5+(len(JOBS)+len(MACHINES))/4))\n", "\n", " for jdx, j in enumerate(JOBS, 1):\n", " for mdx, m in enumerate(MACHINES, 1):\n", " if (j,m) in schedule.index:\n", " xs = schedule.loc[(j,m), 'Start']\n", " xf = schedule.loc[(j,m), 'Finish']\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", " \n", " ax[0].set_title('Job Schedule')\n", " ax[0].set_ylabel('Operation')\n", " ax[1].set_title('Machine Schedule')\n", " ax[1].set_ylabel('Machine')\n", " \n", " for idx, s in enumerate([JOBS, 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(makespan, ax[idx].get_ylim()[0]-0.2, \"{0:0.1f}\".format(makespan), ha='center', va='top')\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", "\n", "visualise(schedule)" ] }, { "cell_type": "markdown", "metadata": { "id": "JFElKdmEPzNr" }, "source": [ "--------------\n", "\n", "## 5. Jobs with Different Operation Sequences \n", "\n", "In job shop scheduling, different jobs can have different operation sequences. For example, in the car manufacturing problem, we can have one job with the sequence of [`add_engine` $\\rightarrow$ `add_wheels` $\\rightarrow$ `inspect`], and another job with [`add_wheels` $\\rightarrow$ `add_engine` $\\rightarrow$ `inspect`].\n", "\n", "The state space search can be directly applied to job shop scheduling with any operation sequences.\n", "\n", "To show an example, we create the following job shop scheduling instance (`add_engine_2` and `add_wheels_2` are swapped in job 2):\n", "\n", "\n", "| Job | Operation | Machine | Duration |\n", "| --- | --------- | ------- | --------- |\n", "| 1 | `add_engine_1` | `engine_hoist` | 30 |\n", "| | `add_wheels_1` | `wheel_station` | 30 |\n", "| | `inspect_1` | `inspector` | 10 |\n", "| 2 | `add_wheels_2` | `wheel_station` | 15 |\n", "| | `add_engine_2` | `engine_hoist` | 60 |\n", "| | `inspect_2` | `inspector` | 10 |" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "executionInfo": { "elapsed": 8, "status": "ok", "timestamp": 1646728809850, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "IOIf1TFAPzNr" }, "outputs": [], "source": [ "machines = ['engine_hoist', 'wheel_station', 'inspector']\n", "\n", "add_engine_1 = Operation('add_engine_1', 'engine_hoist', 30, None, None)\n", "add_wheels_1 = Operation('add_wheels_1', 'wheel_station', 30, add_engine_1, None)\n", "inspect_1 = Operation('inspect_1', 'inspector', 10, add_wheels_1, None)\n", "add_wheels_2 = Operation('add_wheels_2', 'wheel_station', 15, None, None)\n", "add_engine_2 = Operation('add_engine_2', 'engine_hoist', 60, add_wheels_2, None)\n", "inspect_2 = Operation('inspect_2', 'inspector', 10, add_engine_2, None)\n", "\n", "add_engine_1.succ = add_wheels_1\n", "add_wheels_1.succ = inspect_1\n", "add_wheels_2.succ = add_engine_2\n", "add_engine_2.succ = inspect_2\n", "\n", "job_1 = Job('job_1', [add_engine_1, add_wheels_1, inspect_1])\n", "job_2 = Job('job_2', [add_wheels_2, add_engine_2, inspect_2])\n", "\n", "job_shop_2 = JobShop(machines, [job_1, job_2])" ] }, { "cell_type": "markdown", "metadata": { "id": "5O3zTcIdPzNr" }, "source": [ "Then we run the state space search algorithm and visualise the gantt chart of the found best schedule." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 531 }, "executionInfo": { "elapsed": 892, "status": "ok", "timestamp": 1646728810735, "user": { "displayName": "Yi Mei", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GhjbsloGGj8mKvkgwfMTyhu9iqFZUz599lVh7y-zA=s64", "userId": "14923329265121969261" }, "user_tz": -780 }, "id": "Jdx2OQtnPzNr", "outputId": "53617c72-b66d-431f-f23e-45bd91346560" }, "outputs": [ { "data": { "image/png": "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icCF7l4axfAkisysH4FFUJKAecBlBL7g1TVEMLO7gHMJ/PE8EfgFgXtmdA05AJjZy0Ae0JjAKNUdwMnAqQSuGaUE7vN9kcA1Y0CwfAGB5Gk88DCB82YWgesLBFYnTAX+B/za93LCowRLREREREQkQjRFUEREREREJEKUYImIiIiIiESIEiwREREREZEIUYIlIiIiIiISIUqwREREREREIkQJloiIyC4wsxwzmxT8WWFmS4OvC83s0WjHJyIi0aVl2kVERHaTmd0JFLr7fdGORUREYoNGsERERCLAzPLMbGTw9Z1m9qyZfW1mC83sJ2b2NzObYmYfmllisN4AM/vSzMab2Udm1iK6RyEiIntKCZaIiEj96AgcC5wOvAB84e69gRLglGCS9S/gLHcfADwN/ClawYqISGQkRDsAERGR/dT/3L3czKYA8cCHwfIpQC7QFegFfGJmBOssj0KcIiISQUqwRERE6kcpgLtXmVm5b7vpuYrA718Dprn7oGgFKCIikacpgiIiItExE2hiZoMAzCzRzHpGOSYREdlDSrBERESiwN3LgLOAv5rZZGAScHhUgxIRkT2mZdpFREREREQiRCNYIiIiIiIiEaIES0REREREJEKUYImIiIiIiESIEiwREREREZEIUYIlIiIiIiISIUqwREREREREIkQJloiIiIiISIQowRIREREREYkQJVgiIiIiIiIRogRLREREREQkQpRgiYiIiIiIRIgSLBERERERkQhRgiUiIgcEMxthZvfUsr3QzDrszZhqY2b5ZvaLCPV1p5m9EOm6IiKyIyVYIiISE8xsgZmVmVnj7conmpmbWW597t/dM9x9XqT7NbOeZvaxma0zswIzG29mJ0d6PyIiEhuUYImISCyZD5y/5Y2Z9QbSohdORLwHfAI0B5oC1wIboxqRiIjUGyVYIiISS54HLg55fwnwXGgFMzslOKq10cwWm9md220/wsy+DY4WLTazS0M2NzKz981sk5l9b2YdQ9q5mXUKvh5hZo/UUrebmX0SHJWaaWbn7OxggqNx7YEn3L0s+DPK3b8JqXOGmU0KHs9cMxsa0kU7MxsVjOHj0NE9Mzss5Dgnm1leyLb2ZvZlsN0nQGi7PDNbsl2cC8zsuBqOocb9iIjIjpRgiYhILPkOyDKz7mYWD5wHbH8/UBGBJKwhcArwSzMbBmBm7YD/Af8C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YOskSnfvUGMjERERERGRA0hdHjS8xTMERq8qgGOA54AX6iMoERERERGRUIu6pbJsYKdohxHWriRYqe7+GWDuvtDd7wROqZ+wREREREREtplzUCYL8/pEO4ywdmWRi1ILPCFstpldAywFMuonLBEREdkfrU2/hN6nPBPtMET2Gb2P/w29j/9NtMOIDcXFfPXVV9GOIqxdSbCuA9KAa4G7gWOBS+ojKBERERERkWpOPpk+BQUwdGi0I6nVrqwiODb4shC4rH7CERERERER2XeFTbDM7N3atrv76ZELR0REREREZN9VlxGsQcBi4GXge8DqNSIREREREZF9VF0SrObA8cD5wM+A94GX3X1afQYmIiIiIiKyrwm7TLu7V7r7h+5+CXAYMAfID64kKCIiIiIiUv8uvZQVMb7ABdRxkQszSybwzKvzgVzgIeCt+gtLREREREQkxKWXsiI/n27RjiOMuixy8RzQC/gAuMvdp9Z7VCIiIiIiIqHWrCFxw4ZoRxFWXUawLgSKCDwH61qzrWtcGODunlVPsYmIiIiIiAScdRY9CwrgjDOiHUmtwiZY7h72Pi0RERERERGpwyIXIiIiIiIiUjdKsERERERERCJECZaIiIiIiEiE1GmZdhERERERkaj65S9ZOm0aDaMdRxhKsEREREREJPadey6r8/OjHUVYmiIoIiIiIiKxb/FikletinYUYWkES0REREREYt9FF9G9oADOOSfakdRKI1giIiIiIiIRogRLREREREQkQpRgiYiIiIiIRIgSLBERERERkQjRIhciIiIiIhL7bryRxVOm6DlYIiIiIiIie+y001ibmRntKMLSFEEREREREYl9M2eSumhRtKMISyNYIiIiIiIS+666iq4FBXDxxdGOpFYawRIREREREYkQJVgiIiIiIiIRogRLREREREQkQpRgiYiIiIiIRIgWuRARERERkdj3hz+wcPJkPQdLRERERERkjx13HOsTYj990RRBERERERGJfZMmkTFnTrSjCEsJloiIiIiIxL7rr6fTww9HO4qwlGCJiIiIiIhEiBIsERERERGRCFGCJSIiIiIiEiFKsERERERERCIk9tc5FBERERER+fOfmTdhAv2jHUcYSrBERERERCT2HX44G8vKoh1FWJoiKCIiIiIise/bb8maOjXaUYRl7h7tGAQYOHCgjxs3LtphMP7+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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "schedule_2 = state_space_search(job_shop_2)\n", "visualise(schedule_2)" ] }, { "cell_type": "markdown", "metadata": { "id": "7MoVlTLkPzNr" }, "source": [ "---------------\n", "\n", "The original Juypter Notebook can be downloaded [here](https://homepages.ecs.vuw.ac.nz/~yimei/tutorials/job-shop-scheduling-state-space-search.ipynb).\n", "\n", "More tutorials can be found [here](https://meiyi1986.github.io/tutorials/).\n", "\n", "[Yi Mei's homepage](https://meiyi1986.github.io/)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "colab": { "name": "job-shop-scheduling-state-space-search.ipynb", "provenance": [] }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.9.6" } }, "nbformat": 4, "nbformat_minor": 1 }