如何将以下随机元素添加到使用缓冲系统的多台计算机的模拟中?

发布于 2025-01-25 16:58:52 字数 7356 浏览 1 评论 0原文

我对要模拟的机器进行了模拟和分析,进一步走了几步。到目前为止,我被困在我知道如何进一步的一生中。

我决定在机器中添加随机元素。之前(请参见下面的代码)我有一个机器类,该类具有 faudy Repair 过程。我和我的教授已经决定,使用随机性将是对现实的更好代表。因此,我有以下元素要添加和解释该过程:

  1. 所有机器在状态1始于
  2. 每秒(tick)A 处理速度从可能性(%机会)
  3. a 状态中的时间是从分布(或random.choice()易用性的)
  4. 之后的 通过,新状态是从可能性(百分比)中选择
  5. 过程重复直到模拟时间结束。

由于在不同的状态下,因此没有更多的机器故障和维修过程。

我有一个想法,我将需要制作3个功能,以确定状态状态,速度时间 ,我不知道该怎么做。

每台机器的不同参数/可能性如下:

机器1

如果在状态1:

  • 可能的速度(刻度):{3:54%,4:24%,5:22%}
  • 持续时间:指数分布或random.choice()
  • 在持续时间之后的下一个状态:{0:41%,2:54%}

如果在状态2:

  • 可能的速度(ticks):{2:90%, 0:10%}
  • 持续时间:指数分布或random.choice()
  • 在持续时间之后的下一个状态:{0:60%,1:40%}

如果在状态0:

  • 可能的速度(ticks) :{0:100%}
  • 持续时间:指数分布或randy.choice()
  • 在持续时间之后可能的下一个状态:{1:100%}

Machine 2

如果在状态1:

  • 可能的速度(在刻度中):{5:42%,4:34%,7:24%}
  • 持续时间:指数分布或randy.choice()
  • 持续时间后可能的下一个状态:{0:70:70 %,2:30%}

如果在状态2:

  • 可能的速度(在刻度中):{1:80%,0:20%}
  • 持续时间:指数分布或randy.choice.choice()
  • 可能下一个状态持续时间:{0:90%,1:10%}

如果在状态0:

  • 可能的速度(ticks):{0:100%}
  • 持续时间:指数分发或randy.choice.choice()
  • 可能持续时间之后的下一个状态:{1:100%}

任何帮助都将不胜感激!

我现在添加了模拟的代码。我确实知道,由于现在需要失败和维修,因此有几个元素已经过时了,但我不确定如何更改它。

# Parameters for the Machines
# Machine 1
speed_1 = 0.1          # Avg. processing time of Machine 1 in minutes
# speed_1_stdev = 0.6  # St. dev. of processing time of Machine 1
MTTF_1 = 9          # Mean time to failure Machine 1
# fail_1 = 1/MTTF_1    # Parameter for exp. distribution
repair_1 = 5         # Time it takes to repair Machine 1

# Machine 2
speed_2 = 0.15         # Processing time of Machine 2 in minutes
# speed_2_stdev = 0.6  # St. dev. of processing time of Machine 2
MTTF_2 = 7           # Mean time to failure Machine 2
# fail_2 = 1/MTTF_2    # Parameter for exp. distribution
repair_2 = 3         # Time it takes to repair Machine 2


# Simulation time
time = 60           # Sim time in minutes

# Class setup for a Machine
class Machine(object):
    """
    A machine produces units at a fixed processing speed, 
    takes units from a store before and puts units into a store after.

    Machine has a *name*, a processing speed *speed*, a preceeding buffer *in_q*,
    and a proceeding buffer *out_q*.
    """
    def __init__(self, env, name, in_q, out_q, speed, mttf, repair):
        self.env = env
        self.name = name
        self.in_q = in_q
        self.out_q = out_q
        self.speed = speed
        self.mttf = mttf
        self.repair = repair
        self.broken = False
        self.count = 0

        # Start the producing process
        self.process = env.process(self.produce())
        # Start the failure process
        env.process(self.fail_machine())
    
    def produce(self):
        """
        Produce parts as long as the simulation runs. 
        It is prone to breaking down and being repaired.
        """
        
        while True:
            pspeed = self.speed  
            try:
                yield env.timeout(pspeed)
                if len(self.out_q.items) >= self.out_q.capacity:
                    pspeed = 0
                    print(f'{self.env.now:.2f}  {self.name} output buffer full!!!')
                    # Add the "Tailback" status to the event list
                    event_list.append({"Time": self.env.now, "Machine": self.name, 
                                       "State": "Tailback", "Speed": pspeed, 
                                       "Count": self.count, "Tailback": 1})
                else:
                    pspeed = self.speed
                    part = yield self.in_q.get()
                    yield self.out_q.put(part)
                    self.count += 1
                    # Add the "Running" status to the event list
                    event_list.append({"Time": self.env.now, "Machine": self.name, 
                                       "State": "Running", "Speed": pspeed, 
                                       "Count": self.count, "Tailback": 0})
            
            except simpy.Interrupt:  # This ensures that the machine breaks down
                self.broken = True
                pspeed = 0
                yield self.env.timeout(self.repair)
                print(f'{self.env.now:.2f} {self.name} is fixed')
                # Add the "Repaired" event notification to the event list
                event_list.append({"Time": self.env.now, "Machine": self.name, 
                                   "State": "Repaired", "Speed": pspeed, 
                                   "Count": self.count, "Tailback": 0})
                self.broken = False
                pspeed = self.speed
                env.process(self.fail_machine())
        
    def fail_machine(self):
        """
        The machine is prone to break down every now and then.
        """
        yield self.env.timeout(self.mttf)
        pspeed = 0
        print(f'{self.env.now:.2f} {self.name} is in failure.')
        # Add the "Failure" event notification to the event list
        event_list.append({"Time": self.env.now, "Machine": self.name, 
                           "State": "Failure", "Speed": pspeed, 
                           "Count": self.count, "Tailback": 0})
        if not self.broken:
            # Machine only fails if currently working.
            self.process.interrupt(self.mttf)

