Package: graph-jsp-env
Graph Job Shop Problem Gym EnvironmentAbout The ProjectAnGymnasium Environmentimplementation
of the Job Shop Scheduling Problem (JSP) using the disjunctive graph approach.Github:https://github.com/Alexander-Nasuta/graph-jsp-envPyPi:https://pypi.org/project/graph-jsp-env/This environment is inspired by theThe disjunctive graph machine representation of the job shop scheduling problemby Jacek Błażewicz andLearning to Dispatch for Job Shop Scheduling via Deep Reinforcement Learningby Zhang, Cong, et al.This environment does not explicitly include disjunctive edges, like specified by Jacek Błażewicz,
only conjunctive edges.
Additional information is saved in the edges and nodes, such that one could construct the disjunctive edges, so the is no loss in information.This environment is more similar to the Zhang, Cong, et al. implementation.
Zhang, Cong, et al. seems to store exclusively time-information exclusively inside nodes
(see Figure 2: Example of state transition) and no additional information inside the edges (like weights in the representation of Jacek Błażewicz).The DisjunctiveGraphJssEnv uses thenetworkxlibrary for graph structure and graph visualization.
It is highly configurable and offers various rendering options.Quick StartInstall the package with pip:pip install graph-jsp-envMinimal Working Example: Random ActionsThe code below shows a minimal working example without any reinforcement learningimportnumpyasnpfromgraph_jsp_env.disjunctive_graph_jsp_envimportDisjunctiveGraphJspEnvjsp=np.array([[[1,2,0],# job 0[0,2,1]],# job 1[[17,12,19],# task durations of job 0[8,6,2]]# task durations of job 1])env=DisjunctiveGraphJspEnv(jps_instance=jsp,perform_left_shift_if_possible=True,normalize_observation_space=True,# see documentation of DisjunctiveGraphJspEnv::get_state for more informationflat_observation_space=True,# see documentation of DisjunctiveGraphJspEnv::get_state for more informationaction_mode='task',# alternative 'job'dtype='float32'# dtype of the observation space)terminated=Falseinfo={}foriinrange(6):# get valid action mask. sample expects it to be a numpy array of type int8mask=np.array(env.valid_action_mask()).astype(np.int8)action=env.action_space.sample(mask=mask)state,reward,terminated,truncated,info=env.step(action)# chose the visualisation you want to see using the show parameter# console renderingenv.render(show=["gantt_console","graph_console"])print(f"makespan:{info['makespan']}")Stable Baselines3To run the example below you need to install the following packages:pip install stable_baselines3pip install sb3_contribIt is recommended to use theMaskablePPOalgorithm from thesb3_contribpackage.importgymnasiumasgymimportsb3_contribimportnumpyasnpimportstable_baselines3assb3fromgraph_jsp_env.disjunctive_graph_jsp_envimportDisjunctiveGraphJspEnvfromgraph_jsp_env.disjunctive_graph_loggerimportlogfromsb3_contrib.common.wrappersimportActionMaskerfromsb3_contrib.common.maskable.policiesimportMaskableActorCriticPolicyjsp=np.array([[[1,2,0],# job 0[0,2,1]],# job 1[[17,12,19],# task durations of job 0[8,6,2]]# task durations of job 1])env=DisjunctiveGraphJspEnv(jps_instance=jsp,perform_left_shift_if_possible=True,normalize_observation_space=True,flat_observation_space=True,action_mode='task',# alternative 'job')env=sb3.common.monitor.Monitor(env)defmask_fn(env:gym.Env)->np.ndarray:returnenv.valid_action_mask()env=ActionMasker(env,mask_fn)model=sb3_contrib.MaskablePPO(MaskableActorCriticPolicy,env,verbose=1)# Train the agentlog.info("training the model")model.learn(total_timesteps=10_000)VisualisationsThe environment offers multiple visualisation options.
There are four visualisations that can be mixed and matched:gantt_window: a gantt chart visualisation in a separate windowgraph_window: a graph visualisation in a separate window. This visualisation is computationally expensive.gantt_console: a gantt chart visualisation in the consolegraph_console: a graph visualisation in the consoleThe desired visualisation can be defaulted in the constructor of the environment with the argumentdefault_visualisations.
To enable all visualisation specifydefault_visualisations=["gantt_window", "gantt_console", "graph_window", "graph_console"].
The default visualisations are the used by therender()method if no visualisations are specified (using theshowargument).Visualisation in OpenCV WindowThis visualisation can enabled by settingrender_mode='window'or setting the argumentdefault_visualisations=["gantt_window", "graph_window"]in the constructor of the environment.
Additional parameters for OpencCV will be passed to thecv2.imshow()function.
Example:env.render(wait=1_000)# render window closes automatically after 1 secondsenv.render(wait=None)# render window closes when any button is pressed (when the render window is focused)Console VisualisationThis visualisation can enabled by settingrender_mode='window'or setting the argumentdefault_visualisations=["gantt_console", "graph_console"]in the constructor of the environment.More ExamplesVarious examples can be found in thegraph-jsp-examplesrepo.DevelopmentThe following sections are only relevant if you plan on further develop the environment and introduce code changes into
the environment itself.To run this Project locally on your machine follow the following steps:Clone the repogitclonehttps://github.com/Alexander-Nasuta/graph-jsp-env.gitInstall the python requirements_dev packages.requirements_dev.txtincludes all the packages of
specifiedrequirements.txtand some additional development packages likemypy,pytext,toxetc.pipinstall-rrequirements_dev.txtInstall the modules of the project locally. For more info have a look atJames Murphy's testing guidepipinstall-e.TestingFor testing make sure that the dev dependencies are installed (requirements_dev.txt) and the models of this
project are set up (i.e. you have runpip install -e .).Then you should be able to runmypysrcflake8srcpytestor everthing at once usingtox.toxIDEAI recommend to usePycharm.
Of course any code editor can be used instead (likeVS codeorVim).This section goes over a few recommended step for setting up the Project properly insidePycharm.PyCharm SetupMark thesrcdirectory asSource Root.right click on the 'src' -> 'Mark directory as' -> `Source Root`Mark theresourcesdirectory asResource Root.right click on the 'resources' -> 'Mark directory as' -> `Resource Root`Mark thetestsdirectory asTest Source Root.right click on the 'tests' -> 'Mark directory as' -> `Test Source Root`afterwards your project folder should be colored in the following way:(optional) When running a script enableEmulate terminal in output consoleRun (drop down) | Edit Configurations... | Configuration | ☑️ Emulate terminal in output consoleLicenseDistributed under the MIT License. SeeLICENSE.txtfor more information.