作业车间问题的简单模拟,使用并行资源

问题描述

我正在尝试使用 simpy 模块 (https://simpy.readthedocs.io/en/latest/index.html) 编程和模拟作业车间问题。最后我想用强化学习来优化这个问题。但是,我的问题是当我尝试模拟创建的序列(尚未由代理生成)时,simpy 对所有资源(机器)使用时间。我曾想过将带有while循环的各个操作传递给simpy的超时事件,然后进行模拟。但是,它不起作用。有人能帮我吗?到目前为止,这是我的代码

15 15
6 94 12 66  4 10  7 53  3 26  2 15 10 65 11 82  8 10 14 27  9 93 13 92  5 96  0 70  1 83 
4 74  5 31  7 88 14 51 13 57  8 78 11  8  9  7  6 91 10 79  0 18  3 51 12 18  1 99  2 33 
1  4  8 82  9 40 12 86  6 50 11 54 13 21  5  6  0 54  2 68  7 82 10 20  4 39  3 35 14 68 
5 73  2 23  9 30  6 30 10 53  0 94 13 58  4 93  7 32 14 91 11 30  8 56 12 27  1 92  3  9 
7 78  8 23  6 21 10 60  4 36  9 29  2 95 14 99 12 79  5 76  1 93 13 42 11 52  0 42  3 96 
5 29  3 61 12 88 13 70 11 16  4 31 14 65  7 83  2 78  1 26 10 50  0 87  9 62  6 14  8 30 
12 18  3 75  7 20  8  4 14 91  6 68  1 19 11 54  4 85  5 73  2 43 10 24  0 37 13 87  9 66 
11 32  5 52  0  9  7 49 12 61 13 35 14 99  1 62  2  6  8 62  4  7  3 80  9  3  6 57 10  7 
10 85 11 30  6 96 14 91  0 13  1 87  2 82  5 83 12 78  4 56  8 85  7  8  9 66 13 88  3 15 
6  5 11 59  9 30  2 60  8 41  0 17 13 66  3 89 10 78  7 88  1 69 12 45 14 82  4  6  5 13 
4 90  7 27 13  1  0  8  5 91 12 80  6 89  8 49 14 32 10 28  3 90  1 93 11  6  9 35  2 73 
2 47 14 43  0 75 12  8  6 51 10  3  7 84  5 34  8 28  9 60 13 69  1 45  3 67 11 58  4 87 
5 65  8 62 10 97  2 20  3 31  6 33  9 33  0 77 13 50  4 80  1 48 11 90 12 75  7 96 14 44 
8 28 14 21  4 51 13 75  5 17  6 89  9 59  1 56 12 63  7 18 11 17 10 30  3 16  2  7  0 35 
10 57  8 16 12 42  6 34  4 37  1 26 13 68 14 73 11  5  0  8  7 12  3 87  2 83  9 20  5 97 
import gym
import simpy
from simpy.events import AnyOf,AllOf,Event
import random
import numpy as np


class JobShop_RL(gym.Env):

   def __init__(self):
       # Reading the Dataset for the JSP
       with open("taillard.txt","r") as self.data:
           self.read_data = self.data.readline()
           self.line = self.read_data.split()
           # Getting number of Jobs and Machines
           self.jobs = int(self.line[0])
           self.machines = int(self.line[1])
           self.all_jobs = np.zeros((self.jobs,self.machines),dtype=(int,2))
           # Filling Matrix  with (jobs/number) = (machine/time)
           self.line = self.data.readline()
           job = 0
           self.max_time = 0  # Max time
           self.sum_time = 0  # Sum of the whole time
           self.jobs_duration = np.zeros(self.machines,dtype=int)  # Sum of time for each job

           i = 0
           j = 0

           while job < self.jobs:
               self.line = self.line.split()
               while i <= ((self.jobs + self.machines) - 1):
                   self.all_jobs[job][j] = int(self.line[i]),int(self.line[i + 1])
                   self.jobs_duration[job] += int(self.line[i + 1])
                   self.max_time = max(self.max_time,int(self.line[i + 1]))
                   self.sum_time += int(self.line[i + 1])
                   j += 1
                   i += 2

               self.line = self.data.readline()
               job += 1
               i = 0
               j = 0

       # possible legal actions + the same number for no op for each machine
       # e. g. 15x15 Jssp = 15 legal moves and also 15 no op
       self.action_space = gym.spaces.discrete(self.machines+self.machines)
       # observation space
       self.observation_space = gym.spaces.Box

       # jobs_done = last stage,storing all jobs which are done
       self.jobs_done = []
       # last jobs = represents jobs the last jobs ( = nb of machines) which are done
       #self.last_jobs = np.zeros(self.jobs,2))
       # last jobs = represents jobs the last jobs ( = nb of machines) which are done
       self.possible_actions = np.zeros(self.jobs,2))
       i = 0
       while i < self.machines:
           self.possible_actions[i] = self.all_jobs[i][0]
           i += 1
       #
       self.counting = np.zeros(self.machines)

       # final order of the job shop problem
       self.final_order = np.zeros_like(self.all_jobs)

       self.simpy_env = simpy.Environment()
       # Store the simpy resources (machines) in the list
       self.machines_sy = []
       i = 0
       while i <= self.machines:
           self.machines_sy.append(simpy.Resource(self.simpy_env,capacity=1))
           i += 1

   def get_operation_index(self,action):
       index_machine = action // self.jobs
       index_operation = action % self.jobs
       #print("INDEX",index_operation,index_machine,self.all_jobs[index_operation][index_machine])
       # Returns the Indizes of the action,[Machine][Operation]
       return index_operation,index_machine

   def get_machine(self,action):
       nb_machine = self.all_jobs[self.get_operation_index(action)]
       return nb_machine[0]

   def machine_process(self,simpy_env,action):
       #Request and timeout the action for each incoming action (if machine is busy its going in the queue)
       machine = self.get_machine(action)
       print("ACTION IN MACHINE PROCESS",action)
       #operation = self.possible_actions[action]
       #operation = self.final_order[machine][int(self.counting[action])]
       #print("OPERATION",operation)

       i = 0
       j = 0

       while i < self.machines:
           while j < self.jobs:
               operation = self.final_order[i][j]
               with self.machines_sy[operation[0]].request() as req:
                   yield req
                   print("Machine ",i," proceed Operation ",self.final_order[i][j]," at ",simpy_env.Now)
                   self.jobs_done.append(self.final_order[machine][int(self.counting[action])])
                   yield simpy_env.timeout(operation[1])  # Operation[1] defines the processing time
                   print("Machine "," released Operation ",simpy_env.Now)
               j += 1
           if j == 15:
               i += 1
               j = 0


   def is_done(self):
       # Returns True if len(jobs_done) is the same as the sum of operations which need to be done
       # ### Die Anzahl an no ops muss beachtet werden
       if len(self.jobs_done) == self.all_jobs.shape[1]*self.all_jobs.shape[0]:
           return True
       else:
           return False

   def take_action(self,action):
       nb_machine = self.possible_actions[action]
       nb_machine = nb_machine[0]

       self.simpy_env.process(env.machine_process(env.simpy_env,action))
       machine = self.get_machine(action)

       # Filling Final Order
       tmp = np.count_nonzero(self.final_order[nb_machine]) // 2
       self.final_order[nb_machine][tmp] = self.possible_actions[action]

       # Update possible actions
       self.possible_action(action)

   def possible_action(self,action):
       self.counting[action] += 1
       self.possible_actions[action] = self.all_jobs[action][int(self.counting[action])]

   def step(self,action):
       reward = 0
       operation = self.get_operation_index(action)


       if action <= self.machines:
           print("##STEP## norMALE ACTION",action,self.possible_actions[action])
           self.take_action(action)

           reward = 10
       elif self.machines < action <= self.action_space.n:
           print("NOOP",action)
           reward = -3

       #Check if done
       done = self.is_done()
       #Info is unused
       info = {}

       return reward,done,info

   def reset(self):
       pass

   def render(self,mode='human'):
       pass


if __name__ == "__main__":
   env = JobShop_RL()
   print(env.possible_actions)

   env.step(0)
   print("****## NEXT ##***")
   env.step(1)
   print("****## NEXT ##***")
   env.step(2)
   print("****## NEXT ##***")

   env.simpy_env.run(1000)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)