# Generating the arrival of parts in the entry buffer to be used by machine 1
def gen_arrivals(env, entry_buffer):
    """
    Start the process for each part by putting
    the part in the starting buffer
    """
    while True:
        yield env.timeout(random.uniform(0,0.0001))
        # print(f'{env.now:.2f} part has arrived')
        part = object() # Too lazy to make a real part class, also isn't necessary

        yield entry_buffer.put(part)

# Print the status of the number of processed parts per machine every minute
def print_status(env, machine, period):
    while True:
        yield env.timeout(period)
        print(f"{env.now}: {machine.name} has outputted {machine.count}")

# Create environment and start the setup process
env = simpy.Environment()
bufferStart = simpy.Store(env)  # Buffer with unlimited capacity
buffer1 = simpy.Store(env) # Buffer between machines with unlimited capacity
bufferEnd = simpy.Store(env)  # Last buffer with unlimited capacity

# The machines __init__ starts the machine process so no env.process() is needed here
machine_1 = Machine(env, 'Machine 1', bufferStart, buffer1, speed_1, MTTF_1, repair_1)
machine_2 = Machine(env, 'Machine 2', buffer1, bufferEnd, speed_2, MTTF_2, repair_2)


# Process necessary to run all events
env.process(gen_arrivals(env, bufferStart))
env.process(print_status(env, machine_1, 1))
env.process(print_status(env, machine_2, 1))

# Dictionary to log events
event_list = [{"Time": 0.00, "Machine": "All", 
               "State": "Simulation start", 
               "Speed": 0, "Count": 0, "Tailback": 0}]
# Execute
env.run(until = time)

I have gotten a few steps further along with my simulation and analysis of the machines that I want to simulate. As of now I am stuck and do not for the life of my know how to go further.

I have decided to add stochastic elements to my machine. Before (see code below) I had a Machine class that has produce, failure and repair process. My professor and I have decided that using stochasticity will be a better representation of reality. Therefore I have the following elements I would like to add and explanation of the process:

  1. All Machines starts in state 1
  2. Every second (tick) a processing speed is chosen from possibilities (% chance)
  3. Immediately a time in state is chosen from distribution (or random.choice() for ease of use)
  4. After the time in state has passed, a new state is chosen from possibilities (% chance)
  5. The process repeats until simulation time is over.

There is no more machine failure and repair process as this is taken up in the different states.

I have an idea that I will need to make 3 functions, for determining state, speed and time in state only I have no idea how to do this.

The different parameters/possibilities per machine are as follows:

Machine 1

If in state 1:

  • Possible speeds (in ticks): { 3: 54%, 4: 24%, 5 : 22% }
  • Duration: Exponential distribution or random.choice()
  • Possible next state after duration: { 0: 41%, 2: 54%}

If in state 2:

  • Possible speeds (in ticks): { 2: 90%, 0: 10% }
  • Duration: Exponential distribution or random.choice()
  • Possible next state after duration: { 0: 60%, 1: 40%}

If in state 0:

  • Possible speeds (in ticks): { 0: 100% }
  • Duration: Exponential distribution or random.choice()
  • Possible next state after duration: { 1: 100% }

Machine 2

If in state 1:

  • Possible speeds (in ticks): { 5: 42%, 4: 34%, 7 : 24% }
  • Duration: Exponential distribution or random.choice()
  • Possible next state after duration: { 0: 70%, 2: 30%}

If in state 2:

  • Possible speeds (in ticks): { 1: 80%, 0: 20% }
  • Duration: Exponential distribution or random.choice()
  • Possible next state after duration: { 0: 90%, 1: 10%}

If in state 0:

  • Possible speeds (in ticks): { 0: 100% }
  • Duration: Exponential distribution or random.choice()
  • Possible next state after duration: { 1: 100% }

Any help will be much much appreciated!

I am adding the code of my simulation as I have it now. I do know that a few elements are obsolete due to now needing to fail and repair anymore but I am not sure how to change it up.

