diff --git a/JSSEnv/__init__.py b/JSSEnv/__init__.py index b9261d2..8fe54d8 100644 --- a/JSSEnv/__init__.py +++ b/JSSEnv/__init__.py @@ -1,6 +1,7 @@ from gym.envs.registration import register + register( - id='JSSEnv-v1', - entry_point='JSSEnv.envs:JssEnv', + id="jss-v1", + entry_point="JSSEnv.envs:JssEnv", ) diff --git a/JSSEnv/envs/__init__.py b/JSSEnv/envs/__init__.py index 12b7c8e..f2a3681 100644 --- a/JSSEnv/envs/__init__.py +++ b/JSSEnv/envs/__init__.py @@ -1 +1 @@ -from JSSEnv.envs.JssEnv import JssEnv \ No newline at end of file +from JSSEnv.envs.jss_env import JssEnv diff --git a/JSSEnv/envs/JssEnv.py b/JSSEnv/envs/jss_env.py similarity index 66% rename from JSSEnv/envs/JssEnv.py rename to JSSEnv/envs/jss_env.py index 671998d..0b2cf7b 100644 --- a/JSSEnv/envs/JssEnv.py +++ b/JSSEnv/envs/jss_env.py @@ -8,12 +8,9 @@ import plotly.figure_factory as ff from pathlib import Path -from ray.rllib.env.env_context import EnvContext - class JssEnv(gym.Env): - - def __init__(self, config: EnvContext = None, env_config = None): + def __init__(self, env_config=None): """ This environment model the job shop scheduling problem as a single agent problem: @@ -27,22 +24,15 @@ def __init__(self, config: EnvContext = None, env_config = None): we automatically go to the next time step until we have a legal action - - :param config: Ray config dictionary as EnvContext, following the injection paradigm - :param env_config: (Alternative) dictionary for config parameters to ensure gym.make() compatibility + :param env_config: Ray dictionary of config parameter """ + if env_config is None: + env_config = { + "instance_path": str(Path(__file__).parent.absolute()) + + "/instances/ta80" + } + instance_path = env_config["instance_path"] - # This part should be default for ray rllib when working with default_config approach like in the example - # https://github.com/ray-project/ray/blob/master/rllib/examples/custom_env.py) - if config is not None: - instance_path = str( - Path(__file__).parent.absolute()) + config['instance_path'] - else: - # This part should be used when instantiating environment instance with gym.make(). - if env_config is not None: - instance_path = str(Path(__file__).parent.absolute()) + env_config['instance_path'] - else: - instance_path = str(Path(__file__).parent.absolute()) + '/instances/ta80' - # initial values for variables used for instance self.jobs = 0 self.machines = 0 @@ -54,8 +44,8 @@ def __init__(self, config: EnvContext = None, env_config = None): self.nb_machine_legal = 0 # initial values for variables used for solving (to reinitialize when reset() is called) self.solution = None - self.last_time_step = float('inf') - self.current_time_step = float('inf') + self.last_time_step = float("inf") + self.current_time_step = float("inf") self.next_time_step = list() self.next_jobs = list() self.legal_actions = None @@ -73,19 +63,19 @@ def __init__(self, config: EnvContext = None, env_config = None): # initial values for variables used for representation self.start_timestamp = datetime.datetime.now().timestamp() self.sum_op = 0 - instance_file = open(instance_path, 'r') + instance_file = open(instance_path, "r") line_str = instance_file.readline() line_cnt = 1 while line_str: split_data = line_str.split() if line_cnt == 1: - self.jobs, self.machines = int( - split_data[0]), int(split_data[1]) + self.jobs, self.machines = int(split_data[0]), int(split_data[1]) # matrix which store tuple of (machine, length of the job) self.instance_matrix = np.zeros( - (self.jobs, self.machines), dtype=(np.int, 2)) + (self.jobs, self.machines), dtype=(int, 2) + ) # contains all the time to complete jobs - self.jobs_length = np.zeros(self.jobs, dtype=np.int) + self.jobs_length = np.zeros(self.jobs, dtype=int) else: # couple (machine, time) assert len(split_data) % 2 == 0 @@ -109,7 +99,7 @@ def __init__(self, config: EnvContext = None, env_config = None): assert self.max_time_op > 0 assert self.max_time_jobs > 0 assert self.jobs > 0 - assert self.machines > 1, 'We need at least 2 machines' + assert self.machines > 1, "We need at least 2 machines" assert self.instance_matrix is not None # allocate a job + one to wait self.action_space = gym.spaces.Discrete(self.jobs + 1) @@ -117,7 +107,7 @@ def __init__(self, config: EnvContext = None, env_config = None): self.colors = [ tuple([random.random() for _ in range(3)]) for _ in range(self.machines) ] - ''' + """ matrix with the following attributes for each job: -Legal job -Left over time on the current op @@ -126,11 +116,15 @@ def __init__(self, config: EnvContext = None, env_config = None): -When next machine available -Time since IDLE: 0 if not available, time otherwise -Total IDLE time in the schedule - ''' - self.observation_space = gym.spaces.Dict({ - "action_mask": gym.spaces.Box(0, 1, shape=(self.jobs + 1,)), - "real_obs": gym.spaces.Box(low=0.0, high=1.0, shape=(self.jobs, 7), dtype=np.float), - }) + """ + self.observation_space = gym.spaces.Dict( + { + "action_mask": gym.spaces.Box(0, 1, shape=(self.jobs + 1,)), + "real_obs": gym.spaces.Box( + low=0.0, high=1.0, shape=(self.jobs, 7), dtype=float + ), + } + ) def _get_current_state_representation(self): self.state[:, 0] = self.legal_actions[:-1] @@ -149,30 +143,27 @@ def reset(self): self.nb_legal_actions = self.jobs self.nb_machine_legal = 0 # represent all the legal actions - self.legal_actions = np.ones(self.jobs + 1, dtype=np.bool) + self.legal_actions = np.ones(self.jobs + 1, dtype=bool) self.legal_actions[self.jobs] = False # used to represent the solution - self.solution = np.full((self.jobs, self.machines), -1, dtype=np.int) - self.time_until_available_machine = np.zeros( - self.machines, dtype=np.int) - self.time_until_finish_current_op_jobs = np.zeros( - self.jobs, dtype=np.int) - self.todo_time_step_job = np.zeros(self.jobs, dtype=np.int) - self.total_perform_op_time_jobs = np.zeros(self.jobs, dtype=np.int) - self.needed_machine_jobs = np.zeros(self.jobs, dtype=np.int) - self.total_idle_time_jobs = np.zeros(self.jobs, dtype=np.int) - self.idle_time_jobs_last_op = np.zeros(self.jobs, dtype=np.int) - self.illegal_actions = np.zeros( - (self.machines, self.jobs), dtype=np.bool) - self.action_illegal_no_op = np.zeros(self.jobs, dtype=np.bool) - self.machine_legal = np.zeros(self.machines, dtype=np.bool) + self.solution = np.full((self.jobs, self.machines), -1, dtype=int) + self.time_until_available_machine = np.zeros(self.machines, dtype=int) + self.time_until_finish_current_op_jobs = np.zeros(self.jobs, dtype=int) + self.todo_time_step_job = np.zeros(self.jobs, dtype=int) + self.total_perform_op_time_jobs = np.zeros(self.jobs, dtype=int) + self.needed_machine_jobs = np.zeros(self.jobs, dtype=int) + self.total_idle_time_jobs = np.zeros(self.jobs, dtype=int) + self.idle_time_jobs_last_op = np.zeros(self.jobs, dtype=int) + self.illegal_actions = np.zeros((self.machines, self.jobs), dtype=bool) + self.action_illegal_no_op = np.zeros(self.jobs, dtype=bool) + self.machine_legal = np.zeros(self.machines, dtype=bool) for job in range(self.jobs): needed_machine = self.instance_matrix[job][0][0] self.needed_machine_jobs[job] = needed_machine if not self.machine_legal[needed_machine]: self.machine_legal[needed_machine] = True self.nb_machine_legal += 1 - self.state = np.zeros((self.jobs, 7), dtype=np.float) + self.state = np.zeros((self.jobs, 7), dtype=float) return self._get_current_state_representation() def _prioritization_non_final(self): @@ -181,36 +172,57 @@ def _prioritization_non_final(self): if self.machine_legal[machine]: final_job = list() non_final_job = list() - min_non_final = float('inf') + min_non_final = float("inf") for job in range(self.jobs): - if self.needed_machine_jobs[job] == machine and self.legal_actions[job]: + if ( + self.needed_machine_jobs[job] == machine + and self.legal_actions[job] + ): if self.todo_time_step_job[job] == (self.machines - 1): final_job.append(job) else: - current_time_step_non_final = self.todo_time_step_job[job] - time_needed_legal = self.instance_matrix[job][current_time_step_non_final][1] - machine_needed_nextstep = self.instance_matrix[ - job][current_time_step_non_final + 1][0] - if self.time_until_available_machine[machine_needed_nextstep] == 0: + current_time_step_non_final = self.todo_time_step_job[ + job + ] + time_needed_legal = self.instance_matrix[job][ + current_time_step_non_final + ][1] + machine_needed_nextstep = self.instance_matrix[job][ + current_time_step_non_final + 1 + ][0] + if ( + self.time_until_available_machine[ + machine_needed_nextstep + ] + == 0 + ): min_non_final = min( - min_non_final, time_needed_legal) + min_non_final, time_needed_legal + ) non_final_job.append(job) if len(non_final_job) > 0: for job in final_job: current_time_step_final = self.todo_time_step_job[job] - time_needed_legal = self.instance_matrix[job][current_time_step_final][1] + time_needed_legal = self.instance_matrix[job][ + current_time_step_final + ][1] if time_needed_legal > min_non_final: self.legal_actions[job] = False self.nb_legal_actions -= 1 def _check_no_op(self): self.legal_actions[self.jobs] = False - if len(self.next_time_step) > 0 and self.nb_machine_legal <= 3 and self.nb_legal_actions <= 4: + if ( + len(self.next_time_step) > 0 + and self.nb_machine_legal <= 3 + and self.nb_legal_actions <= 4 + ): machine_next = set() next_time_step = self.next_time_step[0] max_horizon = self.current_time_step - max_horizon_machine = [self.current_time_step + - self.max_time_op for _ in range(self.machines)] + max_horizon_machine = [ + self.current_time_step + self.max_time_op for _ in range(self.machines) + ] for job in range(self.jobs): if self.legal_actions[job]: time_step = self.todo_time_step_job[job] @@ -220,33 +232,52 @@ def _check_no_op(self): if end_job < next_time_step: return max_horizon_machine[machine_needed] = min( - max_horizon_machine[machine_needed], end_job) - max_horizon = max( - max_horizon, max_horizon_machine[machine_needed]) + max_horizon_machine[machine_needed], end_job + ) + max_horizon = max(max_horizon, max_horizon_machine[machine_needed]) for job in range(self.jobs): if not self.legal_actions[job]: - if self.time_until_finish_current_op_jobs[job] > 0 and \ - self.todo_time_step_job[job] + 1 < self.machines: + if ( + self.time_until_finish_current_op_jobs[job] > 0 + and self.todo_time_step_job[job] + 1 < self.machines + ): time_step = self.todo_time_step_job[job] + 1 - time_needed = self.current_time_step + \ - self.time_until_finish_current_op_jobs[job] - while time_step < self.machines - 1 and max_horizon > time_needed: + time_needed = ( + self.current_time_step + + self.time_until_finish_current_op_jobs[job] + ) + while ( + time_step < self.machines - 1 and max_horizon > time_needed + ): machine_needed = self.instance_matrix[job][time_step][0] - if max_horizon_machine[machine_needed] > time_needed and self.machine_legal[machine_needed]: + if ( + max_horizon_machine[machine_needed] > time_needed + and self.machine_legal[machine_needed] + ): machine_next.add(machine_needed) if len(machine_next) == self.nb_machine_legal: self.legal_actions[self.jobs] = True return time_needed += self.instance_matrix[job][time_step][1] time_step += 1 - elif not self.action_illegal_no_op[job] and self.todo_time_step_job[job] < self.machines: + elif ( + not self.action_illegal_no_op[job] + and self.todo_time_step_job[job] < self.machines + ): time_step = self.todo_time_step_job[job] machine_needed = self.instance_matrix[job][time_step][0] - time_needed = self.current_time_step + \ - self.time_until_available_machine[machine_needed] - while time_step < self.machines - 1 and max_horizon > time_needed: + time_needed = ( + self.current_time_step + + self.time_until_available_machine[machine_needed] + ) + while ( + time_step < self.machines - 1 and max_horizon > time_needed + ): machine_needed = self.instance_matrix[job][time_step][0] - if max_horizon_machine[machine_needed] > time_needed and self.machine_legal[machine_needed]: + if ( + max_horizon_machine[machine_needed] > time_needed + and self.machine_legal[machine_needed] + ): machine_next.add(machine_needed) if len(machine_next) == self.nb_machine_legal: self.legal_actions[self.jobs] = True @@ -267,11 +298,16 @@ def step(self, action: int): self.illegal_actions[needed_machine][job] = True self.action_illegal_no_op[job] = True while self.nb_machine_legal == 0: - reward -= self._increase_time_step() + reward -= self.increase_time_step() scaled_reward = self._reward_scaler(reward) self._prioritization_non_final() self._check_no_op() - return self._get_current_state_representation(), scaled_reward, self._is_done(), {} + return ( + self._get_current_state_representation(), + scaled_reward, + self._is_done(), + {}, + ) else: current_time_step_job = self.todo_time_step_job[action] machine_needed = self.needed_machine_jobs[action] @@ -282,13 +318,15 @@ def step(self, action: int): self.state[action][1] = time_needed / self.max_time_op to_add_time_step = self.current_time_step + time_needed if to_add_time_step not in self.next_time_step: - index = bisect.bisect_left( - self.next_time_step, to_add_time_step) + index = bisect.bisect_left(self.next_time_step, to_add_time_step) self.next_time_step.insert(index, to_add_time_step) self.next_jobs.insert(index, action) self.solution[action][current_time_step_job] = self.current_time_step for job in range(self.jobs): - if self.needed_machine_jobs[job] == machine_needed and self.legal_actions[job]: + if ( + self.needed_machine_jobs[job] == machine_needed + and self.legal_actions[job] + ): self.legal_actions[job] = False self.nb_legal_actions -= 1 self.nb_machine_legal -= 1 @@ -299,17 +337,22 @@ def step(self, action: int): self.illegal_actions[machine_needed][job] = False # if we can't allocate new job in the current timestep, we pass to the next one while self.nb_machine_legal == 0 and len(self.next_time_step) > 0: - reward -= self._increase_time_step() + reward -= self.increase_time_step() self._prioritization_non_final() self._check_no_op() # we then need to scale the reward scaled_reward = self._reward_scaler(reward) - return self._get_current_state_representation(), scaled_reward, self._is_done(), {} + return ( + self._get_current_state_representation(), + scaled_reward, + self._is_done(), + {}, + ) def _reward_scaler(self, reward): return reward / self.max_time_op - def _increase_time_step(self): + def increase_time_step(self): """ The heart of the logic his here, we need to increase every counter when we have a nope action called and return the time elapsed @@ -324,27 +367,37 @@ def _increase_time_step(self): was_left_time = self.time_until_finish_current_op_jobs[job] if was_left_time > 0: performed_op_job = min(difference, was_left_time) - self.time_until_finish_current_op_jobs[job] = max(0, self.time_until_finish_current_op_jobs[ - job] - difference) - self.state[job][1] = self.time_until_finish_current_op_jobs[job] / \ - self.max_time_op + self.time_until_finish_current_op_jobs[job] = max( + 0, self.time_until_finish_current_op_jobs[job] - difference + ) + self.state[job][1] = ( + self.time_until_finish_current_op_jobs[job] / self.max_time_op + ) self.total_perform_op_time_jobs[job] += performed_op_job - self.state[job][3] = self.total_perform_op_time_jobs[job] / \ - self.max_time_jobs + self.state[job][3] = ( + self.total_perform_op_time_jobs[job] / self.max_time_jobs + ) if self.time_until_finish_current_op_jobs[job] == 0: - self.total_idle_time_jobs[job] += ( - difference - was_left_time) + self.total_idle_time_jobs[job] += difference - was_left_time self.state[job][6] = self.total_idle_time_jobs[job] / self.sum_op - self.idle_time_jobs_last_op[job] = ( - difference - was_left_time) + self.idle_time_jobs_last_op[job] = difference - was_left_time self.state[job][5] = self.idle_time_jobs_last_op[job] / self.sum_op self.todo_time_step_job[job] += 1 - self.state[job][2] = self.todo_time_step_job[job] / \ - self.machines + self.state[job][2] = self.todo_time_step_job[job] / self.machines if self.todo_time_step_job[job] < self.machines: - self.needed_machine_jobs[job] = self.instance_matrix[job][self.todo_time_step_job[job]][0] - self.state[job][4] = max(0, self.time_until_available_machine[ - self.needed_machine_jobs[job]] - difference) / self.max_time_op + self.needed_machine_jobs[job] = self.instance_matrix[job][ + self.todo_time_step_job[job] + ][0] + self.state[job][4] = ( + max( + 0, + self.time_until_available_machine[ + self.needed_machine_jobs[job] + ] + - difference, + ) + / self.max_time_op + ) else: self.needed_machine_jobs[job] = -1 # this allow to have 1 is job is over (not 0 because, 0 strongly indicate that the job is a @@ -362,12 +415,16 @@ def _increase_time_step(self): if self.time_until_available_machine[machine] < difference: empty = difference - self.time_until_available_machine[machine] hole_planning += empty - self.time_until_available_machine[machine] = max(0, self.time_until_available_machine[ - machine] - difference) + self.time_until_available_machine[machine] = max( + 0, self.time_until_available_machine[machine] - difference + ) if self.time_until_available_machine[machine] == 0: for job in range(self.jobs): - if self.needed_machine_jobs[job] == machine and not self.legal_actions[job] and not \ - self.illegal_actions[machine][job]: + if ( + self.needed_machine_jobs[job] == machine + and not self.legal_actions[job] + and not self.illegal_actions[machine][job] + ): self.legal_actions[job] = True self.nb_legal_actions += 1 if not self.machine_legal[machine]: @@ -381,26 +438,33 @@ def _is_done(self): return True return False - def render(self, mode='human'): + def render(self, mode="human"): df = [] for job in range(self.jobs): i = 0 while i < self.machines and self.solution[job][i] != -1: dict_op = dict() - dict_op["Task"] = 'Job {}'.format(job) + dict_op["Task"] = "Job {}".format(job) start_sec = self.start_timestamp + self.solution[job][i] finish_sec = start_sec + self.instance_matrix[job][i][1] dict_op["Start"] = datetime.datetime.fromtimestamp(start_sec) dict_op["Finish"] = datetime.datetime.fromtimestamp(finish_sec) dict_op["Resource"] = "Machine {}".format( - self.instance_matrix[job][i][0]) + self.instance_matrix[job][i][0] + ) df.append(dict_op) i += 1 fig = None if len(df) > 0: df = pd.DataFrame(df) - fig = ff.create_gantt(df, index_col='Resource', colors=self.colors, show_colorbar=True, - group_tasks=True) - # otherwise tasks are listed from the bottom up - fig.update_yaxes(autorange="reversed") + fig = ff.create_gantt( + df, + index_col="Resource", + colors=self.colors, + show_colorbar=True, + group_tasks=True, + ) + fig.update_yaxes( + autorange="reversed" + ) # otherwise tasks are listed from the bottom up return fig diff --git a/JSSEnv/envs/registry.py b/JSSEnv/envs/registry.py index 9193cb5..3dc410a 100644 --- a/JSSEnv/envs/registry.py +++ b/JSSEnv/envs/registry.py @@ -2,11 +2,14 @@ registry = EnvRegistry() + def register(id, **kwargs): return registry.register(id, **kwargs) + def make(id, **kwargs): return registry.make(id, **kwargs) + def spec(id): - return registry.spec(id) \ No newline at end of file + return registry.spec(id) diff --git a/JSSEnv/utils.py b/JSSEnv/utils.py index 13a18b8..be068d9 100644 --- a/JSSEnv/utils.py +++ b/JSSEnv/utils.py @@ -1,29 +1,29 @@ import numpy as np + def assign_env_config(self, kwargs): for key, value in kwargs.items(): setattr(self, key, value) - if hasattr(self, 'env_config'): - # print(self.env_config) + if hasattr(self, "env_config"): for key, value in self.env_config.items(): # Check types based on default settings if hasattr(self, key): - if type(getattr(self,key)) == np.ndarray: + if type(getattr(self, key)) == np.ndarray: setattr(self, key, value) else: - setattr(self, key, - type(getattr(self, key))(value)) + setattr(self, key, type(getattr(self, key))(value)) else: setattr(self, key, value) - + + # Get Ray to work with gym registry def create_env(config, *args, **kwargs): - if type(config) == dict: - env_name = config['env'] - else: - env_name = config - if env_name == 'JSSEnv-v1': - from JSSEnv.envs.JssEnv import JssEnv as env - else: - raise NotImplementedError('Environment {} not recognized.'.format(env_name)) - return env + if type(config) == dict: + env_name = config["env"] + else: + env_name = config + if env_name == "jss-v1": + from JSSEnv.envs.jss_env import JssEnv as env + else: + raise NotImplementedError("Environment {} not recognized.".format(env_name)) + return env diff --git a/JSSEnv/version.py b/JSSEnv/version.py deleted file mode 100644 index 026f764..0000000 --- a/JSSEnv/version.py +++ /dev/null @@ -1,3 +0,0 @@ -VERSION='1.0.2' - -ENV_LIST = ['JSSEnv-v1'] \ No newline at end of file diff --git a/README.md b/README.md index 775c34d..caa2b76 100644 --- a/README.md +++ b/README.md @@ -24,18 +24,49 @@ Getting Started This repository is available as a pip package: ```shell -pip install JSSEnv==1.0.0 +pip install JSSEnv ``` Once installed, the environment will be available in your OpenAi's gym environment and can be used to train a reinforcement learning agent: ```python import gym -env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': 'INSTANCE_PATH'}) +import JSSEnv # an ongoing issue with OpenAi's gym causes it to not import automatically external modules, see: https://github.com/openai/gym/issues/2809 +# for older version of gym, you have to use +# env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': 'INSTANCE_PATH'}) +env = gym.make('jss-v1', env_config={'instance_path': 'INSTANCE_PATH'}) ``` ### Important: Your instance must follow [Taillard's specification](http://jobshop.jjvh.nl/explanation.php#taillard_def). + +How To Use +------------ + +The observation provided by the environment contains both a boolean array indicating if the action is legal or not and the "real" observation + +```python +self.observation_space = gym.spaces.Dict({ + "action_mask": gym.spaces.Box(0, 1, shape=(self.jobs + 1,)), + "real_obs": gym.spaces.Box(low=0.0, high=1.0, shape=(self.jobs, 7), dtype=np.float), + }) +``` + +A random agent would have to sample legal action from this `action_mask` array, otherwise, you might take illegal actions. +In theory, it is not possible to take the same action over and over again as the job will have one of his operations currently on a machine and might not be free for schedule. + +For research purposes, I've made a random loop using RLLib: https://github.com/prosysscience/RL-Job-Shop-Scheduling/blob/0bbe0c0f2b8a742b75cbe67c5f6a825b8cfdf5eb/JSS/randomLoop/random_loop.py + +If you don't want to use RLLib, you can write a simple random loop using `numpy.random.choice` function: + +```python +import numpy as np +np.random.choice(len(legal_action), 1, p=(legal_action / legal_action.sum()))[0] +``` + +Where `legal_action` is the array of legal action (i.e., `action_mask`). +This line of code will randomly sample one legal action from the `action_mask`. + Project Organization ------------ diff --git a/rllib-validate-env.py b/rllib-validate-env.py deleted file mode 100644 index 4cae2cd..0000000 --- a/rllib-validate-env.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: utf-8 -*- -""" - -This python script outlines the _validate_env logic for Rllib (v.1.9.1) and -can be used for debugging issues in environment configuration. - -@author: Philipp Willms -""" -import gym -import numpy as np -import JSSEnv # import of the installed pip package needed - -# test the environment -instance_path = 'JSSEnv/envs/instances/dmu20' -env = gym.make('JSSEnv-v1', env_config={'instance_path': instance_path}) - - -if isinstance(env, gym.Env) : - # Make sure the gym.Env has the two space attributes properly set. - assert hasattr(env, "observation_space") and hasattr( - env, "action_space") - # Get a dummy observation by resetting the env. - dummy_obs = env.reset() - # Convert lists to np.ndarrays. - if type(dummy_obs) is list and isinstance(env.observation_space, - gym.spaces.Box): - dummy_obs = np.array(dummy_obs) - print("Dummy obs after np array conversion: ") - print(dummy_obs) - # Ignore float32/float64 diffs. - if isinstance(env.observation_space, gym.spaces.Box) and \ - env.observation_space.dtype != dummy_obs.dtype: - dummy_obs = dummy_obs.astype(env.observation_space.dtype) - print("Dummy obs after ignore float diffs ") - print(dummy_obs) - # Check, if observation is ok (part of the observation space). If not, - # error. - - determined_obs_space = env.observation_space - - # original code from box.py - # def contains(self, x): - # if not isinstance(x, np.ndarray): - # logger.warn("Casting input x to numpy array.") - # x = np.asarray(x, dtype=self.dtype) - - # return ( - # np.can_cast(x.dtype, self.dtype) - # and x.shape == self.shape - # and np.all(x >= self.low) - # and np.all(x <= self.high) - # ) - - # action_mask check - x = determined_obs_space["action_mask"] - y = dummy_obs["action_mask"] - print(x) - print(y) - print(np.can_cast(x.dtype, y.dtype)) - print(x.shape == y.shape) - print(np.all(y >= x.low)) - print(np.all(y <= x.high)) - - # state check - x = determined_obs_space["real_obs"] - y = dummy_obs["real_obs"] - print(x) - print(y) - print(np.can_cast(x.dtype, y.dtype)) - print(x.shape == y.shape) - print(np.all(y >= x.low)) - print(np.all(y <= x.high)) - -# original code from dict.py -# def contains(self, x): -# if not isinstance(x, dict) or len(x) != len(self.spaces): -# return False -# for k, space in self.spaces.items(): -# if k not in x: -# return False -# if not space.contains(x[k]): -# return False -# return True - - x = determined_obs_space - y = dummy_obs - print("Dict check") - print(isinstance(y, dict)) - print("Length observation space: " + str(len(x.spaces))) - print("Length dummy observation: " + str(len(y))) - print(len(y) == len(x.spaces)) - for k, space in x.spaces.items(): - print(k) - print(space) - if k not in y: - #return False - print("Element not found in dummy observation") - print(k) - if not space.contains(y[k]): - print("Contains check failed") - print(y[k]) - # return False - - # If there is a hard nut to crack with specific observation state, use the following - x = determined_obs_space["real_obs"] - mal_state = y[k] - print(np.can_cast(x.dtype, mal_state.dtype)) - print(x.shape == mal_state.shape) - print(np.all(mal_state >= x.low)) - print(np.all(mal_state <= x.high)) - print(isinstance(y[k], np.ndarray)) - print(x.contains(mal_state)) - - # Copied from rollout_worker.py - if not env.observation_space.contains(dummy_obs): - print( - f"Env's `observation_space` {env.observation_space} does not " - f"contain returned observation after a reset ({dummy_obs})!") - else: - print("All checks passed") \ No newline at end of file diff --git a/setup.py b/setup.py index 4a573b1..dc9a008 100644 --- a/setup.py +++ b/setup.py @@ -1,25 +1,31 @@ from setuptools import setup, find_packages -import sys -import os -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'JSSEnv')) -from JSSEnv.version import VERSION - -setup(name='JSSEnv', - version=VERSION, - author="Pierre Tassel", - author_email="pierre.tassel@aau.at", - description="An optimized OpenAi gym's environment to simulate the Job-Shop Scheduling problem.", - url="https://github.com/prosysscience/JSSEnv", - packages=find_packages(), - classifiers=[ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", - ], - python_requires='>=3.6', - install_requires=['gym', 'pandas', 'numpy', 'plotly', 'imageio', 'psutil', 'requests', 'kaleido', 'pytest', - 'codecov'], - include_package_data=True, - zip_safe=False - ) +setup( + name="JSSEnv", + version="1.0.2", + author="Pierre Tassel", + author_email="pierre.tassel@aau.at", + description="An optimized OpenAi gym's environment to simulate the Job-Shop Scheduling problem.", + url="https://github.com/prosysscience/JSSEnv", + packages=find_packages(), + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + ], + python_requires=">=3.6", + install_requires=[ + "gym", + "pandas", + "numpy", + "plotly", + "imageio", + "psutil", + "requests", + "kaleido", + "pytest", + "codecov", + ], + include_package_data=True, + zip_safe=False, +) diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..830e34e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1 @@ +import JSSEnv diff --git a/tests/test_rendering.py b/tests/test_rendering.py index 1475037..0bb3d58 100644 --- a/tests/test_rendering.py +++ b/tests/test_rendering.py @@ -1,13 +1,18 @@ import gym import unittest import imageio +from pathlib import Path class TestRendering(unittest.TestCase): - def test_optimum_ta01_gif(self): # http://optimizizer.com/solution.php?name=ta01&UB=1231&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta01'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta01" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine @@ -26,7 +31,7 @@ def test_optimum_ta01_gif(self): [7, 9, 8, 5, 6, 0, 2, 3, 1, 13, 14, 12, 4, 10, 11], [6, 0, 7, 11, 5, 14, 10, 2, 4, 13, 8, 9, 3, 12, 1], [13, 10, 7, 9, 5, 3, 11, 1, 12, 14, 2, 4, 0, 6, 8], - [13, 11, 6, 8, 7, 4, 1, 5, 3, 10, 0, 14, 9, 2, 12] + [13, 11, 6, 8, 7, 4, 1, 5, 3, 10, 0, 14, 9, 2, 12], ] done = False job_nb = len(solution_sequence[0]) @@ -42,10 +47,18 @@ def test_optimum_ta01_gif(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -54,9 +67,14 @@ def test_optimum_ta01_gif(self): if no_op and not done: self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step - env._increase_time_step() - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + env.increase_time_step() + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 1231) imageio.mimsave("ta01.gif", images) env.reset() diff --git a/tests/test_solutions.py b/tests/test_solutions.py index d17414b..6b28d7d 100644 --- a/tests/test_solutions.py +++ b/tests/test_solutions.py @@ -1,12 +1,17 @@ import gym import unittest +from pathlib import Path class TestSolution(unittest.TestCase): - def test_optimum_ta01(self): # http://optimizizer.com/solution.php?name=ta01&UB=1231&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta01'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta01" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine @@ -25,7 +30,7 @@ def test_optimum_ta01(self): [7, 9, 8, 5, 6, 0, 2, 3, 1, 13, 14, 12, 4, 10, 11], [6, 0, 7, 11, 5, 14, 10, 2, 4, 13, 8, 9, 3, 12, 1], [13, 10, 7, 9, 5, 3, 11, 1, 12, 14, 2, 4, 0, 6, 8], - [13, 11, 6, 8, 7, 4, 1, 5, 3, 10, 0, 14, 9, 2, 12] + [13, 11, 6, 8, 7, 4, 1, 5, 3, 10, 0, 14, 9, 2, 12], ] done = False job_nb = len(solution_sequence[0]) @@ -40,70 +45,689 @@ def test_optimum_ta01(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 if no_op and not done: self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step - env._increase_time_step() - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + env.increase_time_step() + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 1231) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta41(self): # http://optimizizer.com/solution.php?name=ta41&UB=2006&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta41'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta41" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [9, 21, 27, 23, 5, 8, 10, 11, 3, 16, 1, 19, 13, 24, 17, 18, 2, 15, 25, 22, 28, 6, 29, 20, 0, 26, 14, 7, 4, - 12], - [5, 10, 22, 25, 18, 14, 26, 1, 17, 12, 9, 29, 15, 13, 16, 4, 21, 11, 8, 2, 24, 6, 20, 7, 0, 23, 3, 27, 19, - 28], - [6, 9, 1, 20, 4, 26, 12, 5, 11, 2, 8, 21, 16, 29, 17, 13, 15, 7, 24, 0, 25, 22, 27, 23, 19, 3, 18, 28, 14, - 10], - [6, 8, 9, 17, 13, 21, 15, 1, 29, 18, 11, 12, 0, 3, 7, 4, 2, 20, 28, 23, 27, 5, 14, 19, 25, 26, 24, 16, 10, - 22], - [14, 15, 22, 10, 1, 13, 19, 12, 7, 5, 4, 9, 2, 26, 16, 3, 28, 0, 29, 8, 21, 11, 24, 20, 23, 18, 25, 27, 6, - 17], - [11, 22, 12, 23, 0, 2, 1, 17, 5, 15, 16, 26, 14, 18, 4, 21, 19, 9, 25, 29, 3, 24, 13, 20, 27, 6, 8, 7, 28, - 10], - [11, 4, 24, 17, 22, 20, 21, 1, 19, 29, 12, 9, 5, 14, 0, 18, 8, 3, 15, 2, 28, 25, 7, 10, 13, 23, 16, 27, 26, - 6], - [21, 20, 19, 8, 17, 1, 26, 11, 22, 5, 16, 3, 18, 25, 4, 24, 2, 0, 29, 7, 12, 14, 28, 9, 23, 27, 6, 13, 10, - 15], - [4, 2, 19, 14, 3, 9, 27, 1, 13, 15, 22, 5, 11, 21, 16, 6, 7, 26, 0, 28, 17, 24, 10, 20, 25, 29, 12, 18, 8, - 23], - [18, 15, 17, 11, 9, 22, 1, 13, 26, 14, 28, 29, 27, 4, 21, 19, 0, 25, 6, 24, 23, 20, 7, 10, 12, 3, 16, 5, 2, - 8], - [22, 8, 5, 13, 16, 11, 25, 26, 7, 6, 14, 21, 18, 10, 9, 12, 24, 0, 1, 19, 23, 4, 15, 27, 3, 2, 28, 20, 17, - 29], - [24, 18, 12, 28, 14, 26, 22, 4, 3, 23, 11, 15, 16, 8, 29, 13, 7, 2, 19, 10, 21, 27, 5, 6, 0, 17, 20, 25, 1, - 9], - [7, 21, 1, 22, 25, 9, 5, 16, 4, 11, 27, 20, 6, 12, 13, 0, 15, 17, 19, 14, 29, 2, 23, 24, 28, 8, 10, 26, 3, - 18], - [1, 5, 12, 17, 3, 19, 25, 4, 16, 18, 0, 22, 9, 11, 6, 26, 21, 14, 7, 10, 27, 28, 8, 23, 15, 24, 29, 13, 2, - 20], - [23, 8, 14, 26, 24, 12, 1, 16, 17, 2, 15, 3, 28, 11, 20, 0, 5, 22, 7, 10, 6, 19, 25, 29, 21, 13, 18, 9, 4, - 27], - [1, 14, 12, 15, 4, 26, 17, 6, 5, 0, 9, 10, 27, 13, 21, 23, 16, 28, 7, 19, 29, 2, 3, 24, 18, 11, 8, 20, 22, - 25], - [29, 21, 6, 20, 4, 24, 17, 26, 9, 15, 5, 18, 14, 16, 19, 27, 8, 11, 28, 10, 2, 25, 0, 13, 7, 12, 1, 23, 22, - 3], - [20, 19, 16, 18, 17, 8, 6, 15, 13, 7, 5, 2, 14, 24, 27, 4, 22, 11, 9, 21, 25, 23, 1, 0, 10, 3, 12, 28, 26, - 29], - [22, 28, 15, 25, 24, 27, 2, 16, 5, 17, 29, 21, 14, 19, 3, 13, 12, 6, 20, 8, 1, 4, 7, 23, 26, 18, 11, 0, 10, - 9], - [17, 12, 15, 26, 16, 8, 21, 5, 1, 13, 4, 0, 9, 11, 27, 6, 7, 23, 14, 3, 10, 24, 19, 22, 20, 2, 28, 29, 18, - 25]] + [ + 9, + 21, + 27, + 23, + 5, + 8, + 10, + 11, + 3, + 16, + 1, + 19, + 13, + 24, + 17, + 18, + 2, + 15, + 25, + 22, + 28, + 6, + 29, + 20, + 0, + 26, + 14, + 7, + 4, + 12, + ], + [ + 5, + 10, + 22, + 25, + 18, + 14, + 26, + 1, + 17, + 12, + 9, + 29, + 15, + 13, + 16, + 4, + 21, + 11, + 8, + 2, + 24, + 6, + 20, + 7, + 0, + 23, + 3, + 27, + 19, + 28, + ], + [ + 6, + 9, + 1, + 20, + 4, + 26, + 12, + 5, + 11, + 2, + 8, + 21, + 16, + 29, + 17, + 13, + 15, + 7, + 24, + 0, + 25, + 22, + 27, + 23, + 19, + 3, + 18, + 28, + 14, + 10, + ], + [ + 6, + 8, + 9, + 17, + 13, + 21, + 15, + 1, + 29, + 18, + 11, + 12, + 0, + 3, + 7, + 4, + 2, + 20, + 28, + 23, + 27, + 5, + 14, + 19, + 25, + 26, + 24, + 16, + 10, + 22, + ], + [ + 14, + 15, + 22, + 10, + 1, + 13, + 19, + 12, + 7, + 5, + 4, + 9, + 2, + 26, + 16, + 3, + 28, + 0, + 29, + 8, + 21, + 11, + 24, + 20, + 23, + 18, + 25, + 27, + 6, + 17, + ], + [ + 11, + 22, + 12, + 23, + 0, + 2, + 1, + 17, + 5, + 15, + 16, + 26, + 14, + 18, + 4, + 21, + 19, + 9, + 25, + 29, + 3, + 24, + 13, + 20, + 27, + 6, + 8, + 7, + 28, + 10, + ], + [ + 11, + 4, + 24, + 17, + 22, + 20, + 21, + 1, + 19, + 29, + 12, + 9, + 5, + 14, + 0, + 18, + 8, + 3, + 15, + 2, + 28, + 25, + 7, + 10, + 13, + 23, + 16, + 27, + 26, + 6, + ], + [ + 21, + 20, + 19, + 8, + 17, + 1, + 26, + 11, + 22, + 5, + 16, + 3, + 18, + 25, + 4, + 24, + 2, + 0, + 29, + 7, + 12, + 14, + 28, + 9, + 23, + 27, + 6, + 13, + 10, + 15, + ], + [ + 4, + 2, + 19, + 14, + 3, + 9, + 27, + 1, + 13, + 15, + 22, + 5, + 11, + 21, + 16, + 6, + 7, + 26, + 0, + 28, + 17, + 24, + 10, + 20, + 25, + 29, + 12, + 18, + 8, + 23, + ], + [ + 18, + 15, + 17, + 11, + 9, + 22, + 1, + 13, + 26, + 14, + 28, + 29, + 27, + 4, + 21, + 19, + 0, + 25, + 6, + 24, + 23, + 20, + 7, + 10, + 12, + 3, + 16, + 5, + 2, + 8, + ], + [ + 22, + 8, + 5, + 13, + 16, + 11, + 25, + 26, + 7, + 6, + 14, + 21, + 18, + 10, + 9, + 12, + 24, + 0, + 1, + 19, + 23, + 4, + 15, + 27, + 3, + 2, + 28, + 20, + 17, + 29, + ], + [ + 24, + 18, + 12, + 28, + 14, + 26, + 22, + 4, + 3, + 23, + 11, + 15, + 16, + 8, + 29, + 13, + 7, + 2, + 19, + 10, + 21, + 27, + 5, + 6, + 0, + 17, + 20, + 25, + 1, + 9, + ], + [ + 7, + 21, + 1, + 22, + 25, + 9, + 5, + 16, + 4, + 11, + 27, + 20, + 6, + 12, + 13, + 0, + 15, + 17, + 19, + 14, + 29, + 2, + 23, + 24, + 28, + 8, + 10, + 26, + 3, + 18, + ], + [ + 1, + 5, + 12, + 17, + 3, + 19, + 25, + 4, + 16, + 18, + 0, + 22, + 9, + 11, + 6, + 26, + 21, + 14, + 7, + 10, + 27, + 28, + 8, + 23, + 15, + 24, + 29, + 13, + 2, + 20, + ], + [ + 23, + 8, + 14, + 26, + 24, + 12, + 1, + 16, + 17, + 2, + 15, + 3, + 28, + 11, + 20, + 0, + 5, + 22, + 7, + 10, + 6, + 19, + 25, + 29, + 21, + 13, + 18, + 9, + 4, + 27, + ], + [ + 1, + 14, + 12, + 15, + 4, + 26, + 17, + 6, + 5, + 0, + 9, + 10, + 27, + 13, + 21, + 23, + 16, + 28, + 7, + 19, + 29, + 2, + 3, + 24, + 18, + 11, + 8, + 20, + 22, + 25, + ], + [ + 29, + 21, + 6, + 20, + 4, + 24, + 17, + 26, + 9, + 15, + 5, + 18, + 14, + 16, + 19, + 27, + 8, + 11, + 28, + 10, + 2, + 25, + 0, + 13, + 7, + 12, + 1, + 23, + 22, + 3, + ], + [ + 20, + 19, + 16, + 18, + 17, + 8, + 6, + 15, + 13, + 7, + 5, + 2, + 14, + 24, + 27, + 4, + 22, + 11, + 9, + 21, + 25, + 23, + 1, + 0, + 10, + 3, + 12, + 28, + 26, + 29, + ], + [ + 22, + 28, + 15, + 25, + 24, + 27, + 2, + 16, + 5, + 17, + 29, + 21, + 14, + 19, + 3, + 13, + 12, + 6, + 20, + 8, + 1, + 4, + 7, + 23, + 26, + 18, + 11, + 0, + 10, + 9, + ], + [ + 17, + 12, + 15, + 26, + 16, + 8, + 21, + 5, + 1, + 13, + 4, + 0, + 9, + 11, + 27, + 6, + 7, + 23, + 14, + 3, + 10, + 24, + 19, + 22, + 20, + 2, + 28, + 29, + 18, + 25, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -117,10 +741,18 @@ def test_optimum_ta41(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -128,59 +760,670 @@ def test_optimum_ta41(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 2006) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta42(self): # http://optimizizer.com/solution.php?name=ta42&UB=1939&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta42'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta42" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [12, 8, 26, 24, 14, 21, 4, 15, 18, 11, 7, 0, 10, 13, 20, 19, 28, 29, 2, 1, 22, 16, 17, 23, 9, 27, 5, 25, 3, - 6], - [14, 9, 1, 23, 4, 20, 6, 21, 26, 7, 28, 3, 2, 16, 27, 18, 29, 0, 11, 24, 5, 13, 19, 17, 12, 25, 15, 8, 22, - 10], - [12, 17, 1, 15, 6, 4, 14, 13, 8, 23, 24, 25, 20, 3, 5, 28, 21, 11, 26, 27, 0, 7, 10, 16, 9, 2, 18, 19, 22, - 29], - [24, 6, 1, 4, 9, 11, 0, 15, 28, 16, 25, 14, 29, 10, 27, 5, 13, 20, 26, 22, 8, 17, 18, 3, 21, 19, 23, 2, 7, - 12], - [6, 0, 28, 23, 13, 24, 16, 22, 25, 15, 8, 5, 18, 19, 11, 21, 10, 1, 12, 3, 9, 20, 7, 26, 14, 17, 2, 27, 29, - 4], - [11, 12, 0, 28, 29, 24, 20, 10, 8, 25, 16, 26, 23, 5, 1, 13, 27, 6, 9, 2, 22, 21, 7, 14, 15, 18, 17, 3, 4, - 19], - [1, 11, 22, 17, 9, 25, 14, 23, 16, 0, 24, 28, 6, 29, 5, 2, 18, 4, 7, 13, 10, 20, 21, 3, 26, 15, 19, 12, 27, - 8], - [22, 3, 4, 16, 8, 6, 1, 25, 20, 12, 18, 10, 7, 14, 17, 28, 19, 29, 21, 26, 24, 0, 15, 13, 9, 5, 23, 11, 27, - 2], - [20, 16, 28, 29, 13, 25, 0, 2, 6, 5, 19, 10, 24, 21, 27, 18, 26, 22, 3, 14, 9, 17, 15, 12, 11, 23, 7, 8, 4, - 1], - [23, 9, 11, 8, 15, 12, 14, 24, 16, 28, 5, 25, 29, 6, 20, 18, 19, 3, 2, 21, 27, 10, 26, 1, 22, 13, 4, 0, 7, - 17], - [13, 4, 0, 26, 24, 7, 10, 1, 21, 9, 14, 6, 18, 2, 19, 28, 16, 12, 22, 11, 23, 25, 20, 29, 17, 27, 8, 15, 5, - 3], - [9, 28, 29, 1, 23, 20, 24, 18, 16, 26, 10, 8, 6, 0, 19, 12, 25, 4, 5, 13, 7, 14, 15, 21, 27, 11, 3, 17, 2, - 22], - [24, 13, 0, 9, 11, 1, 16, 23, 15, 29, 26, 28, 6, 4, 5, 20, 19, 8, 2, 27, 21, 14, 7, 22, 10, 18, 17, 3, 12, - 25], - [17, 6, 25, 1, 21, 28, 13, 16, 9, 26, 10, 27, 15, 29, 2, 24, 0, 14, 8, 4, 20, 18, 19, 5, 3, 23, 22, 11, 7, - 12], - [29, 24, 15, 10, 17, 1, 11, 23, 21, 28, 9, 22, 2, 14, 6, 8, 27, 18, 16, 0, 3, 20, 13, 7, 5, 12, 25, 26, 19, - 4], - [6, 18, 2, 14, 21, 11, 24, 0, 29, 22, 13, 27, 20, 23, 1, 16, 7, 15, 3, 12, 9, 28, 26, 10, 4, 5, 8, 19, 17, - 25], - [29, 14, 9, 21, 27, 15, 23, 20, 6, 2, 1, 13, 10, 4, 3, 7, 0, 19, 24, 17, 25, 22, 11, 5, 16, 28, 26, 18, 12, - 8], - [6, 16, 8, 2, 11, 4, 23, 14, 13, 29, 28, 19, 20, 22, 7, 1, 21, 3, 24, 15, 0, 27, 5, 9, 12, 26, 10, 18, 25, - 17], - [11, 10, 12, 16, 17, 28, 4, 1, 14, 7, 8, 29, 25, 21, 5, 24, 6, 18, 0, 19, 9, 15, 13, 3, 2, 23, 27, 22, 20, - 26], - [10, 6, 14, 16, 18, 29, 12, 20, 1, 0, 27, 13, 25, 11, 28, 22, 21, 15, 26, 5, 8, 9, 19, 17, 3, 7, 4, 2, 24, - 23]] + [ + 12, + 8, + 26, + 24, + 14, + 21, + 4, + 15, + 18, + 11, + 7, + 0, + 10, + 13, + 20, + 19, + 28, + 29, + 2, + 1, + 22, + 16, + 17, + 23, + 9, + 27, + 5, + 25, + 3, + 6, + ], + [ + 14, + 9, + 1, + 23, + 4, + 20, + 6, + 21, + 26, + 7, + 28, + 3, + 2, + 16, + 27, + 18, + 29, + 0, + 11, + 24, + 5, + 13, + 19, + 17, + 12, + 25, + 15, + 8, + 22, + 10, + ], + [ + 12, + 17, + 1, + 15, + 6, + 4, + 14, + 13, + 8, + 23, + 24, + 25, + 20, + 3, + 5, + 28, + 21, + 11, + 26, + 27, + 0, + 7, + 10, + 16, + 9, + 2, + 18, + 19, + 22, + 29, + ], + [ + 24, + 6, + 1, + 4, + 9, + 11, + 0, + 15, + 28, + 16, + 25, + 14, + 29, + 10, + 27, + 5, + 13, + 20, + 26, + 22, + 8, + 17, + 18, + 3, + 21, + 19, + 23, + 2, + 7, + 12, + ], + [ + 6, + 0, + 28, + 23, + 13, + 24, + 16, + 22, + 25, + 15, + 8, + 5, + 18, + 19, + 11, + 21, + 10, + 1, + 12, + 3, + 9, + 20, + 7, + 26, + 14, + 17, + 2, + 27, + 29, + 4, + ], + [ + 11, + 12, + 0, + 28, + 29, + 24, + 20, + 10, + 8, + 25, + 16, + 26, + 23, + 5, + 1, + 13, + 27, + 6, + 9, + 2, + 22, + 21, + 7, + 14, + 15, + 18, + 17, + 3, + 4, + 19, + ], + [ + 1, + 11, + 22, + 17, + 9, + 25, + 14, + 23, + 16, + 0, + 24, + 28, + 6, + 29, + 5, + 2, + 18, + 4, + 7, + 13, + 10, + 20, + 21, + 3, + 26, + 15, + 19, + 12, + 27, + 8, + ], + [ + 22, + 3, + 4, + 16, + 8, + 6, + 1, + 25, + 20, + 12, + 18, + 10, + 7, + 14, + 17, + 28, + 19, + 29, + 21, + 26, + 24, + 0, + 15, + 13, + 9, + 5, + 23, + 11, + 27, + 2, + ], + [ + 20, + 16, + 28, + 29, + 13, + 25, + 0, + 2, + 6, + 5, + 19, + 10, + 24, + 21, + 27, + 18, + 26, + 22, + 3, + 14, + 9, + 17, + 15, + 12, + 11, + 23, + 7, + 8, + 4, + 1, + ], + [ + 23, + 9, + 11, + 8, + 15, + 12, + 14, + 24, + 16, + 28, + 5, + 25, + 29, + 6, + 20, + 18, + 19, + 3, + 2, + 21, + 27, + 10, + 26, + 1, + 22, + 13, + 4, + 0, + 7, + 17, + ], + [ + 13, + 4, + 0, + 26, + 24, + 7, + 10, + 1, + 21, + 9, + 14, + 6, + 18, + 2, + 19, + 28, + 16, + 12, + 22, + 11, + 23, + 25, + 20, + 29, + 17, + 27, + 8, + 15, + 5, + 3, + ], + [ + 9, + 28, + 29, + 1, + 23, + 20, + 24, + 18, + 16, + 26, + 10, + 8, + 6, + 0, + 19, + 12, + 25, + 4, + 5, + 13, + 7, + 14, + 15, + 21, + 27, + 11, + 3, + 17, + 2, + 22, + ], + [ + 24, + 13, + 0, + 9, + 11, + 1, + 16, + 23, + 15, + 29, + 26, + 28, + 6, + 4, + 5, + 20, + 19, + 8, + 2, + 27, + 21, + 14, + 7, + 22, + 10, + 18, + 17, + 3, + 12, + 25, + ], + [ + 17, + 6, + 25, + 1, + 21, + 28, + 13, + 16, + 9, + 26, + 10, + 27, + 15, + 29, + 2, + 24, + 0, + 14, + 8, + 4, + 20, + 18, + 19, + 5, + 3, + 23, + 22, + 11, + 7, + 12, + ], + [ + 29, + 24, + 15, + 10, + 17, + 1, + 11, + 23, + 21, + 28, + 9, + 22, + 2, + 14, + 6, + 8, + 27, + 18, + 16, + 0, + 3, + 20, + 13, + 7, + 5, + 12, + 25, + 26, + 19, + 4, + ], + [ + 6, + 18, + 2, + 14, + 21, + 11, + 24, + 0, + 29, + 22, + 13, + 27, + 20, + 23, + 1, + 16, + 7, + 15, + 3, + 12, + 9, + 28, + 26, + 10, + 4, + 5, + 8, + 19, + 17, + 25, + ], + [ + 29, + 14, + 9, + 21, + 27, + 15, + 23, + 20, + 6, + 2, + 1, + 13, + 10, + 4, + 3, + 7, + 0, + 19, + 24, + 17, + 25, + 22, + 11, + 5, + 16, + 28, + 26, + 18, + 12, + 8, + ], + [ + 6, + 16, + 8, + 2, + 11, + 4, + 23, + 14, + 13, + 29, + 28, + 19, + 20, + 22, + 7, + 1, + 21, + 3, + 24, + 15, + 0, + 27, + 5, + 9, + 12, + 26, + 10, + 18, + 25, + 17, + ], + [ + 11, + 10, + 12, + 16, + 17, + 28, + 4, + 1, + 14, + 7, + 8, + 29, + 25, + 21, + 5, + 24, + 6, + 18, + 0, + 19, + 9, + 15, + 13, + 3, + 2, + 23, + 27, + 22, + 20, + 26, + ], + [ + 10, + 6, + 14, + 16, + 18, + 29, + 12, + 20, + 1, + 0, + 27, + 13, + 25, + 11, + 28, + 22, + 21, + 15, + 26, + 5, + 8, + 9, + 19, + 17, + 3, + 7, + 4, + 2, + 24, + 23, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -194,10 +1437,18 @@ def test_optimum_ta42(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -205,59 +1456,670 @@ def test_optimum_ta42(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 1939) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta43(self): # http://optimizizer.com/solution.php?name=ta43&UB=1846&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta43'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta43" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [12, 26, 21, 10, 17, 9, 15, 8, 2, 28, 18, 27, 23, 7, 24, 6, 20, 5, 25, 29, 1, 3, 14, 16, 11, 4, 13, 0, 22, - 19], - [9, 11, 3, 5, 10, 2, 23, 6, 13, 1, 19, 28, 24, 18, 26, 8, 14, 15, 0, 21, 17, 7, 16, 22, 27, 4, 12, 20, 25, - 29], - [6, 23, 17, 9, 12, 3, 11, 4, 7, 16, 28, 15, 10, 26, 5, 18, 22, 14, 8, 25, 13, 1, 29, 2, 20, 19, 0, 27, 21, - 24], - [17, 28, 0, 8, 19, 3, 13, 10, 15, 14, 27, 25, 26, 23, 11, 12, 21, 29, 16, 9, 1, 6, 4, 20, 18, 7, 2, 24, 5, - 22], - [26, 25, 6, 3, 11, 17, 12, 22, 9, 8, 19, 24, 4, 23, 1, 14, 18, 2, 29, 15, 5, 20, 0, 7, 16, 10, 27, 21, 28, - 13], - [4, 26, 22, 5, 13, 28, 6, 0, 9, 21, 8, 17, 7, 10, 25, 2, 27, 14, 3, 15, 20, 29, 16, 23, 11, 24, 1, 19, 12, - 18], - [25, 6, 19, 24, 16, 22, 9, 15, 17, 5, 2, 8, 27, 18, 7, 26, 28, 4, 1, 12, 0, 29, 14, 3, 20, 21, 10, 23, 11, - 13], - [29, 6, 25, 9, 27, 1, 24, 7, 13, 19, 26, 11, 4, 20, 12, 10, 16, 3, 22, 0, 21, 15, 23, 8, 2, 14, 5, 18, 28, - 17], - [25, 7, 21, 26, 1, 20, 15, 8, 28, 27, 4, 0, 22, 19, 23, 10, 16, 17, 9, 3, 2, 14, 6, 12, 5, 18, 24, 13, 11, - 29], - [5, 10, 12, 15, 28, 26, 21, 23, 17, 27, 16, 19, 8, 11, 1, 4, 6, 2, 20, 0, 9, 22, 29, 3, 13, 7, 14, 25, 18, - 24], - [4, 12, 0, 9, 25, 26, 7, 22, 17, 6, 15, 3, 13, 29, 23, 24, 14, 21, 27, 5, 8, 18, 19, 11, 10, 1, 2, 20, 16, - 28], - [28, 3, 13, 11, 2, 15, 5, 26, 24, 17, 23, 27, 4, 12, 29, 20, 18, 14, 16, 25, 7, 1, 9, 6, 10, 19, 0, 22, 8, - 21], - [16, 6, 28, 1, 26, 2, 9, 0, 22, 13, 11, 7, 10, 12, 27, 18, 15, 8, 3, 23, 20, 17, 4, 14, 24, 25, 21, 19, 29, - 5], - [23, 7, 4, 6, 10, 19, 21, 16, 28, 26, 9, 25, 5, 15, 22, 8, 17, 3, 13, 27, 2, 11, 12, 20, 24, 14, 18, 0, 29, - 1], - [22, 6, 11, 7, 2, 0, 24, 16, 26, 15, 8, 13, 1, 27, 17, 10, 9, 5, 20, 3, 25, 23, 4, 12, 29, 14, 28, 21, 19, - 18], - [21, 3, 17, 28, 4, 6, 25, 24, 26, 8, 22, 13, 27, 9, 15, 2, 0, 1, 5, 12, 14, 23, 18, 20, 11, 19, 16, 7, 29, - 10], - [5, 29, 22, 6, 28, 7, 16, 4, 10, 24, 17, 26, 19, 11, 8, 21, 3, 9, 13, 23, 18, 2, 25, 20, 1, 0, 27, 15, 12, - 14], - [16, 22, 13, 0, 23, 9, 28, 3, 8, 1, 18, 17, 4, 6, 12, 5, 15, 24, 2, 29, 21, 11, 19, 14, 20, 25, 7, 26, 27, - 10], - [29, 2, 27, 16, 26, 19, 20, 25, 4, 22, 0, 9, 17, 23, 18, 15, 3, 6, 13, 11, 5, 8, 10, 24, 28, 7, 12, 21, 14, - 1], - [23, 9, 22, 19, 28, 4, 14, 7, 25, 27, 1, 15, 16, 17, 26, 5, 24, 10, 6, 13, 8, 2, 12, 20, 18, 29, 21, 3, 0, - 11]] + [ + 12, + 26, + 21, + 10, + 17, + 9, + 15, + 8, + 2, + 28, + 18, + 27, + 23, + 7, + 24, + 6, + 20, + 5, + 25, + 29, + 1, + 3, + 14, + 16, + 11, + 4, + 13, + 0, + 22, + 19, + ], + [ + 9, + 11, + 3, + 5, + 10, + 2, + 23, + 6, + 13, + 1, + 19, + 28, + 24, + 18, + 26, + 8, + 14, + 15, + 0, + 21, + 17, + 7, + 16, + 22, + 27, + 4, + 12, + 20, + 25, + 29, + ], + [ + 6, + 23, + 17, + 9, + 12, + 3, + 11, + 4, + 7, + 16, + 28, + 15, + 10, + 26, + 5, + 18, + 22, + 14, + 8, + 25, + 13, + 1, + 29, + 2, + 20, + 19, + 0, + 27, + 21, + 24, + ], + [ + 17, + 28, + 0, + 8, + 19, + 3, + 13, + 10, + 15, + 14, + 27, + 25, + 26, + 23, + 11, + 12, + 21, + 29, + 16, + 9, + 1, + 6, + 4, + 20, + 18, + 7, + 2, + 24, + 5, + 22, + ], + [ + 26, + 25, + 6, + 3, + 11, + 17, + 12, + 22, + 9, + 8, + 19, + 24, + 4, + 23, + 1, + 14, + 18, + 2, + 29, + 15, + 5, + 20, + 0, + 7, + 16, + 10, + 27, + 21, + 28, + 13, + ], + [ + 4, + 26, + 22, + 5, + 13, + 28, + 6, + 0, + 9, + 21, + 8, + 17, + 7, + 10, + 25, + 2, + 27, + 14, + 3, + 15, + 20, + 29, + 16, + 23, + 11, + 24, + 1, + 19, + 12, + 18, + ], + [ + 25, + 6, + 19, + 24, + 16, + 22, + 9, + 15, + 17, + 5, + 2, + 8, + 27, + 18, + 7, + 26, + 28, + 4, + 1, + 12, + 0, + 29, + 14, + 3, + 20, + 21, + 10, + 23, + 11, + 13, + ], + [ + 29, + 6, + 25, + 9, + 27, + 1, + 24, + 7, + 13, + 19, + 26, + 11, + 4, + 20, + 12, + 10, + 16, + 3, + 22, + 0, + 21, + 15, + 23, + 8, + 2, + 14, + 5, + 18, + 28, + 17, + ], + [ + 25, + 7, + 21, + 26, + 1, + 20, + 15, + 8, + 28, + 27, + 4, + 0, + 22, + 19, + 23, + 10, + 16, + 17, + 9, + 3, + 2, + 14, + 6, + 12, + 5, + 18, + 24, + 13, + 11, + 29, + ], + [ + 5, + 10, + 12, + 15, + 28, + 26, + 21, + 23, + 17, + 27, + 16, + 19, + 8, + 11, + 1, + 4, + 6, + 2, + 20, + 0, + 9, + 22, + 29, + 3, + 13, + 7, + 14, + 25, + 18, + 24, + ], + [ + 4, + 12, + 0, + 9, + 25, + 26, + 7, + 22, + 17, + 6, + 15, + 3, + 13, + 29, + 23, + 24, + 14, + 21, + 27, + 5, + 8, + 18, + 19, + 11, + 10, + 1, + 2, + 20, + 16, + 28, + ], + [ + 28, + 3, + 13, + 11, + 2, + 15, + 5, + 26, + 24, + 17, + 23, + 27, + 4, + 12, + 29, + 20, + 18, + 14, + 16, + 25, + 7, + 1, + 9, + 6, + 10, + 19, + 0, + 22, + 8, + 21, + ], + [ + 16, + 6, + 28, + 1, + 26, + 2, + 9, + 0, + 22, + 13, + 11, + 7, + 10, + 12, + 27, + 18, + 15, + 8, + 3, + 23, + 20, + 17, + 4, + 14, + 24, + 25, + 21, + 19, + 29, + 5, + ], + [ + 23, + 7, + 4, + 6, + 10, + 19, + 21, + 16, + 28, + 26, + 9, + 25, + 5, + 15, + 22, + 8, + 17, + 3, + 13, + 27, + 2, + 11, + 12, + 20, + 24, + 14, + 18, + 0, + 29, + 1, + ], + [ + 22, + 6, + 11, + 7, + 2, + 0, + 24, + 16, + 26, + 15, + 8, + 13, + 1, + 27, + 17, + 10, + 9, + 5, + 20, + 3, + 25, + 23, + 4, + 12, + 29, + 14, + 28, + 21, + 19, + 18, + ], + [ + 21, + 3, + 17, + 28, + 4, + 6, + 25, + 24, + 26, + 8, + 22, + 13, + 27, + 9, + 15, + 2, + 0, + 1, + 5, + 12, + 14, + 23, + 18, + 20, + 11, + 19, + 16, + 7, + 29, + 10, + ], + [ + 5, + 29, + 22, + 6, + 28, + 7, + 16, + 4, + 10, + 24, + 17, + 26, + 19, + 11, + 8, + 21, + 3, + 9, + 13, + 23, + 18, + 2, + 25, + 20, + 1, + 0, + 27, + 15, + 12, + 14, + ], + [ + 16, + 22, + 13, + 0, + 23, + 9, + 28, + 3, + 8, + 1, + 18, + 17, + 4, + 6, + 12, + 5, + 15, + 24, + 2, + 29, + 21, + 11, + 19, + 14, + 20, + 25, + 7, + 26, + 27, + 10, + ], + [ + 29, + 2, + 27, + 16, + 26, + 19, + 20, + 25, + 4, + 22, + 0, + 9, + 17, + 23, + 18, + 15, + 3, + 6, + 13, + 11, + 5, + 8, + 10, + 24, + 28, + 7, + 12, + 21, + 14, + 1, + ], + [ + 23, + 9, + 22, + 19, + 28, + 4, + 14, + 7, + 25, + 27, + 1, + 15, + 16, + 17, + 26, + 5, + 24, + 10, + 6, + 13, + 8, + 2, + 12, + 20, + 18, + 29, + 21, + 3, + 0, + 11, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -271,10 +2133,18 @@ def test_optimum_ta43(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -282,59 +2152,670 @@ def test_optimum_ta43(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 1846) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta44(self): # http://optimizizer.com/solution.php?name=ta44&UB=1979&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta44'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta44" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [29, 6, 0, 27, 19, 10, 4, 11, 12, 13, 18, 20, 2, 5, 26, 16, 23, 14, 21, 3, 25, 17, 1, 24, 7, 22, 28, 8, 15, - 9], - [22, 9, 3, 4, 1, 2, 17, 20, 18, 13, 26, 5, 14, 29, 8, 16, 23, 0, 28, 7, 6, 19, 24, 11, 27, 21, 12, 15, 10, - 25], - [25, 27, 4, 22, 11, 0, 19, 13, 9, 17, 8, 3, 29, 21, 12, 1, 2, 10, 20, 18, 26, 5, 23, 24, 14, 6, 28, 7, 16, - 15], - [12, 4, 15, 18, 23, 13, 21, 9, 19, 5, 0, 25, 22, 29, 1, 3, 26, 6, 14, 7, 10, 28, 24, 17, 16, 2, 27, 11, 20, - 8], - [8, 21, 18, 1, 29, 20, 0, 23, 14, 10, 25, 28, 16, 12, 13, 5, 26, 9, 4, 17, 19, 11, 24, 27, 3, 6, 7, 22, 2, - 15], - [0, 17, 13, 21, 12, 11, 9, 16, 8, 27, 29, 5, 10, 4, 18, 23, 25, 6, 26, 22, 14, 1, 7, 15, 3, 19, 28, 24, 2, - 20], - [5, 18, 27, 13, 0, 24, 29, 8, 14, 4, 19, 10, 22, 9, 26, 25, 16, 3, 15, 6, 28, 11, 1, 7, 12, 20, 23, 17, 21, - 2], - [23, 27, 1, 10, 5, 20, 9, 24, 18, 19, 8, 2, 15, 16, 12, 21, 26, 4, 13, 25, 11, 0, 14, 7, 29, 22, 6, 28, 3, - 17], - [18, 22, 21, 7, 24, 23, 9, 19, 2, 5, 1, 13, 14, 16, 12, 8, 3, 20, 6, 29, 28, 15, 26, 17, 0, 4, 27, 10, 11, - 25], - [7, 2, 24, 23, 15, 13, 8, 10, 9, 11, 21, 4, 12, 27, 0, 14, 6, 17, 25, 5, 3, 19, 29, 26, 1, 18, 20, 16, 28, - 22], - [27, 19, 7, 14, 21, 0, 6, 1, 24, 3, 18, 13, 10, 16, 5, 23, 4, 9, 29, 20, 22, 17, 28, 26, 12, 8, 15, 11, 25, - 2], - [23, 26, 18, 1, 10, 29, 28, 11, 24, 6, 5, 12, 19, 25, 13, 4, 15, 20, 22, 14, 17, 7, 9, 27, 2, 3, 16, 21, 8, - 0], - [9, 13, 27, 18, 21, 0, 5, 12, 19, 22, 29, 10, 17, 14, 26, 8, 16, 1, 4, 28, 6, 15, 11, 2, 24, 25, 3, 20, 7, - 23], - [4, 26, 11, 3, 13, 16, 1, 12, 22, 0, 29, 7, 28, 2, 20, 17, 21, 5, 23, 19, 14, 8, 10, 18, 6, 27, 25, 9, 15, - 24], - [21, 18, 22, 11, 27, 19, 5, 20, 26, 12, 24, 1, 4, 13, 2, 6, 23, 25, 9, 10, 17, 15, 28, 7, 3, 29, 0, 8, 14, - 16], - [13, 28, 2, 10, 0, 17, 4, 18, 6, 14, 11, 26, 9, 5, 20, 12, 25, 21, 7, 8, 16, 23, 19, 27, 1, 3, 24, 22, 15, - 29], - [25, 21, 13, 0, 26, 1, 24, 19, 27, 2, 11, 20, 15, 8, 12, 4, 5, 7, 17, 29, 10, 6, 3, 14, 28, 16, 18, 9, 22, - 23], - [9, 21, 10, 13, 1, 5, 20, 24, 19, 2, 28, 25, 11, 18, 14, 6, 26, 4, 29, 17, 22, 0, 12, 23, 8, 15, 7, 3, 27, - 16], - [29, 13, 2, 16, 27, 4, 28, 5, 20, 23, 17, 8, 21, 25, 14, 7, 22, 11, 24, 0, 15, 18, 9, 12, 6, 26, 19, 3, 1, - 10], - [24, 29, 28, 27, 4, 2, 0, 19, 5, 8, 14, 3, 21, 17, 20, 9, 12, 1, 18, 13, 25, 10, 11, 23, 6, 15, 16, 22, 26, - 7]] + [ + 29, + 6, + 0, + 27, + 19, + 10, + 4, + 11, + 12, + 13, + 18, + 20, + 2, + 5, + 26, + 16, + 23, + 14, + 21, + 3, + 25, + 17, + 1, + 24, + 7, + 22, + 28, + 8, + 15, + 9, + ], + [ + 22, + 9, + 3, + 4, + 1, + 2, + 17, + 20, + 18, + 13, + 26, + 5, + 14, + 29, + 8, + 16, + 23, + 0, + 28, + 7, + 6, + 19, + 24, + 11, + 27, + 21, + 12, + 15, + 10, + 25, + ], + [ + 25, + 27, + 4, + 22, + 11, + 0, + 19, + 13, + 9, + 17, + 8, + 3, + 29, + 21, + 12, + 1, + 2, + 10, + 20, + 18, + 26, + 5, + 23, + 24, + 14, + 6, + 28, + 7, + 16, + 15, + ], + [ + 12, + 4, + 15, + 18, + 23, + 13, + 21, + 9, + 19, + 5, + 0, + 25, + 22, + 29, + 1, + 3, + 26, + 6, + 14, + 7, + 10, + 28, + 24, + 17, + 16, + 2, + 27, + 11, + 20, + 8, + ], + [ + 8, + 21, + 18, + 1, + 29, + 20, + 0, + 23, + 14, + 10, + 25, + 28, + 16, + 12, + 13, + 5, + 26, + 9, + 4, + 17, + 19, + 11, + 24, + 27, + 3, + 6, + 7, + 22, + 2, + 15, + ], + [ + 0, + 17, + 13, + 21, + 12, + 11, + 9, + 16, + 8, + 27, + 29, + 5, + 10, + 4, + 18, + 23, + 25, + 6, + 26, + 22, + 14, + 1, + 7, + 15, + 3, + 19, + 28, + 24, + 2, + 20, + ], + [ + 5, + 18, + 27, + 13, + 0, + 24, + 29, + 8, + 14, + 4, + 19, + 10, + 22, + 9, + 26, + 25, + 16, + 3, + 15, + 6, + 28, + 11, + 1, + 7, + 12, + 20, + 23, + 17, + 21, + 2, + ], + [ + 23, + 27, + 1, + 10, + 5, + 20, + 9, + 24, + 18, + 19, + 8, + 2, + 15, + 16, + 12, + 21, + 26, + 4, + 13, + 25, + 11, + 0, + 14, + 7, + 29, + 22, + 6, + 28, + 3, + 17, + ], + [ + 18, + 22, + 21, + 7, + 24, + 23, + 9, + 19, + 2, + 5, + 1, + 13, + 14, + 16, + 12, + 8, + 3, + 20, + 6, + 29, + 28, + 15, + 26, + 17, + 0, + 4, + 27, + 10, + 11, + 25, + ], + [ + 7, + 2, + 24, + 23, + 15, + 13, + 8, + 10, + 9, + 11, + 21, + 4, + 12, + 27, + 0, + 14, + 6, + 17, + 25, + 5, + 3, + 19, + 29, + 26, + 1, + 18, + 20, + 16, + 28, + 22, + ], + [ + 27, + 19, + 7, + 14, + 21, + 0, + 6, + 1, + 24, + 3, + 18, + 13, + 10, + 16, + 5, + 23, + 4, + 9, + 29, + 20, + 22, + 17, + 28, + 26, + 12, + 8, + 15, + 11, + 25, + 2, + ], + [ + 23, + 26, + 18, + 1, + 10, + 29, + 28, + 11, + 24, + 6, + 5, + 12, + 19, + 25, + 13, + 4, + 15, + 20, + 22, + 14, + 17, + 7, + 9, + 27, + 2, + 3, + 16, + 21, + 8, + 0, + ], + [ + 9, + 13, + 27, + 18, + 21, + 0, + 5, + 12, + 19, + 22, + 29, + 10, + 17, + 14, + 26, + 8, + 16, + 1, + 4, + 28, + 6, + 15, + 11, + 2, + 24, + 25, + 3, + 20, + 7, + 23, + ], + [ + 4, + 26, + 11, + 3, + 13, + 16, + 1, + 12, + 22, + 0, + 29, + 7, + 28, + 2, + 20, + 17, + 21, + 5, + 23, + 19, + 14, + 8, + 10, + 18, + 6, + 27, + 25, + 9, + 15, + 24, + ], + [ + 21, + 18, + 22, + 11, + 27, + 19, + 5, + 20, + 26, + 12, + 24, + 1, + 4, + 13, + 2, + 6, + 23, + 25, + 9, + 10, + 17, + 15, + 28, + 7, + 3, + 29, + 0, + 8, + 14, + 16, + ], + [ + 13, + 28, + 2, + 10, + 0, + 17, + 4, + 18, + 6, + 14, + 11, + 26, + 9, + 5, + 20, + 12, + 25, + 21, + 7, + 8, + 16, + 23, + 19, + 27, + 1, + 3, + 24, + 22, + 15, + 29, + ], + [ + 25, + 21, + 13, + 0, + 26, + 1, + 24, + 19, + 27, + 2, + 11, + 20, + 15, + 8, + 12, + 4, + 5, + 7, + 17, + 29, + 10, + 6, + 3, + 14, + 28, + 16, + 18, + 9, + 22, + 23, + ], + [ + 9, + 21, + 10, + 13, + 1, + 5, + 20, + 24, + 19, + 2, + 28, + 25, + 11, + 18, + 14, + 6, + 26, + 4, + 29, + 17, + 22, + 0, + 12, + 23, + 8, + 15, + 7, + 3, + 27, + 16, + ], + [ + 29, + 13, + 2, + 16, + 27, + 4, + 28, + 5, + 20, + 23, + 17, + 8, + 21, + 25, + 14, + 7, + 22, + 11, + 24, + 0, + 15, + 18, + 9, + 12, + 6, + 26, + 19, + 3, + 1, + 10, + ], + [ + 24, + 29, + 28, + 27, + 4, + 2, + 0, + 19, + 5, + 8, + 14, + 3, + 21, + 17, + 20, + 9, + 12, + 1, + 18, + 13, + 25, + 10, + 11, + 23, + 6, + 15, + 16, + 22, + 26, + 7, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -348,10 +2829,18 @@ def test_optimum_ta44(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -359,59 +2848,670 @@ def test_optimum_ta44(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 1979) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta45(self): # http://optimizizer.com/solution.php?name=ta45&UB=2000&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta45'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta45" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [29, 25, 11, 17, 22, 26, 27, 21, 13, 7, 18, 15, 1, 8, 28, 0, 19, 6, 24, 10, 2, 23, 20, 4, 5, 9, 14, 16, 12, - 3], - [29, 14, 19, 28, 27, 0, 24, 21, 22, 26, 7, 12, 5, 8, 10, 15, 18, 25, 11, 17, 13, 9, 6, 20, 4, 16, 2, 23, 3, - 1], - [3, 2, 28, 15, 5, 27, 6, 4, 8, 14, 10, 1, 17, 7, 12, 18, 22, 11, 23, 26, 19, 20, 21, 25, 0, 29, 13, 16, 9, - 24], - [11, 6, 14, 20, 17, 26, 0, 15, 27, 22, 21, 7, 16, 23, 18, 13, 3, 29, 28, 4, 12, 1, 24, 5, 10, 19, 9, 8, 25, - 2], - [5, 3, 21, 13, 4, 2, 19, 20, 6, 26, 23, 12, 17, 27, 11, 28, 8, 0, 7, 22, 16, 18, 29, 10, 9, 24, 14, 1, 25, - 15], - [21, 28, 22, 24, 20, 13, 8, 7, 3, 25, 29, 0, 10, 14, 16, 5, 4, 12, 27, 18, 26, 17, 23, 2, 6, 9, 15, 19, 1, - 11], - [7, 5, 17, 12, 24, 6, 26, 3, 28, 9, 11, 1, 29, 27, 18, 16, 23, 4, 0, 20, 25, 13, 21, 14, 8, 15, 10, 22, 2, - 19], - [17, 15, 28, 27, 11, 21, 22, 23, 18, 5, 10, 0, 20, 25, 9, 7, 2, 4, 1, 3, 29, 6, 8, 19, 14, 16, 24, 26, 13, - 12], - [24, 1, 28, 21, 3, 17, 18, 7, 11, 27, 25, 12, 14, 5, 6, 10, 19, 4, 20, 9, 26, 15, 16, 0, 22, 13, 8, 23, 2, - 29], - [11, 7, 3, 18, 17, 0, 26, 6, 4, 12, 16, 5, 23, 9, 24, 25, 15, 14, 20, 28, 1, 22, 13, 10, 8, 29, 21, 19, 2, - 27], - [20, 29, 3, 8, 28, 15, 12, 0, 10, 25, 27, 6, 23, 11, 5, 9, 2, 1, 13, 21, 18, 4, 24, 16, 14, 26, 7, 19, 17, - 22], - [28, 0, 6, 26, 13, 4, 27, 15, 9, 21, 23, 10, 11, 17, 14, 18, 20, 1, 19, 22, 25, 24, 3, 7, 5, 2, 16, 29, 8, - 12], - [15, 26, 14, 18, 7, 3, 28, 25, 16, 22, 13, 6, 4, 17, 29, 5, 27, 10, 11, 19, 2, 24, 12, 1, 20, 8, 21, 23, 9, - 0], - [22, 24, 27, 15, 11, 12, 26, 0, 18, 28, 13, 6, 7, 17, 1, 23, 16, 21, 5, 2, 8, 19, 4, 10, 9, 14, 20, 25, 3, - 29], - [23, 22, 6, 26, 15, 29, 11, 5, 28, 18, 27, 24, 12, 8, 25, 10, 9, 7, 2, 13, 21, 20, 17, 4, 3, 1, 14, 16, 0, - 19], - [23, 27, 1, 6, 14, 8, 13, 9, 11, 0, 5, 10, 26, 20, 21, 7, 17, 4, 15, 28, 2, 18, 22, 25, 3, 24, 29, 19, 16, - 12], - [16, 23, 22, 5, 29, 20, 12, 8, 7, 17, 25, 1, 18, 15, 4, 21, 14, 28, 9, 19, 13, 6, 10, 3, 2, 0, 27, 26, 24, - 11], - [3, 2, 7, 8, 28, 24, 9, 6, 22, 21, 15, 12, 16, 17, 27, 14, 5, 23, 25, 1, 10, 29, 13, 0, 11, 20, 19, 18, 26, - 4], - [27, 2, 0, 5, 4, 22, 19, 1, 12, 8, 3, 26, 23, 25, 17, 15, 7, 20, 13, 11, 29, 28, 18, 6, 10, 24, 9, 21, 14, - 16], - [15, 11, 29, 6, 23, 25, 0, 17, 18, 16, 24, 22, 13, 10, 20, 21, 5, 9, 1, 28, 2, 27, 3, 19, 12, 4, 14, 8, 7, - 26]] + [ + 29, + 25, + 11, + 17, + 22, + 26, + 27, + 21, + 13, + 7, + 18, + 15, + 1, + 8, + 28, + 0, + 19, + 6, + 24, + 10, + 2, + 23, + 20, + 4, + 5, + 9, + 14, + 16, + 12, + 3, + ], + [ + 29, + 14, + 19, + 28, + 27, + 0, + 24, + 21, + 22, + 26, + 7, + 12, + 5, + 8, + 10, + 15, + 18, + 25, + 11, + 17, + 13, + 9, + 6, + 20, + 4, + 16, + 2, + 23, + 3, + 1, + ], + [ + 3, + 2, + 28, + 15, + 5, + 27, + 6, + 4, + 8, + 14, + 10, + 1, + 17, + 7, + 12, + 18, + 22, + 11, + 23, + 26, + 19, + 20, + 21, + 25, + 0, + 29, + 13, + 16, + 9, + 24, + ], + [ + 11, + 6, + 14, + 20, + 17, + 26, + 0, + 15, + 27, + 22, + 21, + 7, + 16, + 23, + 18, + 13, + 3, + 29, + 28, + 4, + 12, + 1, + 24, + 5, + 10, + 19, + 9, + 8, + 25, + 2, + ], + [ + 5, + 3, + 21, + 13, + 4, + 2, + 19, + 20, + 6, + 26, + 23, + 12, + 17, + 27, + 11, + 28, + 8, + 0, + 7, + 22, + 16, + 18, + 29, + 10, + 9, + 24, + 14, + 1, + 25, + 15, + ], + [ + 21, + 28, + 22, + 24, + 20, + 13, + 8, + 7, + 3, + 25, + 29, + 0, + 10, + 14, + 16, + 5, + 4, + 12, + 27, + 18, + 26, + 17, + 23, + 2, + 6, + 9, + 15, + 19, + 1, + 11, + ], + [ + 7, + 5, + 17, + 12, + 24, + 6, + 26, + 3, + 28, + 9, + 11, + 1, + 29, + 27, + 18, + 16, + 23, + 4, + 0, + 20, + 25, + 13, + 21, + 14, + 8, + 15, + 10, + 22, + 2, + 19, + ], + [ + 17, + 15, + 28, + 27, + 11, + 21, + 22, + 23, + 18, + 5, + 10, + 0, + 20, + 25, + 9, + 7, + 2, + 4, + 1, + 3, + 29, + 6, + 8, + 19, + 14, + 16, + 24, + 26, + 13, + 12, + ], + [ + 24, + 1, + 28, + 21, + 3, + 17, + 18, + 7, + 11, + 27, + 25, + 12, + 14, + 5, + 6, + 10, + 19, + 4, + 20, + 9, + 26, + 15, + 16, + 0, + 22, + 13, + 8, + 23, + 2, + 29, + ], + [ + 11, + 7, + 3, + 18, + 17, + 0, + 26, + 6, + 4, + 12, + 16, + 5, + 23, + 9, + 24, + 25, + 15, + 14, + 20, + 28, + 1, + 22, + 13, + 10, + 8, + 29, + 21, + 19, + 2, + 27, + ], + [ + 20, + 29, + 3, + 8, + 28, + 15, + 12, + 0, + 10, + 25, + 27, + 6, + 23, + 11, + 5, + 9, + 2, + 1, + 13, + 21, + 18, + 4, + 24, + 16, + 14, + 26, + 7, + 19, + 17, + 22, + ], + [ + 28, + 0, + 6, + 26, + 13, + 4, + 27, + 15, + 9, + 21, + 23, + 10, + 11, + 17, + 14, + 18, + 20, + 1, + 19, + 22, + 25, + 24, + 3, + 7, + 5, + 2, + 16, + 29, + 8, + 12, + ], + [ + 15, + 26, + 14, + 18, + 7, + 3, + 28, + 25, + 16, + 22, + 13, + 6, + 4, + 17, + 29, + 5, + 27, + 10, + 11, + 19, + 2, + 24, + 12, + 1, + 20, + 8, + 21, + 23, + 9, + 0, + ], + [ + 22, + 24, + 27, + 15, + 11, + 12, + 26, + 0, + 18, + 28, + 13, + 6, + 7, + 17, + 1, + 23, + 16, + 21, + 5, + 2, + 8, + 19, + 4, + 10, + 9, + 14, + 20, + 25, + 3, + 29, + ], + [ + 23, + 22, + 6, + 26, + 15, + 29, + 11, + 5, + 28, + 18, + 27, + 24, + 12, + 8, + 25, + 10, + 9, + 7, + 2, + 13, + 21, + 20, + 17, + 4, + 3, + 1, + 14, + 16, + 0, + 19, + ], + [ + 23, + 27, + 1, + 6, + 14, + 8, + 13, + 9, + 11, + 0, + 5, + 10, + 26, + 20, + 21, + 7, + 17, + 4, + 15, + 28, + 2, + 18, + 22, + 25, + 3, + 24, + 29, + 19, + 16, + 12, + ], + [ + 16, + 23, + 22, + 5, + 29, + 20, + 12, + 8, + 7, + 17, + 25, + 1, + 18, + 15, + 4, + 21, + 14, + 28, + 9, + 19, + 13, + 6, + 10, + 3, + 2, + 0, + 27, + 26, + 24, + 11, + ], + [ + 3, + 2, + 7, + 8, + 28, + 24, + 9, + 6, + 22, + 21, + 15, + 12, + 16, + 17, + 27, + 14, + 5, + 23, + 25, + 1, + 10, + 29, + 13, + 0, + 11, + 20, + 19, + 18, + 26, + 4, + ], + [ + 27, + 2, + 0, + 5, + 4, + 22, + 19, + 1, + 12, + 8, + 3, + 26, + 23, + 25, + 17, + 15, + 7, + 20, + 13, + 11, + 29, + 28, + 18, + 6, + 10, + 24, + 9, + 21, + 14, + 16, + ], + [ + 15, + 11, + 29, + 6, + 23, + 25, + 0, + 17, + 18, + 16, + 24, + 22, + 13, + 10, + 20, + 21, + 5, + 9, + 1, + 28, + 2, + 27, + 3, + 19, + 12, + 4, + 14, + 8, + 7, + 26, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -425,10 +3525,18 @@ def test_optimum_ta45(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -436,59 +3544,670 @@ def test_optimum_ta45(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 2000) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta46(self): # http://optimizizer.com/solution.php?name=ta46&UB=2006&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta46'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta46" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [29, 6, 14, 19, 13, 5, 8, 16, 11, 17, 1, 28, 22, 21, 18, 27, 20, 12, 15, 23, 9, 0, 4, 24, 25, 10, 3, 7, 2, - 26], - [10, 14, 22, 25, 15, 26, 27, 4, 11, 3, 13, 0, 6, 18, 1, 16, 21, 5, 12, 2, 23, 20, 28, 24, 19, 9, 17, 7, 29, - 8], - [13, 26, 16, 11, 17, 19, 21, 4, 14, 10, 15, 27, 6, 28, 3, 24, 29, 9, 8, 20, 22, 12, 1, 25, 23, 0, 2, 18, 5, - 7], - [19, 4, 15, 26, 17, 29, 9, 7, 13, 16, 12, 5, 11, 20, 8, 3, 18, 1, 27, 2, 23, 6, 22, 14, 0, 24, 21, 10, 28, - 25], - [18, 22, 17, 13, 29, 15, 25, 26, 16, 11, 21, 6, 7, 8, 4, 9, 20, 14, 3, 28, 23, 24, 1, 27, 10, 2, 12, 0, 5, - 19], - [17, 14, 6, 8, 15, 16, 1, 19, 9, 28, 22, 7, 11, 18, 12, 26, 13, 21, 20, 23, 4, 29, 2, 24, 10, 0, 3, 25, 5, - 27], - [12, 13, 5, 25, 19, 28, 23, 26, 16, 10, 6, 1, 27, 18, 8, 14, 7, 22, 11, 2, 24, 9, 29, 3, 15, 21, 4, 17, 0, - 20], - [29, 14, 5, 11, 25, 16, 15, 17, 0, 13, 21, 18, 6, 10, 19, 28, 7, 9, 20, 2, 1, 8, 4, 26, 27, 12, 23, 24, 3, - 22], - [29, 26, 25, 6, 8, 1, 14, 4, 5, 22, 18, 11, 9, 17, 13, 27, 19, 12, 28, 21, 24, 0, 15, 20, 16, 3, 2, 23, 10, - 7], - [14, 25, 9, 6, 5, 24, 18, 3, 21, 29, 19, 26, 16, 8, 28, 12, 13, 27, 7, 11, 2, 17, 23, 15, 22, 4, 1, 10, 0, - 20], - [6, 1, 19, 15, 8, 17, 10, 0, 4, 13, 16, 25, 14, 22, 11, 5, 2, 28, 23, 20, 3, 27, 9, 18, 21, 29, 7, 26, 12, - 24], - [11, 5, 15, 14, 1, 8, 16, 26, 23, 0, 17, 12, 24, 3, 10, 20, 21, 29, 27, 4, 22, 7, 2, 25, 13, 18, 9, 6, 19, - 28], - [22, 8, 16, 13, 9, 0, 6, 19, 14, 26, 25, 5, 7, 27, 17, 18, 12, 11, 29, 4, 10, 20, 3, 24, 21, 2, 28, 1, 15, - 23], - [23, 3, 20, 24, 5, 16, 18, 15, 6, 19, 9, 26, 28, 27, 8, 12, 7, 1, 11, 14, 21, 10, 25, 29, 4, 22, 17, 2, 0, - 13], - [19, 15, 28, 24, 26, 11, 5, 0, 16, 17, 22, 7, 3, 6, 10, 12, 14, 8, 20, 1, 29, 2, 9, 23, 13, 21, 27, 25, 4, - 18], - [6, 2, 26, 9, 17, 11, 5, 0, 20, 15, 1, 16, 10, 7, 22, 14, 4, 18, 21, 29, 27, 24, 13, 8, 28, 19, 12, 25, 3, - 23], - [19, 20, 25, 13, 1, 5, 16, 28, 9, 26, 8, 17, 23, 11, 6, 18, 14, 10, 21, 22, 2, 4, 27, 3, 7, 15, 29, 24, 12, - 0], - [28, 20, 11, 13, 16, 21, 27, 26, 8, 6, 0, 17, 18, 10, 15, 23, 9, 1, 22, 24, 25, 29, 3, 2, 5, 4, 19, 7, 12, - 14], - [25, 22, 5, 6, 10, 29, 28, 3, 13, 16, 21, 9, 7, 14, 26, 19, 1, 15, 12, 23, 0, 24, 2, 27, 11, 20, 18, 17, 8, - 4], - [5, 29, 11, 26, 0, 6, 8, 10, 27, 22, 7, 16, 17, 1, 9, 14, 28, 2, 3, 21, 23, 19, 12, 15, 13, 18, 20, 24, 25, - 4]] + [ + 29, + 6, + 14, + 19, + 13, + 5, + 8, + 16, + 11, + 17, + 1, + 28, + 22, + 21, + 18, + 27, + 20, + 12, + 15, + 23, + 9, + 0, + 4, + 24, + 25, + 10, + 3, + 7, + 2, + 26, + ], + [ + 10, + 14, + 22, + 25, + 15, + 26, + 27, + 4, + 11, + 3, + 13, + 0, + 6, + 18, + 1, + 16, + 21, + 5, + 12, + 2, + 23, + 20, + 28, + 24, + 19, + 9, + 17, + 7, + 29, + 8, + ], + [ + 13, + 26, + 16, + 11, + 17, + 19, + 21, + 4, + 14, + 10, + 15, + 27, + 6, + 28, + 3, + 24, + 29, + 9, + 8, + 20, + 22, + 12, + 1, + 25, + 23, + 0, + 2, + 18, + 5, + 7, + ], + [ + 19, + 4, + 15, + 26, + 17, + 29, + 9, + 7, + 13, + 16, + 12, + 5, + 11, + 20, + 8, + 3, + 18, + 1, + 27, + 2, + 23, + 6, + 22, + 14, + 0, + 24, + 21, + 10, + 28, + 25, + ], + [ + 18, + 22, + 17, + 13, + 29, + 15, + 25, + 26, + 16, + 11, + 21, + 6, + 7, + 8, + 4, + 9, + 20, + 14, + 3, + 28, + 23, + 24, + 1, + 27, + 10, + 2, + 12, + 0, + 5, + 19, + ], + [ + 17, + 14, + 6, + 8, + 15, + 16, + 1, + 19, + 9, + 28, + 22, + 7, + 11, + 18, + 12, + 26, + 13, + 21, + 20, + 23, + 4, + 29, + 2, + 24, + 10, + 0, + 3, + 25, + 5, + 27, + ], + [ + 12, + 13, + 5, + 25, + 19, + 28, + 23, + 26, + 16, + 10, + 6, + 1, + 27, + 18, + 8, + 14, + 7, + 22, + 11, + 2, + 24, + 9, + 29, + 3, + 15, + 21, + 4, + 17, + 0, + 20, + ], + [ + 29, + 14, + 5, + 11, + 25, + 16, + 15, + 17, + 0, + 13, + 21, + 18, + 6, + 10, + 19, + 28, + 7, + 9, + 20, + 2, + 1, + 8, + 4, + 26, + 27, + 12, + 23, + 24, + 3, + 22, + ], + [ + 29, + 26, + 25, + 6, + 8, + 1, + 14, + 4, + 5, + 22, + 18, + 11, + 9, + 17, + 13, + 27, + 19, + 12, + 28, + 21, + 24, + 0, + 15, + 20, + 16, + 3, + 2, + 23, + 10, + 7, + ], + [ + 14, + 25, + 9, + 6, + 5, + 24, + 18, + 3, + 21, + 29, + 19, + 26, + 16, + 8, + 28, + 12, + 13, + 27, + 7, + 11, + 2, + 17, + 23, + 15, + 22, + 4, + 1, + 10, + 0, + 20, + ], + [ + 6, + 1, + 19, + 15, + 8, + 17, + 10, + 0, + 4, + 13, + 16, + 25, + 14, + 22, + 11, + 5, + 2, + 28, + 23, + 20, + 3, + 27, + 9, + 18, + 21, + 29, + 7, + 26, + 12, + 24, + ], + [ + 11, + 5, + 15, + 14, + 1, + 8, + 16, + 26, + 23, + 0, + 17, + 12, + 24, + 3, + 10, + 20, + 21, + 29, + 27, + 4, + 22, + 7, + 2, + 25, + 13, + 18, + 9, + 6, + 19, + 28, + ], + [ + 22, + 8, + 16, + 13, + 9, + 0, + 6, + 19, + 14, + 26, + 25, + 5, + 7, + 27, + 17, + 18, + 12, + 11, + 29, + 4, + 10, + 20, + 3, + 24, + 21, + 2, + 28, + 1, + 15, + 23, + ], + [ + 23, + 3, + 20, + 24, + 5, + 16, + 18, + 15, + 6, + 19, + 9, + 26, + 28, + 27, + 8, + 12, + 7, + 1, + 11, + 14, + 21, + 10, + 25, + 29, + 4, + 22, + 17, + 2, + 0, + 13, + ], + [ + 19, + 15, + 28, + 24, + 26, + 11, + 5, + 0, + 16, + 17, + 22, + 7, + 3, + 6, + 10, + 12, + 14, + 8, + 20, + 1, + 29, + 2, + 9, + 23, + 13, + 21, + 27, + 25, + 4, + 18, + ], + [ + 6, + 2, + 26, + 9, + 17, + 11, + 5, + 0, + 20, + 15, + 1, + 16, + 10, + 7, + 22, + 14, + 4, + 18, + 21, + 29, + 27, + 24, + 13, + 8, + 28, + 19, + 12, + 25, + 3, + 23, + ], + [ + 19, + 20, + 25, + 13, + 1, + 5, + 16, + 28, + 9, + 26, + 8, + 17, + 23, + 11, + 6, + 18, + 14, + 10, + 21, + 22, + 2, + 4, + 27, + 3, + 7, + 15, + 29, + 24, + 12, + 0, + ], + [ + 28, + 20, + 11, + 13, + 16, + 21, + 27, + 26, + 8, + 6, + 0, + 17, + 18, + 10, + 15, + 23, + 9, + 1, + 22, + 24, + 25, + 29, + 3, + 2, + 5, + 4, + 19, + 7, + 12, + 14, + ], + [ + 25, + 22, + 5, + 6, + 10, + 29, + 28, + 3, + 13, + 16, + 21, + 9, + 7, + 14, + 26, + 19, + 1, + 15, + 12, + 23, + 0, + 24, + 2, + 27, + 11, + 20, + 18, + 17, + 8, + 4, + ], + [ + 5, + 29, + 11, + 26, + 0, + 6, + 8, + 10, + 27, + 22, + 7, + 16, + 17, + 1, + 9, + 14, + 28, + 2, + 3, + 21, + 23, + 19, + 12, + 15, + 13, + 18, + 20, + 24, + 25, + 4, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -502,10 +4221,18 @@ def test_optimum_ta46(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -513,59 +4240,670 @@ def test_optimum_ta46(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 2006) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta47(self): # http://optimizizer.com/solution.php?name=ta47&UB=1889&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta47'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta47" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [15, 8, 19, 23, 1, 11, 25, 26, 24, 28, 16, 2, 4, 7, 18, 0, 14, 20, 13, 12, 29, 27, 21, 3, 10, 5, 6, 9, 17, - 22], - [16, 17, 7, 8, 1, 0, 23, 15, 3, 28, 18, 25, 26, 6, 27, 2, 19, 14, 29, 11, 10, 13, 22, 4, 12, 24, 21, 5, 20, - 9], - [3, 20, 8, 6, 28, 23, 27, 4, 18, 1, 22, 2, 16, 19, 0, 24, 9, 26, 21, 11, 12, 14, 25, 5, 15, 29, 10, 17, 13, - 7], - [17, 12, 15, 28, 24, 11, 13, 8, 2, 1, 29, 18, 16, 9, 4, 26, 7, 10, 25, 5, 0, 14, 21, 22, 20, 6, 27, 3, 19, - 23], - [1, 23, 8, 15, 12, 27, 6, 14, 4, 18, 26, 25, 7, 3, 11, 21, 24, 5, 16, 28, 20, 13, 2, 22, 17, 10, 19, 0, 29, - 9], - [13, 5, 24, 28, 19, 1, 22, 7, 16, 12, 23, 3, 6, 15, 11, 18, 25, 26, 29, 8, 9, 21, 2, 20, 17, 0, 14, 27, 10, - 4], - [9, 24, 28, 3, 5, 7, 8, 1, 13, 12, 6, 19, 21, 0, 18, 29, 4, 20, 10, 17, 23, 27, 15, 25, 22, 16, 11, 14, 2, - 26], - [14, 0, 7, 12, 18, 15, 10, 24, 27, 6, 16, 17, 23, 19, 11, 13, 20, 29, 21, 5, 26, 1, 9, 3, 4, 25, 2, 22, 8, - 28], - [4, 1, 21, 6, 15, 23, 18, 24, 0, 12, 5, 26, 7, 11, 13, 14, 17, 27, 9, 8, 3, 16, 28, 22, 19, 25, 20, 29, 2, - 10], - [25, 21, 19, 20, 18, 6, 15, 5, 28, 24, 3, 27, 12, 2, 10, 4, 17, 7, 29, 8, 1, 14, 9, 22, 16, 26, 13, 11, 23, - 0], - [29, 2, 18, 24, 4, 23, 15, 5, 14, 1, 0, 11, 13, 16, 7, 27, 10, 19, 9, 28, 12, 25, 22, 3, 17, 21, 8, 6, 20, - 26], - [0, 18, 16, 15, 10, 24, 29, 1, 11, 25, 14, 3, 2, 19, 6, 9, 27, 8, 5, 4, 7, 26, 22, 28, 12, 21, 20, 23, 13, - 17], - [8, 13, 10, 17, 0, 18, 3, 1, 7, 28, 14, 16, 19, 5, 12, 2, 25, 15, 29, 24, 4, 21, 26, 27, 20, 23, 9, 6, 22, - 11], - [9, 19, 20, 15, 5, 27, 3, 14, 1, 23, 13, 12, 2, 11, 6, 0, 18, 16, 28, 17, 24, 22, 25, 21, 29, 7, 26, 8, 4, - 10], - [20, 13, 2, 15, 3, 8, 19, 25, 28, 7, 23, 6, 9, 0, 21, 5, 29, 11, 10, 12, 1, 26, 14, 4, 24, 17, 27, 16, 22, - 18], - [3, 15, 18, 17, 19, 27, 11, 12, 24, 1, 5, 7, 28, 26, 20, 14, 13, 21, 23, 29, 9, 25, 0, 10, 4, 22, 16, 8, 6, - 2], - [21, 7, 0, 20, 4, 9, 8, 26, 5, 15, 14, 22, 3, 19, 27, 1, 24, 18, 17, 28, 23, 2, 13, 16, 11, 29, 6, 25, 12, - 10], - [4, 26, 9, 15, 21, 1, 3, 27, 28, 16, 19, 29, 8, 10, 24, 12, 18, 0, 25, 13, 11, 6, 20, 5, 14, 23, 7, 17, 22, - 2], - [25, 28, 10, 11, 9, 23, 16, 26, 14, 15, 0, 1, 21, 7, 20, 3, 2, 12, 13, 27, 29, 5, 6, 24, 19, 17, 18, 22, 4, - 8], - [16, 2, 0, 1, 3, 6, 9, 20, 4, 18, 28, 5, 8, 22, 23, 21, 25, 11, 24, 14, 10, 26, 17, 19, 15, 29, 12, 7, 27, - 13]] + [ + 15, + 8, + 19, + 23, + 1, + 11, + 25, + 26, + 24, + 28, + 16, + 2, + 4, + 7, + 18, + 0, + 14, + 20, + 13, + 12, + 29, + 27, + 21, + 3, + 10, + 5, + 6, + 9, + 17, + 22, + ], + [ + 16, + 17, + 7, + 8, + 1, + 0, + 23, + 15, + 3, + 28, + 18, + 25, + 26, + 6, + 27, + 2, + 19, + 14, + 29, + 11, + 10, + 13, + 22, + 4, + 12, + 24, + 21, + 5, + 20, + 9, + ], + [ + 3, + 20, + 8, + 6, + 28, + 23, + 27, + 4, + 18, + 1, + 22, + 2, + 16, + 19, + 0, + 24, + 9, + 26, + 21, + 11, + 12, + 14, + 25, + 5, + 15, + 29, + 10, + 17, + 13, + 7, + ], + [ + 17, + 12, + 15, + 28, + 24, + 11, + 13, + 8, + 2, + 1, + 29, + 18, + 16, + 9, + 4, + 26, + 7, + 10, + 25, + 5, + 0, + 14, + 21, + 22, + 20, + 6, + 27, + 3, + 19, + 23, + ], + [ + 1, + 23, + 8, + 15, + 12, + 27, + 6, + 14, + 4, + 18, + 26, + 25, + 7, + 3, + 11, + 21, + 24, + 5, + 16, + 28, + 20, + 13, + 2, + 22, + 17, + 10, + 19, + 0, + 29, + 9, + ], + [ + 13, + 5, + 24, + 28, + 19, + 1, + 22, + 7, + 16, + 12, + 23, + 3, + 6, + 15, + 11, + 18, + 25, + 26, + 29, + 8, + 9, + 21, + 2, + 20, + 17, + 0, + 14, + 27, + 10, + 4, + ], + [ + 9, + 24, + 28, + 3, + 5, + 7, + 8, + 1, + 13, + 12, + 6, + 19, + 21, + 0, + 18, + 29, + 4, + 20, + 10, + 17, + 23, + 27, + 15, + 25, + 22, + 16, + 11, + 14, + 2, + 26, + ], + [ + 14, + 0, + 7, + 12, + 18, + 15, + 10, + 24, + 27, + 6, + 16, + 17, + 23, + 19, + 11, + 13, + 20, + 29, + 21, + 5, + 26, + 1, + 9, + 3, + 4, + 25, + 2, + 22, + 8, + 28, + ], + [ + 4, + 1, + 21, + 6, + 15, + 23, + 18, + 24, + 0, + 12, + 5, + 26, + 7, + 11, + 13, + 14, + 17, + 27, + 9, + 8, + 3, + 16, + 28, + 22, + 19, + 25, + 20, + 29, + 2, + 10, + ], + [ + 25, + 21, + 19, + 20, + 18, + 6, + 15, + 5, + 28, + 24, + 3, + 27, + 12, + 2, + 10, + 4, + 17, + 7, + 29, + 8, + 1, + 14, + 9, + 22, + 16, + 26, + 13, + 11, + 23, + 0, + ], + [ + 29, + 2, + 18, + 24, + 4, + 23, + 15, + 5, + 14, + 1, + 0, + 11, + 13, + 16, + 7, + 27, + 10, + 19, + 9, + 28, + 12, + 25, + 22, + 3, + 17, + 21, + 8, + 6, + 20, + 26, + ], + [ + 0, + 18, + 16, + 15, + 10, + 24, + 29, + 1, + 11, + 25, + 14, + 3, + 2, + 19, + 6, + 9, + 27, + 8, + 5, + 4, + 7, + 26, + 22, + 28, + 12, + 21, + 20, + 23, + 13, + 17, + ], + [ + 8, + 13, + 10, + 17, + 0, + 18, + 3, + 1, + 7, + 28, + 14, + 16, + 19, + 5, + 12, + 2, + 25, + 15, + 29, + 24, + 4, + 21, + 26, + 27, + 20, + 23, + 9, + 6, + 22, + 11, + ], + [ + 9, + 19, + 20, + 15, + 5, + 27, + 3, + 14, + 1, + 23, + 13, + 12, + 2, + 11, + 6, + 0, + 18, + 16, + 28, + 17, + 24, + 22, + 25, + 21, + 29, + 7, + 26, + 8, + 4, + 10, + ], + [ + 20, + 13, + 2, + 15, + 3, + 8, + 19, + 25, + 28, + 7, + 23, + 6, + 9, + 0, + 21, + 5, + 29, + 11, + 10, + 12, + 1, + 26, + 14, + 4, + 24, + 17, + 27, + 16, + 22, + 18, + ], + [ + 3, + 15, + 18, + 17, + 19, + 27, + 11, + 12, + 24, + 1, + 5, + 7, + 28, + 26, + 20, + 14, + 13, + 21, + 23, + 29, + 9, + 25, + 0, + 10, + 4, + 22, + 16, + 8, + 6, + 2, + ], + [ + 21, + 7, + 0, + 20, + 4, + 9, + 8, + 26, + 5, + 15, + 14, + 22, + 3, + 19, + 27, + 1, + 24, + 18, + 17, + 28, + 23, + 2, + 13, + 16, + 11, + 29, + 6, + 25, + 12, + 10, + ], + [ + 4, + 26, + 9, + 15, + 21, + 1, + 3, + 27, + 28, + 16, + 19, + 29, + 8, + 10, + 24, + 12, + 18, + 0, + 25, + 13, + 11, + 6, + 20, + 5, + 14, + 23, + 7, + 17, + 22, + 2, + ], + [ + 25, + 28, + 10, + 11, + 9, + 23, + 16, + 26, + 14, + 15, + 0, + 1, + 21, + 7, + 20, + 3, + 2, + 12, + 13, + 27, + 29, + 5, + 6, + 24, + 19, + 17, + 18, + 22, + 4, + 8, + ], + [ + 16, + 2, + 0, + 1, + 3, + 6, + 9, + 20, + 4, + 18, + 28, + 5, + 8, + 22, + 23, + 21, + 25, + 11, + 24, + 14, + 10, + 26, + 17, + 19, + 15, + 29, + 12, + 7, + 27, + 13, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -579,10 +4917,18 @@ def test_optimum_ta47(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -590,59 +4936,670 @@ def test_optimum_ta47(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 1889) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta48(self): # http://optimizizer.com/solution.php?name=ta48&UB=1937&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta48'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta48" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [24, 13, 22, 18, 2, 15, 9, 11, 12, 25, 5, 29, 8, 16, 4, 14, 17, 21, 27, 7, 0, 3, 23, 20, 28, 19, 10, 6, 1, - 26], - [28, 26, 24, 22, 8, 23, 4, 16, 2, 14, 12, 5, 9, 10, 7, 27, 20, 19, 13, 29, 18, 3, 17, 21, 0, 1, 11, 15, 6, - 25], - [1, 13, 10, 12, 7, 29, 23, 5, 27, 24, 19, 3, 6, 26, 22, 15, 8, 21, 25, 0, 2, 14, 28, 17, 11, 20, 16, 18, 4, - 9], - [17, 9, 4, 27, 13, 16, 8, 2, 5, 25, 20, 15, 12, 14, 3, 7, 28, 6, 24, 18, 21, 19, 10, 23, 1, 26, 0, 29, 11, - 22], - [8, 1, 24, 25, 28, 10, 27, 16, 15, 19, 12, 4, 18, 7, 23, 5, 13, 9, 29, 3, 20, 21, 2, 0, 14, 22, 11, 17, 26, - 6], - [26, 27, 29, 17, 7, 11, 3, 24, 4, 14, 12, 18, 23, 28, 20, 15, 19, 0, 9, 6, 16, 2, 22, 10, 21, 5, 1, 13, 25, - 8], - [29, 24, 0, 25, 27, 5, 23, 28, 11, 22, 13, 9, 20, 8, 17, 21, 10, 6, 2, 18, 3, 12, 26, 4, 15, 19, 7, 1, 16, - 14], - [22, 12, 4, 6, 19, 11, 10, 2, 26, 28, 24, 29, 17, 23, 13, 27, 18, 21, 14, 16, 3, 7, 20, 9, 1, 0, 25, 5, 8, - 15], - [4, 28, 13, 27, 24, 9, 29, 5, 7, 20, 8, 25, 17, 10, 18, 3, 14, 23, 21, 0, 6, 16, 11, 2, 19, 22, 15, 26, 1, - 12], - [3, 7, 25, 4, 22, 11, 5, 26, 9, 24, 8, 14, 29, 12, 23, 19, 20, 27, 6, 18, 0, 2, 28, 21, 16, 1, 13, 17, 15, - 10], - [21, 3, 26, 23, 13, 12, 16, 9, 7, 28, 29, 20, 25, 22, 27, 18, 4, 5, 17, 14, 8, 10, 0, 24, 15, 19, 11, 2, 6, - 1], - [1, 11, 18, 25, 17, 26, 8, 22, 19, 12, 24, 28, 7, 3, 4, 14, 29, 9, 13, 23, 0, 27, 6, 20, 5, 10, 15, 21, 16, - 2], - [24, 12, 23, 1, 6, 17, 18, 2, 4, 13, 26, 3, 15, 5, 25, 8, 9, 14, 28, 16, 19, 27, 22, 0, 7, 21, 20, 10, 11, - 29], - [11, 29, 1, 12, 17, 2, 13, 5, 7, 26, 28, 27, 4, 23, 24, 6, 18, 25, 9, 0, 19, 14, 3, 8, 20, 16, 10, 22, 15, - 21], - [18, 9, 22, 28, 2, 26, 12, 3, 29, 5, 27, 13, 4, 14, 19, 15, 1, 7, 10, 24, 17, 21, 23, 20, 6, 16, 8, 0, 11, - 25], - [23, 17, 9, 10, 27, 8, 28, 12, 24, 15, 19, 4, 20, 5, 26, 29, 2, 0, 25, 22, 6, 11, 13, 18, 16, 7, 14, 3, 1, - 21], - [8, 12, 17, 23, 2, 6, 15, 10, 1, 26, 27, 11, 13, 9, 4, 28, 19, 18, 24, 7, 25, 20, 5, 14, 21, 0, 3, 16, 29, - 22], - [15, 21, 9, 13, 11, 29, 24, 4, 12, 23, 26, 28, 1, 8, 16, 7, 17, 20, 22, 5, 0, 6, 10, 14, 25, 18, 2, 19, 27, - 3], - [23, 28, 25, 2, 13, 1, 29, 26, 3, 9, 18, 17, 12, 5, 20, 10, 8, 27, 6, 24, 15, 22, 11, 7, 21, 14, 0, 4, 19, - 16], - [13, 12, 27, 29, 17, 25, 9, 2, 5, 1, 19, 7, 10, 21, 23, 20, 3, 22, 4, 16, 14, 0, 8, 11, 24, 15, 6, 28, 18, - 26]] + [ + 24, + 13, + 22, + 18, + 2, + 15, + 9, + 11, + 12, + 25, + 5, + 29, + 8, + 16, + 4, + 14, + 17, + 21, + 27, + 7, + 0, + 3, + 23, + 20, + 28, + 19, + 10, + 6, + 1, + 26, + ], + [ + 28, + 26, + 24, + 22, + 8, + 23, + 4, + 16, + 2, + 14, + 12, + 5, + 9, + 10, + 7, + 27, + 20, + 19, + 13, + 29, + 18, + 3, + 17, + 21, + 0, + 1, + 11, + 15, + 6, + 25, + ], + [ + 1, + 13, + 10, + 12, + 7, + 29, + 23, + 5, + 27, + 24, + 19, + 3, + 6, + 26, + 22, + 15, + 8, + 21, + 25, + 0, + 2, + 14, + 28, + 17, + 11, + 20, + 16, + 18, + 4, + 9, + ], + [ + 17, + 9, + 4, + 27, + 13, + 16, + 8, + 2, + 5, + 25, + 20, + 15, + 12, + 14, + 3, + 7, + 28, + 6, + 24, + 18, + 21, + 19, + 10, + 23, + 1, + 26, + 0, + 29, + 11, + 22, + ], + [ + 8, + 1, + 24, + 25, + 28, + 10, + 27, + 16, + 15, + 19, + 12, + 4, + 18, + 7, + 23, + 5, + 13, + 9, + 29, + 3, + 20, + 21, + 2, + 0, + 14, + 22, + 11, + 17, + 26, + 6, + ], + [ + 26, + 27, + 29, + 17, + 7, + 11, + 3, + 24, + 4, + 14, + 12, + 18, + 23, + 28, + 20, + 15, + 19, + 0, + 9, + 6, + 16, + 2, + 22, + 10, + 21, + 5, + 1, + 13, + 25, + 8, + ], + [ + 29, + 24, + 0, + 25, + 27, + 5, + 23, + 28, + 11, + 22, + 13, + 9, + 20, + 8, + 17, + 21, + 10, + 6, + 2, + 18, + 3, + 12, + 26, + 4, + 15, + 19, + 7, + 1, + 16, + 14, + ], + [ + 22, + 12, + 4, + 6, + 19, + 11, + 10, + 2, + 26, + 28, + 24, + 29, + 17, + 23, + 13, + 27, + 18, + 21, + 14, + 16, + 3, + 7, + 20, + 9, + 1, + 0, + 25, + 5, + 8, + 15, + ], + [ + 4, + 28, + 13, + 27, + 24, + 9, + 29, + 5, + 7, + 20, + 8, + 25, + 17, + 10, + 18, + 3, + 14, + 23, + 21, + 0, + 6, + 16, + 11, + 2, + 19, + 22, + 15, + 26, + 1, + 12, + ], + [ + 3, + 7, + 25, + 4, + 22, + 11, + 5, + 26, + 9, + 24, + 8, + 14, + 29, + 12, + 23, + 19, + 20, + 27, + 6, + 18, + 0, + 2, + 28, + 21, + 16, + 1, + 13, + 17, + 15, + 10, + ], + [ + 21, + 3, + 26, + 23, + 13, + 12, + 16, + 9, + 7, + 28, + 29, + 20, + 25, + 22, + 27, + 18, + 4, + 5, + 17, + 14, + 8, + 10, + 0, + 24, + 15, + 19, + 11, + 2, + 6, + 1, + ], + [ + 1, + 11, + 18, + 25, + 17, + 26, + 8, + 22, + 19, + 12, + 24, + 28, + 7, + 3, + 4, + 14, + 29, + 9, + 13, + 23, + 0, + 27, + 6, + 20, + 5, + 10, + 15, + 21, + 16, + 2, + ], + [ + 24, + 12, + 23, + 1, + 6, + 17, + 18, + 2, + 4, + 13, + 26, + 3, + 15, + 5, + 25, + 8, + 9, + 14, + 28, + 16, + 19, + 27, + 22, + 0, + 7, + 21, + 20, + 10, + 11, + 29, + ], + [ + 11, + 29, + 1, + 12, + 17, + 2, + 13, + 5, + 7, + 26, + 28, + 27, + 4, + 23, + 24, + 6, + 18, + 25, + 9, + 0, + 19, + 14, + 3, + 8, + 20, + 16, + 10, + 22, + 15, + 21, + ], + [ + 18, + 9, + 22, + 28, + 2, + 26, + 12, + 3, + 29, + 5, + 27, + 13, + 4, + 14, + 19, + 15, + 1, + 7, + 10, + 24, + 17, + 21, + 23, + 20, + 6, + 16, + 8, + 0, + 11, + 25, + ], + [ + 23, + 17, + 9, + 10, + 27, + 8, + 28, + 12, + 24, + 15, + 19, + 4, + 20, + 5, + 26, + 29, + 2, + 0, + 25, + 22, + 6, + 11, + 13, + 18, + 16, + 7, + 14, + 3, + 1, + 21, + ], + [ + 8, + 12, + 17, + 23, + 2, + 6, + 15, + 10, + 1, + 26, + 27, + 11, + 13, + 9, + 4, + 28, + 19, + 18, + 24, + 7, + 25, + 20, + 5, + 14, + 21, + 0, + 3, + 16, + 29, + 22, + ], + [ + 15, + 21, + 9, + 13, + 11, + 29, + 24, + 4, + 12, + 23, + 26, + 28, + 1, + 8, + 16, + 7, + 17, + 20, + 22, + 5, + 0, + 6, + 10, + 14, + 25, + 18, + 2, + 19, + 27, + 3, + ], + [ + 23, + 28, + 25, + 2, + 13, + 1, + 29, + 26, + 3, + 9, + 18, + 17, + 12, + 5, + 20, + 10, + 8, + 27, + 6, + 24, + 15, + 22, + 11, + 7, + 21, + 14, + 0, + 4, + 19, + 16, + ], + [ + 13, + 12, + 27, + 29, + 17, + 25, + 9, + 2, + 5, + 1, + 19, + 7, + 10, + 21, + 23, + 20, + 3, + 22, + 4, + 16, + 14, + 0, + 8, + 11, + 24, + 15, + 6, + 28, + 18, + 26, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -656,10 +5613,18 @@ def test_optimum_ta48(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -667,59 +5632,670 @@ def test_optimum_ta48(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 1937) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta49(self): # http://optimizizer.com/solution.php?name=ta49&UB=1963&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta49'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta49" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [19, 6, 27, 25, 14, 8, 24, 28, 20, 21, 3, 15, 29, 23, 0, 16, 4, 18, 26, 10, 11, 9, 17, 7, 2, 1, 5, 12, 22, - 13], - [15, 5, 6, 28, 29, 1, 11, 3, 18, 26, 7, 20, 8, 14, 0, 17, 2, 19, 21, 10, 25, 23, 24, 4, 9, 12, 13, 22, 27, - 16], - [11, 5, 8, 10, 1, 16, 14, 3, 23, 21, 2, 22, 13, 0, 12, 18, 7, 9, 26, 28, 20, 6, 17, 19, 4, 29, 25, 24, 27, - 15], - [10, 3, 13, 29, 8, 20, 18, 0, 11, 28, 16, 22, 19, 26, 23, 14, 25, 27, 24, 1, 17, 2, 7, 15, 21, 4, 12, 9, 6, - 5], - [20, 10, 24, 5, 11, 22, 26, 16, 18, 13, 17, 8, 19, 2, 3, 23, 0, 4, 27, 7, 21, 14, 9, 28, 12, 1, 25, 15, 29, - 6], - [4, 0, 25, 20, 16, 19, 27, 2, 28, 10, 3, 26, 23, 7, 22, 13, 8, 21, 24, 17, 12, 6, 5, 29, 18, 1, 14, 15, 9, - 11], - [20, 24, 21, 2, 5, 27, 10, 23, 17, 8, 9, 3, 6, 1, 22, 11, 19, 29, 18, 16, 14, 0, 12, 4, 25, 13, 15, 7, 28, - 26], - [27, 5, 17, 14, 15, 29, 9, 8, 23, 10, 24, 16, 3, 0, 1, 11, 7, 18, 19, 12, 2, 28, 21, 25, 13, 6, 20, 26, 4, - 22], - [0, 21, 20, 22, 8, 23, 9, 3, 25, 16, 13, 18, 6, 2, 26, 11, 17, 1, 10, 7, 29, 5, 19, 14, 27, 28, 24, 15, 12, - 4], - [9, 2, 5, 17, 28, 16, 8, 22, 26, 4, 21, 1, 0, 12, 20, 14, 19, 13, 10, 7, 23, 3, 27, 29, 15, 25, 6, 11, 24, - 18], - [8, 16, 23, 0, 9, 3, 19, 18, 2, 12, 21, 4, 26, 7, 17, 25, 22, 14, 24, 5, 29, 6, 1, 13, 15, 28, 10, 27, 11, - 20], - [19, 17, 26, 0, 16, 4, 28, 3, 7, 8, 23, 11, 13, 15, 27, 20, 9, 14, 2, 25, 21, 18, 22, 12, 1, 6, 29, 10, 5, - 24], - [17, 22, 6, 13, 20, 21, 9, 24, 8, 19, 12, 10, 28, 0, 16, 11, 23, 3, 25, 7, 15, 27, 2, 14, 18, 26, 1, 29, 4, - 5], - [20, 25, 2, 0, 27, 8, 1, 29, 22, 15, 17, 28, 26, 13, 21, 23, 11, 16, 24, 9, 14, 4, 3, 19, 18, 7, 6, 5, 10, - 12], - [1, 3, 15, 9, 21, 6, 25, 7, 18, 12, 27, 28, 20, 23, 0, 16, 22, 26, 11, 19, 24, 8, 17, 2, 4, 10, 29, 5, 13, - 14], - [18, 8, 26, 24, 10, 23, 28, 19, 14, 16, 11, 0, 17, 2, 4, 3, 25, 12, 7, 9, 29, 22, 21, 1, 20, 13, 27, 5, 15, - 6], - [26, 28, 22, 24, 27, 17, 29, 7, 16, 3, 12, 4, 10, 1, 11, 0, 18, 15, 20, 25, 8, 2, 19, 9, 6, 23, 14, 13, 21, - 5], - [28, 19, 18, 16, 26, 15, 29, 17, 0, 27, 3, 13, 4, 11, 1, 23, 25, 10, 12, 6, 21, 24, 7, 5, 9, 14, 22, 8, 20, - 2], - [26, 27, 8, 20, 10, 23, 1, 14, 16, 3, 6, 0, 7, 18, 28, 4, 21, 12, 9, 11, 2, 25, 5, 13, 24, 29, 15, 19, 22, - 17], - [8, 25, 15, 17, 9, 22, 14, 0, 12, 3, 1, 29, 21, 2, 16, 4, 27, 26, 28, 6, 11, 7, 23, 24, 5, 18, 10, 19, 20, - 13]] + [ + 19, + 6, + 27, + 25, + 14, + 8, + 24, + 28, + 20, + 21, + 3, + 15, + 29, + 23, + 0, + 16, + 4, + 18, + 26, + 10, + 11, + 9, + 17, + 7, + 2, + 1, + 5, + 12, + 22, + 13, + ], + [ + 15, + 5, + 6, + 28, + 29, + 1, + 11, + 3, + 18, + 26, + 7, + 20, + 8, + 14, + 0, + 17, + 2, + 19, + 21, + 10, + 25, + 23, + 24, + 4, + 9, + 12, + 13, + 22, + 27, + 16, + ], + [ + 11, + 5, + 8, + 10, + 1, + 16, + 14, + 3, + 23, + 21, + 2, + 22, + 13, + 0, + 12, + 18, + 7, + 9, + 26, + 28, + 20, + 6, + 17, + 19, + 4, + 29, + 25, + 24, + 27, + 15, + ], + [ + 10, + 3, + 13, + 29, + 8, + 20, + 18, + 0, + 11, + 28, + 16, + 22, + 19, + 26, + 23, + 14, + 25, + 27, + 24, + 1, + 17, + 2, + 7, + 15, + 21, + 4, + 12, + 9, + 6, + 5, + ], + [ + 20, + 10, + 24, + 5, + 11, + 22, + 26, + 16, + 18, + 13, + 17, + 8, + 19, + 2, + 3, + 23, + 0, + 4, + 27, + 7, + 21, + 14, + 9, + 28, + 12, + 1, + 25, + 15, + 29, + 6, + ], + [ + 4, + 0, + 25, + 20, + 16, + 19, + 27, + 2, + 28, + 10, + 3, + 26, + 23, + 7, + 22, + 13, + 8, + 21, + 24, + 17, + 12, + 6, + 5, + 29, + 18, + 1, + 14, + 15, + 9, + 11, + ], + [ + 20, + 24, + 21, + 2, + 5, + 27, + 10, + 23, + 17, + 8, + 9, + 3, + 6, + 1, + 22, + 11, + 19, + 29, + 18, + 16, + 14, + 0, + 12, + 4, + 25, + 13, + 15, + 7, + 28, + 26, + ], + [ + 27, + 5, + 17, + 14, + 15, + 29, + 9, + 8, + 23, + 10, + 24, + 16, + 3, + 0, + 1, + 11, + 7, + 18, + 19, + 12, + 2, + 28, + 21, + 25, + 13, + 6, + 20, + 26, + 4, + 22, + ], + [ + 0, + 21, + 20, + 22, + 8, + 23, + 9, + 3, + 25, + 16, + 13, + 18, + 6, + 2, + 26, + 11, + 17, + 1, + 10, + 7, + 29, + 5, + 19, + 14, + 27, + 28, + 24, + 15, + 12, + 4, + ], + [ + 9, + 2, + 5, + 17, + 28, + 16, + 8, + 22, + 26, + 4, + 21, + 1, + 0, + 12, + 20, + 14, + 19, + 13, + 10, + 7, + 23, + 3, + 27, + 29, + 15, + 25, + 6, + 11, + 24, + 18, + ], + [ + 8, + 16, + 23, + 0, + 9, + 3, + 19, + 18, + 2, + 12, + 21, + 4, + 26, + 7, + 17, + 25, + 22, + 14, + 24, + 5, + 29, + 6, + 1, + 13, + 15, + 28, + 10, + 27, + 11, + 20, + ], + [ + 19, + 17, + 26, + 0, + 16, + 4, + 28, + 3, + 7, + 8, + 23, + 11, + 13, + 15, + 27, + 20, + 9, + 14, + 2, + 25, + 21, + 18, + 22, + 12, + 1, + 6, + 29, + 10, + 5, + 24, + ], + [ + 17, + 22, + 6, + 13, + 20, + 21, + 9, + 24, + 8, + 19, + 12, + 10, + 28, + 0, + 16, + 11, + 23, + 3, + 25, + 7, + 15, + 27, + 2, + 14, + 18, + 26, + 1, + 29, + 4, + 5, + ], + [ + 20, + 25, + 2, + 0, + 27, + 8, + 1, + 29, + 22, + 15, + 17, + 28, + 26, + 13, + 21, + 23, + 11, + 16, + 24, + 9, + 14, + 4, + 3, + 19, + 18, + 7, + 6, + 5, + 10, + 12, + ], + [ + 1, + 3, + 15, + 9, + 21, + 6, + 25, + 7, + 18, + 12, + 27, + 28, + 20, + 23, + 0, + 16, + 22, + 26, + 11, + 19, + 24, + 8, + 17, + 2, + 4, + 10, + 29, + 5, + 13, + 14, + ], + [ + 18, + 8, + 26, + 24, + 10, + 23, + 28, + 19, + 14, + 16, + 11, + 0, + 17, + 2, + 4, + 3, + 25, + 12, + 7, + 9, + 29, + 22, + 21, + 1, + 20, + 13, + 27, + 5, + 15, + 6, + ], + [ + 26, + 28, + 22, + 24, + 27, + 17, + 29, + 7, + 16, + 3, + 12, + 4, + 10, + 1, + 11, + 0, + 18, + 15, + 20, + 25, + 8, + 2, + 19, + 9, + 6, + 23, + 14, + 13, + 21, + 5, + ], + [ + 28, + 19, + 18, + 16, + 26, + 15, + 29, + 17, + 0, + 27, + 3, + 13, + 4, + 11, + 1, + 23, + 25, + 10, + 12, + 6, + 21, + 24, + 7, + 5, + 9, + 14, + 22, + 8, + 20, + 2, + ], + [ + 26, + 27, + 8, + 20, + 10, + 23, + 1, + 14, + 16, + 3, + 6, + 0, + 7, + 18, + 28, + 4, + 21, + 12, + 9, + 11, + 2, + 25, + 5, + 13, + 24, + 29, + 15, + 19, + 22, + 17, + ], + [ + 8, + 25, + 15, + 17, + 9, + 22, + 14, + 0, + 12, + 3, + 1, + 29, + 21, + 2, + 16, + 4, + 27, + 26, + 28, + 6, + 11, + 7, + 23, + 24, + 5, + 18, + 10, + 19, + 20, + 13, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -733,10 +6309,18 @@ def test_optimum_ta49(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -744,59 +6328,670 @@ def test_optimum_ta49(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 1963) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta50(self): # http://optimizizer.com/solution.php?name=ta50&UB=1923&problemclass=ta - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta50'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta50" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [4, 11, 1, 2, 12, 25, 9, 6, 29, 0, 28, 13, 5, 8, 21, 23, 22, 14, 20, 16, 15, 7, 26, 27, 17, 19, 3, 18, 24, - 10], - [25, 6, 4, 11, 17, 27, 18, 29, 1, 13, 2, 28, 10, 14, 5, 20, 12, 7, 21, 9, 16, 0, 3, 19, 8, 24, 26, 15, 22, - 23], - [12, 23, 14, 10, 0, 26, 16, 1, 6, 28, 17, 22, 4, 27, 25, 13, 5, 7, 11, 9, 19, 24, 18, 21, 15, 20, 8, 29, 3, - 2], - [8, 13, 22, 4, 14, 21, 23, 1, 9, 12, 2, 10, 17, 29, 15, 5, 24, 25, 27, 3, 19, 6, 28, 0, 20, 26, 16, 7, 18, - 11], - [10, 25, 22, 21, 29, 12, 14, 0, 13, 20, 28, 9, 24, 4, 6, 27, 16, 3, 7, 11, 8, 23, 5, 19, 2, 17, 15, 1, 26, - 18], - [28, 23, 21, 14, 27, 13, 15, 12, 4, 9, 25, 2, 0, 3, 10, 16, 22, 18, 11, 19, 8, 26, 6, 29, 1, 17, 20, 24, 7, - 5], - [11, 4, 13, 23, 26, 20, 0, 6, 3, 12, 15, 14, 19, 29, 25, 9, 16, 17, 2, 7, 28, 21, 5, 24, 18, 22, 8, 10, 1, - 27], - [3, 23, 19, 9, 12, 13, 24, 25, 15, 1, 4, 16, 22, 2, 28, 11, 5, 0, 14, 6, 26, 29, 7, 18, 8, 17, 20, 27, 10, - 21], - [5, 19, 15, 13, 10, 29, 0, 20, 9, 26, 21, 28, 11, 7, 18, 24, 4, 23, 14, 1, 22, 3, 16, 6, 17, 2, 27, 12, 8, - 25], - [6, 8, 9, 23, 25, 12, 2, 3, 7, 26, 29, 22, 1, 28, 17, 4, 18, 5, 14, 20, 24, 21, 16, 10, 13, 27, 19, 0, 15, - 11], - [15, 26, 18, 25, 1, 3, 23, 19, 28, 4, 16, 11, 6, 24, 21, 10, 12, 5, 0, 8, 13, 14, 9, 2, 22, 27, 20, 17, 29, - 7], - [14, 24, 28, 4, 20, 6, 19, 2, 3, 15, 10, 12, 17, 18, 9, 23, 7, 26, 11, 8, 1, 21, 16, 22, 25, 13, 29, 5, 27, - 0], - [11, 18, 28, 26, 24, 13, 4, 23, 10, 3, 12, 5, 29, 20, 0, 6, 14, 17, 21, 27, 8, 25, 16, 19, 7, 15, 22, 1, 2, - 9], - [9, 15, 12, 1, 27, 17, 26, 14, 10, 2, 21, 19, 5, 0, 3, 29, 11, 24, 4, 22, 16, 18, 23, 28, 8, 13, 25, 7, 6, - 20], - [13, 8, 23, 29, 26, 19, 27, 11, 7, 3, 28, 15, 12, 25, 9, 5, 6, 4, 14, 21, 10, 0, 18, 22, 2, 17, 16, 20, 24, - 1], - [23, 28, 13, 2, 14, 21, 29, 15, 0, 4, 12, 9, 26, 3, 1, 10, 6, 17, 5, 24, 7, 25, 19, 11, 20, 18, 22, 16, 27, - 8], - [21, 15, 28, 18, 4, 23, 12, 5, 13, 11, 6, 0, 1, 3, 19, 22, 17, 7, 25, 14, 20, 8, 29, 26, 16, 24, 10, 9, 2, - 27], - [5, 24, 10, 15, 6, 20, 27, 13, 23, 17, 11, 1, 28, 26, 29, 9, 18, 12, 4, 3, 14, 21, 22, 25, 8, 7, 0, 19, 2, - 16], - [14, 6, 18, 24, 11, 26, 21, 23, 10, 12, 2, 17, 13, 16, 4, 25, 28, 1, 27, 19, 15, 20, 9, 22, 7, 0, 3, 29, 8, - 5], - [29, 3, 21, 2, 12, 5, 4, 11, 10, 14, 26, 16, 6, 19, 18, 13, 25, 7, 20, 28, 15, 0, 27, 9, 24, 1, 8, 23, 17, - 22]] + [ + 4, + 11, + 1, + 2, + 12, + 25, + 9, + 6, + 29, + 0, + 28, + 13, + 5, + 8, + 21, + 23, + 22, + 14, + 20, + 16, + 15, + 7, + 26, + 27, + 17, + 19, + 3, + 18, + 24, + 10, + ], + [ + 25, + 6, + 4, + 11, + 17, + 27, + 18, + 29, + 1, + 13, + 2, + 28, + 10, + 14, + 5, + 20, + 12, + 7, + 21, + 9, + 16, + 0, + 3, + 19, + 8, + 24, + 26, + 15, + 22, + 23, + ], + [ + 12, + 23, + 14, + 10, + 0, + 26, + 16, + 1, + 6, + 28, + 17, + 22, + 4, + 27, + 25, + 13, + 5, + 7, + 11, + 9, + 19, + 24, + 18, + 21, + 15, + 20, + 8, + 29, + 3, + 2, + ], + [ + 8, + 13, + 22, + 4, + 14, + 21, + 23, + 1, + 9, + 12, + 2, + 10, + 17, + 29, + 15, + 5, + 24, + 25, + 27, + 3, + 19, + 6, + 28, + 0, + 20, + 26, + 16, + 7, + 18, + 11, + ], + [ + 10, + 25, + 22, + 21, + 29, + 12, + 14, + 0, + 13, + 20, + 28, + 9, + 24, + 4, + 6, + 27, + 16, + 3, + 7, + 11, + 8, + 23, + 5, + 19, + 2, + 17, + 15, + 1, + 26, + 18, + ], + [ + 28, + 23, + 21, + 14, + 27, + 13, + 15, + 12, + 4, + 9, + 25, + 2, + 0, + 3, + 10, + 16, + 22, + 18, + 11, + 19, + 8, + 26, + 6, + 29, + 1, + 17, + 20, + 24, + 7, + 5, + ], + [ + 11, + 4, + 13, + 23, + 26, + 20, + 0, + 6, + 3, + 12, + 15, + 14, + 19, + 29, + 25, + 9, + 16, + 17, + 2, + 7, + 28, + 21, + 5, + 24, + 18, + 22, + 8, + 10, + 1, + 27, + ], + [ + 3, + 23, + 19, + 9, + 12, + 13, + 24, + 25, + 15, + 1, + 4, + 16, + 22, + 2, + 28, + 11, + 5, + 0, + 14, + 6, + 26, + 29, + 7, + 18, + 8, + 17, + 20, + 27, + 10, + 21, + ], + [ + 5, + 19, + 15, + 13, + 10, + 29, + 0, + 20, + 9, + 26, + 21, + 28, + 11, + 7, + 18, + 24, + 4, + 23, + 14, + 1, + 22, + 3, + 16, + 6, + 17, + 2, + 27, + 12, + 8, + 25, + ], + [ + 6, + 8, + 9, + 23, + 25, + 12, + 2, + 3, + 7, + 26, + 29, + 22, + 1, + 28, + 17, + 4, + 18, + 5, + 14, + 20, + 24, + 21, + 16, + 10, + 13, + 27, + 19, + 0, + 15, + 11, + ], + [ + 15, + 26, + 18, + 25, + 1, + 3, + 23, + 19, + 28, + 4, + 16, + 11, + 6, + 24, + 21, + 10, + 12, + 5, + 0, + 8, + 13, + 14, + 9, + 2, + 22, + 27, + 20, + 17, + 29, + 7, + ], + [ + 14, + 24, + 28, + 4, + 20, + 6, + 19, + 2, + 3, + 15, + 10, + 12, + 17, + 18, + 9, + 23, + 7, + 26, + 11, + 8, + 1, + 21, + 16, + 22, + 25, + 13, + 29, + 5, + 27, + 0, + ], + [ + 11, + 18, + 28, + 26, + 24, + 13, + 4, + 23, + 10, + 3, + 12, + 5, + 29, + 20, + 0, + 6, + 14, + 17, + 21, + 27, + 8, + 25, + 16, + 19, + 7, + 15, + 22, + 1, + 2, + 9, + ], + [ + 9, + 15, + 12, + 1, + 27, + 17, + 26, + 14, + 10, + 2, + 21, + 19, + 5, + 0, + 3, + 29, + 11, + 24, + 4, + 22, + 16, + 18, + 23, + 28, + 8, + 13, + 25, + 7, + 6, + 20, + ], + [ + 13, + 8, + 23, + 29, + 26, + 19, + 27, + 11, + 7, + 3, + 28, + 15, + 12, + 25, + 9, + 5, + 6, + 4, + 14, + 21, + 10, + 0, + 18, + 22, + 2, + 17, + 16, + 20, + 24, + 1, + ], + [ + 23, + 28, + 13, + 2, + 14, + 21, + 29, + 15, + 0, + 4, + 12, + 9, + 26, + 3, + 1, + 10, + 6, + 17, + 5, + 24, + 7, + 25, + 19, + 11, + 20, + 18, + 22, + 16, + 27, + 8, + ], + [ + 21, + 15, + 28, + 18, + 4, + 23, + 12, + 5, + 13, + 11, + 6, + 0, + 1, + 3, + 19, + 22, + 17, + 7, + 25, + 14, + 20, + 8, + 29, + 26, + 16, + 24, + 10, + 9, + 2, + 27, + ], + [ + 5, + 24, + 10, + 15, + 6, + 20, + 27, + 13, + 23, + 17, + 11, + 1, + 28, + 26, + 29, + 9, + 18, + 12, + 4, + 3, + 14, + 21, + 22, + 25, + 8, + 7, + 0, + 19, + 2, + 16, + ], + [ + 14, + 6, + 18, + 24, + 11, + 26, + 21, + 23, + 10, + 12, + 2, + 17, + 13, + 16, + 4, + 25, + 28, + 1, + 27, + 19, + 15, + 20, + 9, + 22, + 7, + 0, + 3, + 29, + 8, + 5, + ], + [ + 29, + 3, + 21, + 2, + 12, + 5, + 4, + 11, + 10, + 14, + 26, + 16, + 6, + 19, + 18, + 13, + 25, + 7, + 20, + 28, + 15, + 0, + 27, + 9, + 24, + 1, + 8, + 23, + 17, + 22, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -810,10 +7005,18 @@ def test_optimum_ta50(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -821,48 +7024,809 @@ def test_optimum_ta50(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 1923) env.reset() self.assertEqual(env.current_time_step, 0) def test_optimum_ta51(self): - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta51'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta51" + }, + ) env.reset() self.assertEqual(env.current_time_step, 0) # for every machine give the jobs to process in order for every machine solution_sequence = [ - [37, 5, 24, 19, 41, 31, 17, 45, 4, 26, 34, 22, 0, 14, 8, 38, 44, 6, 32, 39, 15, 13, 35, 12, 33, 29, 9, 20, - 7, 10, 3, 16, 23, 28, 25, 48, 18, 43, 27, 21, 11, 30, 1, 47, 42, 36, 40, 46, 49, 2], - [14, 20, 1, 33, 45, 28, 9, 6, 5, 17, 18, 8, 42, 35, 3, 23, 0, 30, 44, 31, 16, 21, 38, 32, 41, 10, 34, 24, - 43, 22, 40, 29, 4, 26, 27, 48, 15, 25, 2, 47, 36, 12, 39, 46, 7, 11, 13, 49, 19, 37], - [28, 2, 34, 44, 5, 20, 8, 37, 18, 42, 14, 22, 41, 24, 12, 32, 49, 15, 40, 33, 10, 13, 26, 11, 19, 3, 9, 45, - 21, 1, 4, 16, 23, 35, 39, 47, 29, 6, 0, 36, 7, 38, 48, 31, 27, 46, 43, 17, 25, 30], - [5, 4, 28, 40, 41, 9, 0, 13, 14, 20, 34, 11, 46, 42, 12, 8, 37, 49, 23, 44, 24, 22, 32, 29, 48, 38, 2, 33, - 3, 18, 45, 36, 35, 15, 30, 19, 1, 31, 21, 6, 10, 27, 25, 26, 17, 7, 47, 43, 39, 16], - [15, 9, 47, 29, 20, 14, 34, 12, 5, 40, 49, 2, 23, 0, 37, 8, 10, 46, 18, 41, 11, 38, 3, 16, 7, 39, 33, 30, 4, - 35, 26, 44, 45, 24, 48, 1, 19, 21, 17, 31, 27, 25, 43, 42, 22, 28, 6, 32, 13, 36], - [4, 9, 44, 35, 37, 34, 0, 5, 14, 10, 42, 13, 40, 8, 39, 45, 21, 3, 11, 18, 46, 33, 32, 47, 27, 49, 41, 26, - 20, 22, 38, 2, 28, 7, 24, 31, 15, 29, 23, 30, 19, 36, 6, 25, 48, 1, 16, 12, 17, 43], - [5, 34, 49, 14, 6, 42, 39, 7, 26, 4, 43, 40, 10, 37, 38, 8, 9, 41, 12, 27, 45, 25, 15, 48, 30, 44, 0, 29, 2, - 11, 19, 23, 21, 13, 16, 33, 24, 17, 35, 3, 22, 46, 20, 18, 36, 31, 28, 32, 47, 1], - [46, 31, 9, 8, 35, 45, 34, 26, 4, 20, 0, 44, 21, 3, 13, 38, 18, 41, 14, 11, 22, 36, 27, 15, 25, 33, 1, 29, - 43, 40, 16, 32, 30, 10, 28, 7, 24, 47, 48, 6, 2, 23, 39, 49, 17, 5, 19, 42, 37, 12], - [29, 12, 35, 28, 20, 6, 0, 13, 10, 8, 34, 31, 24, 15, 32, 40, 45, 30, 14, 9, 2, 49, 41, 37, 38, 48, 11, 26, - 16, 1, 44, 36, 18, 3, 39, 46, 23, 42, 4, 43, 21, 22, 25, 19, 27, 17, 5, 7, 47, 33], - [10, 0, 45, 6, 17, 49, 46, 34, 23, 38, 44, 4, 11, 27, 37, 21, 31, 14, 18, 8, 12, 20, 40, 3, 33, 41, 9, 32, - 35, 48, 16, 1, 43, 39, 24, 15, 47, 36, 29, 5, 2, 28, 26, 42, 25, 22, 19, 30, 13, 7], - [16, 0, 6, 7, 46, 3, 14, 18, 41, 5, 8, 35, 32, 39, 43, 34, 37, 22, 4, 24, 13, 48, 12, 11, 45, 49, 2, 44, 40, - 9, 10, 29, 38, 31, 19, 27, 21, 17, 23, 33, 30, 25, 15, 28, 42, 47, 20, 36, 1, 26], - [34, 10, 7, 17, 45, 40, 2, 47, 26, 13, 9, 14, 15, 44, 4, 48, 19, 37, 42, 29, 49, 43, 41, 36, 22, 11, 32, 6, - 25, 8, 5, 28, 0, 20, 3, 38, 27, 1, 18, 33, 23, 31, 16, 30, 39, 24, 21, 35, 46, 12], - [9, 16, 29, 44, 17, 34, 28, 7, 12, 3, 20, 21, 41, 13, 0, 8, 46, 32, 4, 6, 37, 14, 36, 10, 15, 24, 38, 11, - 33, 26, 25, 48, 39, 1, 31, 42, 47, 27, 22, 30, 19, 45, 43, 23, 35, 2, 40, 5, 49, 18], - [6, 17, 2, 31, 25, 7, 36, 28, 47, 35, 5, 46, 20, 34, 18, 0, 14, 24, 15, 8, 42, 37, 13, 49, 41, 43, 12, 45, - 32, 9, 40, 33, 26, 38, 44, 16, 11, 3, 1, 4, 29, 21, 30, 27, 10, 48, 23, 22, 19, 39], - [7, 35, 37, 13, 34, 14, 42, 39, 5, 18, 40, 45, 8, 6, 23, 32, 2, 49, 9, 3, 43, 47, 25, 41, 22, 10, 11, 20, - 26, 16, 33, 4, 30, 44, 21, 1, 29, 27, 38, 12, 17, 46, 0, 24, 36, 19, 28, 15, 31, 48]] + [ + 37, + 5, + 24, + 19, + 41, + 31, + 17, + 45, + 4, + 26, + 34, + 22, + 0, + 14, + 8, + 38, + 44, + 6, + 32, + 39, + 15, + 13, + 35, + 12, + 33, + 29, + 9, + 20, + 7, + 10, + 3, + 16, + 23, + 28, + 25, + 48, + 18, + 43, + 27, + 21, + 11, + 30, + 1, + 47, + 42, + 36, + 40, + 46, + 49, + 2, + ], + [ + 14, + 20, + 1, + 33, + 45, + 28, + 9, + 6, + 5, + 17, + 18, + 8, + 42, + 35, + 3, + 23, + 0, + 30, + 44, + 31, + 16, + 21, + 38, + 32, + 41, + 10, + 34, + 24, + 43, + 22, + 40, + 29, + 4, + 26, + 27, + 48, + 15, + 25, + 2, + 47, + 36, + 12, + 39, + 46, + 7, + 11, + 13, + 49, + 19, + 37, + ], + [ + 28, + 2, + 34, + 44, + 5, + 20, + 8, + 37, + 18, + 42, + 14, + 22, + 41, + 24, + 12, + 32, + 49, + 15, + 40, + 33, + 10, + 13, + 26, + 11, + 19, + 3, + 9, + 45, + 21, + 1, + 4, + 16, + 23, + 35, + 39, + 47, + 29, + 6, + 0, + 36, + 7, + 38, + 48, + 31, + 27, + 46, + 43, + 17, + 25, + 30, + ], + [ + 5, + 4, + 28, + 40, + 41, + 9, + 0, + 13, + 14, + 20, + 34, + 11, + 46, + 42, + 12, + 8, + 37, + 49, + 23, + 44, + 24, + 22, + 32, + 29, + 48, + 38, + 2, + 33, + 3, + 18, + 45, + 36, + 35, + 15, + 30, + 19, + 1, + 31, + 21, + 6, + 10, + 27, + 25, + 26, + 17, + 7, + 47, + 43, + 39, + 16, + ], + [ + 15, + 9, + 47, + 29, + 20, + 14, + 34, + 12, + 5, + 40, + 49, + 2, + 23, + 0, + 37, + 8, + 10, + 46, + 18, + 41, + 11, + 38, + 3, + 16, + 7, + 39, + 33, + 30, + 4, + 35, + 26, + 44, + 45, + 24, + 48, + 1, + 19, + 21, + 17, + 31, + 27, + 25, + 43, + 42, + 22, + 28, + 6, + 32, + 13, + 36, + ], + [ + 4, + 9, + 44, + 35, + 37, + 34, + 0, + 5, + 14, + 10, + 42, + 13, + 40, + 8, + 39, + 45, + 21, + 3, + 11, + 18, + 46, + 33, + 32, + 47, + 27, + 49, + 41, + 26, + 20, + 22, + 38, + 2, + 28, + 7, + 24, + 31, + 15, + 29, + 23, + 30, + 19, + 36, + 6, + 25, + 48, + 1, + 16, + 12, + 17, + 43, + ], + [ + 5, + 34, + 49, + 14, + 6, + 42, + 39, + 7, + 26, + 4, + 43, + 40, + 10, + 37, + 38, + 8, + 9, + 41, + 12, + 27, + 45, + 25, + 15, + 48, + 30, + 44, + 0, + 29, + 2, + 11, + 19, + 23, + 21, + 13, + 16, + 33, + 24, + 17, + 35, + 3, + 22, + 46, + 20, + 18, + 36, + 31, + 28, + 32, + 47, + 1, + ], + [ + 46, + 31, + 9, + 8, + 35, + 45, + 34, + 26, + 4, + 20, + 0, + 44, + 21, + 3, + 13, + 38, + 18, + 41, + 14, + 11, + 22, + 36, + 27, + 15, + 25, + 33, + 1, + 29, + 43, + 40, + 16, + 32, + 30, + 10, + 28, + 7, + 24, + 47, + 48, + 6, + 2, + 23, + 39, + 49, + 17, + 5, + 19, + 42, + 37, + 12, + ], + [ + 29, + 12, + 35, + 28, + 20, + 6, + 0, + 13, + 10, + 8, + 34, + 31, + 24, + 15, + 32, + 40, + 45, + 30, + 14, + 9, + 2, + 49, + 41, + 37, + 38, + 48, + 11, + 26, + 16, + 1, + 44, + 36, + 18, + 3, + 39, + 46, + 23, + 42, + 4, + 43, + 21, + 22, + 25, + 19, + 27, + 17, + 5, + 7, + 47, + 33, + ], + [ + 10, + 0, + 45, + 6, + 17, + 49, + 46, + 34, + 23, + 38, + 44, + 4, + 11, + 27, + 37, + 21, + 31, + 14, + 18, + 8, + 12, + 20, + 40, + 3, + 33, + 41, + 9, + 32, + 35, + 48, + 16, + 1, + 43, + 39, + 24, + 15, + 47, + 36, + 29, + 5, + 2, + 28, + 26, + 42, + 25, + 22, + 19, + 30, + 13, + 7, + ], + [ + 16, + 0, + 6, + 7, + 46, + 3, + 14, + 18, + 41, + 5, + 8, + 35, + 32, + 39, + 43, + 34, + 37, + 22, + 4, + 24, + 13, + 48, + 12, + 11, + 45, + 49, + 2, + 44, + 40, + 9, + 10, + 29, + 38, + 31, + 19, + 27, + 21, + 17, + 23, + 33, + 30, + 25, + 15, + 28, + 42, + 47, + 20, + 36, + 1, + 26, + ], + [ + 34, + 10, + 7, + 17, + 45, + 40, + 2, + 47, + 26, + 13, + 9, + 14, + 15, + 44, + 4, + 48, + 19, + 37, + 42, + 29, + 49, + 43, + 41, + 36, + 22, + 11, + 32, + 6, + 25, + 8, + 5, + 28, + 0, + 20, + 3, + 38, + 27, + 1, + 18, + 33, + 23, + 31, + 16, + 30, + 39, + 24, + 21, + 35, + 46, + 12, + ], + [ + 9, + 16, + 29, + 44, + 17, + 34, + 28, + 7, + 12, + 3, + 20, + 21, + 41, + 13, + 0, + 8, + 46, + 32, + 4, + 6, + 37, + 14, + 36, + 10, + 15, + 24, + 38, + 11, + 33, + 26, + 25, + 48, + 39, + 1, + 31, + 42, + 47, + 27, + 22, + 30, + 19, + 45, + 43, + 23, + 35, + 2, + 40, + 5, + 49, + 18, + ], + [ + 6, + 17, + 2, + 31, + 25, + 7, + 36, + 28, + 47, + 35, + 5, + 46, + 20, + 34, + 18, + 0, + 14, + 24, + 15, + 8, + 42, + 37, + 13, + 49, + 41, + 43, + 12, + 45, + 32, + 9, + 40, + 33, + 26, + 38, + 44, + 16, + 11, + 3, + 1, + 4, + 29, + 21, + 30, + 27, + 10, + 48, + 23, + 22, + 19, + 39, + ], + [ + 7, + 35, + 37, + 13, + 34, + 14, + 42, + 39, + 5, + 18, + 40, + 45, + 8, + 6, + 23, + 32, + 2, + 49, + 9, + 3, + 43, + 47, + 25, + 41, + 22, + 10, + 11, + 20, + 26, + 16, + 33, + 4, + 30, + 44, + 21, + 1, + 29, + 27, + 38, + 12, + 17, + 46, + 0, + 24, + 36, + 19, + 28, + 15, + 31, + 48, + ], + ] done = False machine_nb = len(solution_sequence) job_nb = len(solution_sequence[0]) @@ -876,10 +7840,18 @@ def test_optimum_ta51(self): break if env.machine_legal[machine] and index_machine[machine] < job_nb: action_to_do = solution_sequence[machine][index_machine[machine]] - if env.needed_machine_jobs[action_to_do] == machine and env.legal_actions[action_to_do]: + if ( + env.needed_machine_jobs[action_to_do] == machine + and env.legal_actions[action_to_do] + ): no_op = False - self.assertTrue(env.legal_actions[action_to_do], "We don't perform illegal actions") - self.assertEqual(sum(env.legal_actions[:-1]), env.nb_legal_actions) + self.assertTrue( + env.legal_actions[action_to_do], + "We don't perform illegal actions", + ) + self.assertEqual( + sum(env.legal_actions[:-1]), env.nb_legal_actions + ) state, reward, done, _ = env.step(action_to_do) index_machine[machine] += 1 step_nb += 1 @@ -887,12 +7859,17 @@ def test_optimum_ta51(self): self.assertTrue(len(env.next_time_step) > 0, "step {}".format(step_nb)) previous_time_step = env.current_time_step state, reward, done, _ = env.step(env.jobs) - self.assertTrue(env.current_time_step > previous_time_step, "we increase the time step") - self.assertEqual(sum(index_machine), len(solution_sequence) * len(solution_sequence[0])) + self.assertTrue( + env.current_time_step > previous_time_step, + "we increase the time step", + ) + self.assertEqual( + sum(index_machine), len(solution_sequence) * len(solution_sequence[0]) + ) self.assertEqual(env.current_time_step, 2760) env.reset() self.assertEqual(env.current_time_step, 0) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_state.py b/tests/test_state.py index a8fcf6c..eef499b 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -1,12 +1,17 @@ import gym import unittest import numpy as np +from pathlib import Path class TestState(unittest.TestCase): - def test_random(self): - env = gym.make('JSSEnv:jss-v1', env_config={'instance_path': '../JSSEnv/envs/instances/ta80'}) + env = gym.make( + "jss-v1", + env_config={ + "instance_path": f"{str(Path(__file__).parent.absolute())}/../JSSEnv/envs/instances/ta01" + }, + ) average = 0 for _ in range(100): state = env.reset() @@ -14,27 +19,48 @@ def test_random(self): legal_actions = env.get_legal_actions() done = False total_reward = 0 - self.assertTrue(max(state['real_obs'].flatten()) <= 1.0, "Out of max bound state") - self.assertTrue(min(state['real_obs'].flatten()) >= 0.0, "Out of min bound state") - self.assertTrue(not np.isnan(state['real_obs']).any(), "NaN inside state rep!") - self.assertTrue(not np.isinf(state['real_obs']).any(), "Inf inside state rep!") + self.assertTrue( + max(state["real_obs"].flatten()) <= 1.0, "Out of max bound state" + ) + self.assertTrue( + min(state["real_obs"].flatten()) >= 0.0, "Out of min bound state" + ) + self.assertTrue( + not np.isnan(state["real_obs"]).any(), "NaN inside state rep!" + ) + self.assertTrue( + not np.isinf(state["real_obs"]).any(), "Inf inside state rep!" + ) machines_available = set() for job in range(len(env.legal_actions[:-1])): if env.legal_actions[job]: machine_needed = env.needed_machine_jobs[job] machines_available.add(machine_needed) - self.assertEqual(len(machines_available), env.nb_machine_legal, - "machine available and nb machine available are not coherant") + self.assertEqual( + len(machines_available), + env.nb_machine_legal, + "machine available and nb machine available are not coherant", + ) while not done: - actions = np.random.choice(len(legal_actions), 1, p=(legal_actions / legal_actions.sum()))[0] + actions = np.random.choice( + len(legal_actions), 1, p=(legal_actions / legal_actions.sum()) + )[0] assert legal_actions[:-1].sum() == env.nb_legal_actions state, rewards, done, _ = env.step(actions) legal_actions = env.get_legal_actions() total_reward += rewards - self.assertTrue(max(state['real_obs'].flatten()) <= 1.0, "Out of max bound state") - self.assertTrue(min(state['real_obs'].flatten()) >= 0.0, "Out of min bound state") - self.assertTrue(not np.isnan(state['real_obs']).any(), "NaN inside state rep!") - self.assertTrue(not np.isinf(state['real_obs']).any(), "Inf inside state rep!") + self.assertTrue( + max(state["real_obs"].flatten()) <= 1.0, "Out of max bound state" + ) + self.assertTrue( + min(state["real_obs"].flatten()) >= 0.0, "Out of min bound state" + ) + self.assertTrue( + not np.isnan(state["real_obs"]).any(), "NaN inside state rep!" + ) + self.assertTrue( + not np.isinf(state["real_obs"]).any(), "Inf inside state rep!" + ) machines_available = set() for job in range(len(env.legal_actions[:-1])): if env.legal_actions[job]: @@ -43,6 +69,8 @@ def test_random(self): assert len(machines_available) == env.nb_machine_legal average += env.last_time_step self.assertEqual(len(env.next_time_step), 0) - self.assertNotEqual(min(env.solution.flatten()), -1, np.array2string(env.solution.flatten())) + self.assertNotEqual( + min(env.solution.flatten()), -1, np.array2string(env.solution.flatten()) + ) for job in range(env.jobs): self.assertEqual(env.todo_time_step_job[job], env.machines)