# Parameters for the Machines
# Machine 1
speed_1 = 0.1          # Avg. processing time of Machine 1 in minutes
# speed_1_stdev = 0.6  # St. dev. of processing time of Machine 1
MTTF_1 = 9          # Mean time to failure Machine 1
# fail_1 = 1/MTTF_1    # Parameter for exp. distribution
repair_1 = 5         # Time it takes to repair Machine 1

# Machine 2
speed_2 = 0.15         # Processing time of Machine 2 in minutes
# speed_2_stdev = 0.6  # St. dev. of processing time of Machine 2
MTTF_2 = 7           # Mean time to failure Machine 2
# fail_2 = 1/MTTF_2    # Parameter for exp. distribution
repair_2 = 3         # Time it takes to repair Machine 2


# Simulation time
time = 60           # Sim time in minutes

# Class setup for a Machine
class Machine(object):
    """
    A machine produces units at a fixed processing speed, 
    takes units from a store before and puts units into a store after.

    Machine has a *name*, a processing speed *speed*, a preceeding buffer *in_q*,
    and a proceeding buffer *out_q*.
    """
    def __init__(self, env, name, in_q, out_q, speed, mttf, repair):
        self.env = env
        self.name = name
        self.in_q = in_q
        self.out_q = out_q
        self.speed = speed
        self.mttf = mttf
        self.repair = repair
        self.broken = False
        self.count = 0

        # Start the producing process
        self.process = env.process(self.produce())
        # Start the failure process
        env.process(self.fail_machine())
    
    def produce(self):
        """
        Produce parts as long as the simulation runs. 
        It is prone to breaking down and being repaired.
        """
        
        while True:
            pspeed = self.speed  
            try:
                yield env.timeout(pspeed)
                if len(self.out_q.items) >= self.out_q.capacity:
                    pspeed = 0
                    print(f'{self.env.now:.2f}  {self.name} output buffer full!!!')
                    # Add the "Tailback" status to the event list
                    event_list.append({"Time": self.env.now, "Machine": self.name, 
                                       "State": "Tailback", "Speed": pspeed, 
                                       "Count": self.count, "Tailback": 1})
                else:
                    pspeed = self.speed
                    part = yield self.in_q.get()
                    yield self.out_q.put(part)
                    self.count += 1
                    # Add the "Running" status to the event list
                    event_list.append({"Time": self.env.now, "Machine": self.name, 
                                       "State": "Running", "Speed": pspeed, 
                                       "Count": self.count, "Tailback": 0})
            
            except simpy.Interrupt:  # This ensures that the machine breaks down
                self.broken = True
                pspeed = 0
                yield self.env.timeout(self.repair)
                print(f'{self.env.now:.2f} {self.name} is fixed')
                # Add the "Repaired" event notification to the event list
                event_list.append({"Time": self.env.now, "Machine": self.name, 
                                   "State": "Repaired", "Speed": pspeed, 
                                   "Count": self.count, "Tailback": 0})
                self.broken = False
                pspeed = self.speed
                env.process(self.fail_machine())
        
    def fail_machine(self):
        """
        The machine is prone to break down every now and then.
        """
        yield self.env.timeout(self.mttf)
        pspeed = 0
        print(f'{self.env.now:.2f} {self.name} is in failure.')
        # Add the "Failure" event notification to the event list
        event_list.append({"Time": self.env.now, "Machine": self.name, 
                           "State": "Failure", "Speed": pspeed, 
                           "Count": self.count, "Tailback": 0})
        if not self.broken:
            # Machine only fails if currently working.
            self.process.interrupt(self.mttf)

# Generating the arrival of parts in the entry buffer to be used by machine 1
def gen_arrivals(env, entry_buffer):
    """
    Start the process for each part by putting
    the part in the starting buffer
    """
    while True:
        yield env.timeout(random.uniform(0,0.0001))
        # print(f'{env.now:.2f} part has arrived')
        part = object() # Too lazy to make a real part class, also isn't necessary

        yield entry_buffer.put(part)

# Print the status of the number of processed parts per machine every minute
def print_status(env, machine, period):
    while True:
        yield env.timeout(period)
        print(f"{env.now}: {machine.name} has outputted {machine.count}")

# Create environment and start the setup process
env = simpy.Environment()
bufferStart = simpy.Store(env)  # Buffer with unlimited capacity
buffer1 = simpy.Store(env) # Buffer between machines with unlimited capacity
bufferEnd = simpy.Store(env)  # Last buffer with unlimited capacity

# The machines __init__ starts the machine process so no env.process() is needed here
machine_1 = Machine(env, 'Machine 1', bufferStart, buffer1, speed_1, MTTF_1, repair_1)
machine_2 = Machine(env, 'Machine 2', buffer1, bufferEnd, speed_2, MTTF_2, repair_2)


# Process necessary to run all events
env.process(gen_arrivals(env, bufferStart))
env.process(print_status(env, machine_1, 1))
env.process(print_status(env, machine_2, 1))

# Dictionary to log events
event_list = [{"Time": 0.00, "Machine": "All", 
               "State": "Simulation start", 
               "Speed": 0, "Count": 0, "Tailback": 0}]
# Execute
env.run(until = time)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文