Created
February 19, 2017 11:05
-
-
Save YaLTeR/8f844481444e0b0b89175593b4dd822f to your computer and use it in GitHub Desktop.
Elevator simulation, a university task. Written in Russian for fun.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from enum import Enum | |
import random | |
import simpy | |
ЛИФТ_ВРЕМЯ_ДВИЖЕНИЯ_ДВЕРЕЙ = 3 # секунды | |
ЛИФТ_СКОЛЬКО_ДВЕРИ_ОТКРЫТЫ = 6 # секунды | |
ЛИФТ_СЕКУНД_НА_ПЕРВЫЙ_И_ПОСЛЕДНИЙ_ЭТАЖ = 4 # секунды, время проезда первого и последнего этажа (больше из-за ускорения / замедления) | |
ЛИФТ_СЕКУНД_НА_ЭТАЖ = 4 # секунды, время проезда одного этажа | |
ЛИФТ_МАКСИМУМ_ПАССАЖИРОВ = 12 | |
ЧИСЛО_ЛИФТОВ = 3 | |
ЛИФТ_ПЕРВЫЙ_ЭТАЖ = 0 | |
ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ = 7 | |
номер_текущего_лифта = 0 | |
время_в_очереди = [] | |
время_до_цели = [] | |
class СостояниеЛифта(Enum): | |
СОН = 1 | |
ДВИЖЕНИЕ = 2 | |
ОТКРЫТИЕ_ДВЕРЕЙ = 3 | |
ОЖИДАНИЕ_ПАССАЖИРОВ = 4 | |
ЗАКРЫТИЕ_ДВЕРЕЙ = 5 | |
class Направление(Enum): | |
НЕТ = 0 | |
ВВЕРХ = 1 | |
ВНИЗ = -1 | |
@staticmethod | |
def из(откуда, куда): | |
if откуда == куда: | |
return Направление.НЕТ | |
elif откуда < куда: | |
return Направление.ВВЕРХ | |
else: | |
return Направление.ВНИЗ | |
class СтратегияБездействия(Enum): | |
ПРОСТАЯ = 0 | |
БАЗОВЫЙ_ЭТАЖ = 1 | |
class СтратегияНаправления(Enum): | |
ВМК = 0 | |
ВЕРХНИЙ_ПРИОРИТЕТ = 1 | |
НИЖНИЙ_ПРИОРИТЕТ = 2 | |
СТРАТЕГИЯ_БЕЗДЕЙСТВИЯ = СтратегияБездействия.БАЗОВЫЙ_ЭТАЖ | |
СТРАТЕГИЯ_НАПРАВЛЕНИЯ = СтратегияНаправления.НИЖНИЙ_ПРИОРИТЕТ | |
БАЗОВЫЙ_ЭТАЖ = 0 | |
def лог(секунды, строка): | |
часы = секунды / 3600 | |
секунды %= 3600 | |
минуты = секунды / 60 | |
секунды %= 60 | |
# print("[%02d:%02d:%02d] %s" % (часы, минуты, секунды, строка)) | |
def время_до_этажа(откуда, куда): | |
число_этажей = abs(куда - откуда) | |
if число_этажей <= 1: | |
return ЛИФТ_СЕКУНД_НА_ПЕРВЫЙ_И_ПОСЛЕДНИЙ_ЭТАЖ * число_этажей | |
else: | |
return 2 * ЛИФТ_СЕКУНД_НА_ПЕРВЫЙ_И_ПОСЛЕДНИЙ_ЭТАЖ + (число_этажей - 2) * ЛИФТ_СЕКУНД_НА_ЭТАЖ | |
class Пассажир(object): | |
def __init__(я, мой_этаж, нужный_этаж, время): | |
я.мой_этаж = мой_этаж | |
я.нужный_этаж = нужный_этаж | |
я.встал_в_очередь = время | |
def направление(я): | |
return Направление.из(я.мой_этаж, я.нужный_этаж) | |
class Лифт(object): | |
def __init__(я, окружение, контроллер, контроллер_пассажиров, номер): | |
я.окружение = окружение | |
я.действие = окружение.process(я.работа()) | |
я.контроллер = контроллер | |
я.контроллер_пассажиров = контроллер_пассажиров | |
я.номер = номер | |
я.состояние = СостояниеЛифта.СОН | |
я.новое_состояние = СостояниеЛифта.СОН | |
я.пассажиры = [] | |
я.кнопки = {этаж: False for этаж in range(ЛИФТ_ПЕРВЫЙ_ЭТАЖ, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1)} | |
я.направление = Направление.НЕТ | |
я.текущий_этаж = ЛИФТ_ПЕРВЫЙ_ЭТАЖ | |
я.начало_движения = True | |
def лог(я, строка): | |
лог(я.окружение.now, "Лифт %d, этаж %d: " % (я.номер, я.текущий_этаж) + строка) | |
def двери(я): | |
return я.окружение.timeout(ЛИФТ_ВРЕМЯ_ДВИЖЕНИЯ_ДВЕРЕЙ) | |
def открыть_двери(я): | |
я.лог("Открываем двери.") | |
я.состояние = СостояниеЛифта.ОТКРЫТИЕ_ДВЕРЕЙ | |
return я.двери() | |
def закрыть_двери(я): | |
я.лог("Закрываем двери.") | |
я.состояние = СостояниеЛифта.ЗАКРЫТИЕ_ДВЕРЕЙ | |
return я.двери() | |
def сон(я, время): | |
я.лог("Сон.") | |
я.состояние = СостояниеЛифта.СОН | |
return я.окружение.timeout(время) | |
def ожидать_пассажиров(я): | |
# я.лог("Посадка пассажиров.") | |
я.состояние = СостояниеЛифта.ОЖИДАНИЕ_ПАССАЖИРОВ | |
return я.окружение.timeout(ЛИФТ_СКОЛЬКО_ДВЕРИ_ОТКРЫТЫ) | |
def двигаться(я, время): | |
я.лог("Движение.") | |
я.состояние = СостояниеЛифта.ДВИЖЕНИЕ | |
return я.окружение.timeout(время) | |
def нажать_кнопки(я): | |
for э in range(ЛИФТ_ПЕРВЫЙ_ЭТАЖ, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1): | |
я.кнопки[э] = any(п.нужный_этаж == э for п in я.пассажиры) | |
def набрать_пассажиров(я): | |
if len(я.пассажиры) < ЛИФТ_МАКСИМУМ_ПАССАЖИРОВ: | |
пассажиры = [] | |
for п in я.контроллер_пассажиров.пассажиры[я.текущий_этаж]: | |
if len(я.пассажиры) < ЛИФТ_МАКСИМУМ_ПАССАЖИРОВ and (я.направление == Направление.НЕТ or п.направление() == я.направление): | |
я.пассажиры.append(п) | |
время_в_очереди.append(я.окружение.now - п.встал_в_очередь) | |
else: | |
пассажиры.append(п) | |
я.контроллер_пассажиров.пассажиры[я.текущий_этаж] = пассажиры | |
def куда_ехать(я): | |
# Проверяем следующий этаж на предмет кнопки для перехвата. | |
следующий_этаж = я.текущий_этаж + я.направление.value | |
кнопка = я.контроллер.кнопки_на_этажах[(следующий_этаж, я.направление)] | |
if кнопка.нажата and not кнопка.занята: | |
я.лог("Едем на %d этаж, перехватывая кнопку." % следующий_этаж) | |
кнопка.занята = True | |
кнопка.назначенный_лифт = я | |
return следующий_этаж | |
# Сначала проверяем, нажаты ли кнопки. | |
этажи_для_проверки = [] | |
if (я.направление == Направление.ВВЕРХ or СТРАТЕГИЯ_НАПРАВЛЕНИЯ == СтратегияНаправления.ВЕРХНИЙ_ПРИОРИТЕТ) and not СТРАТЕГИЯ_НАПРАВЛЕНИЯ == СтратегияНаправления.НИЖНИЙ_ПРИОРИТЕТ: | |
этажи_для_проверки.extend(range(я.текущий_этаж + 1, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1)) | |
этажи_для_проверки.extend(range(я.текущий_этаж - 1, ЛИФТ_ПЕРВЫЙ_ЭТАЖ - 1, -1)) | |
elif я.направление == Направление.ВНИЗ or СТРАТЕГИЯ_НАПРАВЛЕНИЯ == СтратегияНаправления.НИЖНИЙ_ПРИОРИТЕТ: | |
этажи_для_проверки.extend(range(я.текущий_этаж - 1, ЛИФТ_ПЕРВЫЙ_ЭТАЖ - 1, -1)) | |
этажи_для_проверки.extend(range(я.текущий_этаж + 1, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1)) | |
for этаж in этажи_для_проверки: | |
if я.кнопки[этаж]: | |
я.лог("Едем на %d этаж, так как нажата кнопка в лифте." % этаж) | |
return этаж | |
# Кнопки не нажаты. Проверим, нужно ли нам ехать к какой-то кнопке на этаже. | |
for этаж in этажи_для_проверки: | |
for направление in [Направление.ВВЕРХ, Направление.ВНИЗ]: | |
кнопка = я.контроллер.кнопки_на_этажах[(этаж, направление)] | |
if кнопка.нажата and not кнопка.занята and кнопка.назначенный_лифт == я: | |
if Направление.из(я.текущий_этаж, этаж) == я.направление and abs(я.текущий_этаж - этаж) == 1: | |
кнопка.занята = True | |
я.лог("Едем на %d этаж, так как нажата кнопка на этаже (занимаем)." % этаж) | |
else: | |
я.лог("Едем на %d этаж, так как нажата кнопка на этаже." % этаж) | |
return этаж | |
if СТРАТЕГИЯ_БЕЗДЕЙСТВИЯ == СтратегияБездействия.БАЗОВЫЙ_ЭТАЖ and я.текущий_этаж != БАЗОВЫЙ_ЭТАЖ: | |
я.лог("Едем на базовый этаж (%d)." % БАЗОВЫЙ_ЭТАЖ) | |
return БАЗОВЫЙ_ЭТАЖ | |
я.лог("Не нужно никуда ехать.") | |
return None | |
def нужно_открывать_двери(я): | |
if я.кнопки[я.текущий_этаж]: | |
return True | |
for направление in [Направление.ВВЕРХ, Направление.ВНИЗ]: | |
кнопка = я.контроллер.кнопки_на_этажах[(я.текущий_этаж, направление)] | |
if кнопка.нажата and кнопка.назначенный_лифт == я: | |
return True | |
return False | |
def обновить_направление(я): | |
этажи_для_проверки = [] | |
if (я.направление == Направление.ВВЕРХ or СТРАТЕГИЯ_НАПРАВЛЕНИЯ == СтратегияНаправления.ВЕРХНИЙ_ПРИОРИТЕТ) and not СТРАТЕГИЯ_НАПРАВЛЕНИЯ == СтратегияНаправления.НИЖНИЙ_ПРИОРИТЕТ: | |
этажи_для_проверки.extend(range(я.текущий_этаж + 1, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1)) | |
этажи_для_проверки.extend(range(я.текущий_этаж - 1, ЛИФТ_ПЕРВЫЙ_ЭТАЖ - 1, -1)) | |
elif я.направление == Направление.ВНИЗ or СТРАТЕГИЯ_НАПРАВЛЕНИЯ == СтратегияНаправления.НИЖНИЙ_ПРИОРИТЕТ: | |
этажи_для_проверки.extend(range(я.текущий_этаж - 1, ЛИФТ_ПЕРВЫЙ_ЭТАЖ - 1, -1)) | |
этажи_для_проверки.extend(range(я.текущий_этаж + 1, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1)) | |
for этаж in этажи_для_проверки: | |
if я.кнопки[этаж]: | |
я.направление = Направление.из(я.текущий_этаж, этаж) | |
я.лог("Направление после открытия дверей: %s, так как нажата кнопка в лифте." % я.направление.name) | |
return | |
# Если мы остановились на этаже, потому что там была нажата кнопка, нужно установить направление в направление кнопки. | |
for направление in [Направление.ВВЕРХ, Направление.ВНИЗ]: | |
кнопка = я.контроллер.кнопки_на_этажах[(я.текущий_этаж, направление)] | |
if кнопка.нажата and кнопка.назначенный_лифт == я: | |
я.направление = направление | |
я.лог("Направление после открытия дверей: %s, так как мы остановились на этаже, на котором нажата кнопка в этом направлении." % я.направление.name) | |
return | |
я.лог("Направление после открытия дверей отсутствует.") | |
я.направление = Направление.НЕТ | |
def обновить_направление_2(я): | |
# Вызывается сразу после закрытия дверей, чтобы понять, куда дальше ехать и нужно ли куда-то дальше ехать. | |
# Также вызывается котроллером при назначении лифта на кнопку, если лифт спит. | |
этажи_для_проверки = [] | |
if (я.направление == Направление.ВВЕРХ or СТРАТЕГИЯ_НАПРАВЛЕНИЯ == СтратегияНаправления.ВЕРХНИЙ_ПРИОРИТЕТ) and not СТРАТЕГИЯ_НАПРАВЛЕНИЯ == СтратегияНаправления.НИЖНИЙ_ПРИОРИТЕТ: | |
этажи_для_проверки.extend(range(я.текущий_этаж + 1, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1)) | |
этажи_для_проверки.extend(range(я.текущий_этаж - 1, ЛИФТ_ПЕРВЫЙ_ЭТАЖ - 1, -1)) | |
elif я.направление == Направление.ВНИЗ or СТРАТЕГИЯ_НАПРАВЛЕНИЯ == СтратегияНаправления.НИЖНИЙ_ПРИОРИТЕТ: | |
этажи_для_проверки.extend(range(я.текущий_этаж - 1, ЛИФТ_ПЕРВЫЙ_ЭТАЖ - 1, -1)) | |
этажи_для_проверки.extend(range(я.текущий_этаж + 1, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1)) | |
else: | |
этажи_1 = range(я.текущий_этаж + 1, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1) | |
этажи_2 = range(я.текущий_этаж - 1, ЛИФТ_ПЕРВЫЙ_ЭТАЖ - 1, -1) | |
этажи = [] | |
if len(этажи_1) > len(этажи_2): | |
этажи = этажи_1 | |
else: | |
этажи = этажи_2 | |
for i in range(0, min(len(этажи_1), len(этажи_2))): | |
этажи_для_проверки.append(этажи_1[i]) | |
этажи_для_проверки.append(этажи_2[i]) | |
for i in range(min(len(этажи_1), len(этажи_2)), max(len(этажи_1), len(этажи_2))): | |
этажи_для_проверки.append(этажи[i]) | |
for этаж in этажи_для_проверки: | |
if я.кнопки[этаж]: | |
я.направление = Направление.из(я.текущий_этаж, этаж) | |
return | |
# Если мы дошли досюда, то лифт пустой. | |
# Проверим кнопки на этажах. | |
этажи_для_проверки = [] | |
этажи_1 = range(я.текущий_этаж + 1, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1) | |
этажи_2 = range(я.текущий_этаж - 1, ЛИФТ_ПЕРВЫЙ_ЭТАЖ - 1, -1) | |
этажи = [] | |
if len(этажи_1) > len(этажи_2): | |
этажи = этажи_1 | |
else: | |
этажи = этажи_2 | |
for i in range(0, min(len(этажи_1), len(этажи_2))): | |
этажи_для_проверки.append(этажи_1[i]) | |
этажи_для_проверки.append(этажи_2[i]) | |
for i in range(min(len(этажи_1), len(этажи_2)), max(len(этажи_1), len(этажи_2))): | |
этажи_для_проверки.append(этажи[i]) | |
for этаж in этажи_для_проверки: | |
for направление in [Направление.ВВЕРХ, Направление.ВНИЗ]: | |
кнопка = я.контроллер.кнопки_на_этажах[(этаж, направление)] | |
if кнопка.нажата and not кнопка.занята and кнопка.назначенный_лифт == я: | |
я.направление = Направление.из(я.текущий_этаж, этаж) | |
return | |
# Лифт пустой и нажатых кнопок нет. | |
if СТРАТЕГИЯ_БЕЗДЕЙСТВИЯ == СтратегияБездействия.БАЗОВЫЙ_ЭТАЖ: | |
я.направление = Направление.из(я.текущий_этаж, БАЗОВЫЙ_ЭТАЖ) | |
else: | |
я.направление = Направление.НЕТ | |
def работа(я): | |
while True: | |
if я.состояние == СостояниеЛифта.ДВИЖЕНИЕ: | |
нужный_этаж = я.куда_ехать() | |
следующий_этаж = я.текущий_этаж + я.направление.value | |
время = ЛИФТ_СЕКУНД_НА_ЭТАЖ | |
if нужный_этаж is None or нужный_этаж == следующий_этаж or Направление.из(я.текущий_этаж, нужный_этаж) != я.направление: | |
# Если нам нужно остановиться на следующем этаже или развернуться. | |
время = ЛИФТ_СЕКУНД_НА_ПЕРВЫЙ_И_ПОСЛЕДНИЙ_ЭТАЖ | |
elif я.начало_движения: | |
# Просто начало движения. | |
время = ЛИФТ_СЕКУНД_НА_ПЕРВЫЙ_И_ПОСЛЕДНИЙ_ЭТАЖ | |
я.начало_движения = False | |
yield я.двигаться(время) | |
я.текущий_этаж = следующий_этаж | |
if нужный_этаж == я.текущий_этаж and я.нужно_открывать_двери(): | |
# Мы остановились на этаже либо потому что у нас была нажата кнопка этажа, либо потому что на этаже была нажата кнопка. | |
я.состояние = СостояниеЛифта.ОТКРЫТИЕ_ДВЕРЕЙ | |
я.кнопки[я.текущий_этаж] = False | |
я.обновить_направление() | |
elif нужный_этаж is None or нужный_этаж == я.текущий_этаж: | |
# Мы остановились либо из-за того, что у нас пропала цель (например, кнопку на этаже "взял" другой лифт), | |
# либо из-за того, что мы приехали к нужному этажу, где не надо открывать двери (например, если контроллер все лифты отправляет на первый этаж) | |
я.состояние = СостояниеЛифта.СОН | |
я.направление = Направление.НЕТ | |
else: | |
# Мы едем в направлении к нужному этажу. | |
я.направление = Направление.из(я.текущий_этаж, нужный_этаж) | |
elif я.состояние == СостояниеЛифта.ОТКРЫТИЕ_ДВЕРЕЙ: | |
yield я.открыть_двери() | |
я.состояние = СостояниеЛифта.ОЖИДАНИЕ_ПАССАЖИРОВ | |
elif я.состояние == СостояниеЛифта.ОЖИДАНИЕ_ПАССАЖИРОВ: | |
# Высадим пассажиров. | |
for п in я.пассажиры: | |
if п.нужный_этаж == я.текущий_этаж: | |
время_до_цели.append(я.окружение.now - п.встал_в_очередь) | |
я.пассажиры[:] = [п for п in я.пассажиры if п.нужный_этаж != я.текущий_этаж] | |
я.лог("Высадили пассажиров, осталось %d." % len(я.пассажиры)) | |
# Подождём новых. | |
yield я.ожидать_пассажиров() | |
я.набрать_пассажиров() | |
я.нажать_кнопки() | |
я.лог("Погрузили пассажиров, теперь их %d." % len(я.пассажиры)) | |
я.состояние = СостояниеЛифта.ЗАКРЫТИЕ_ДВЕРЕЙ | |
elif я.состояние == СостояниеЛифта.ЗАКРЫТИЕ_ДВЕРЕЙ: | |
yield я.закрыть_двери() | |
# Обновим состояние. | |
я.начало_движения = True | |
я.состояние = СостояниеЛифта.СОН | |
я.обновить_направление_2() | |
if я.направление != Направление.НЕТ: | |
я.состояние = СостояниеЛифта.ДВИЖЕНИЕ | |
# Отожмём нажатые кнопки. | |
кнопки = [] | |
if я.направление == Направление.НЕТ: | |
for направление in [Направление.ВВЕРХ, Направление.ВНИЗ]: | |
кнопка = я.контроллер.кнопки_на_этажах[(я.текущий_этаж, направление)] | |
if кнопка.нажата and кнопка.назначенный_лифт == я: | |
кнопки.append(кнопка) | |
else: | |
for направление in [Направление.ВВЕРХ, Направление.ВНИЗ]: | |
кнопка = я.контроллер.кнопки_на_этажах[(я.текущий_этаж, направление)] | |
if кнопка.нажата and кнопка.назначенный_лифт == я and (кнопка.занята or направление == я.направление): | |
кнопки.append(кнопка) | |
for кнопка in кнопки: | |
кнопка.нажата = False | |
кнопка.занята = False | |
кнопка.назначенный_лифт = None | |
elif я.состояние == СостояниеЛифта.СОН: | |
try: | |
yield я.сон(float('inf')) | |
except simpy.Interrupt as e: | |
continue | |
class КнопкаНаЭтаже(object): | |
def __init__(я): | |
я.нажата = False | |
я.занята = False | |
я.назначенный_лифт = None | |
class КонтроллерЛифтов(object): | |
def __init__(я, окружение, пассажиры): | |
global номер_текущего_лифта | |
я.окружение = окружение | |
я.лифты = [Лифт(окружение, я, пассажиры, номер_текущего_лифта + i) for i in range(0, ЧИСЛО_ЛИФТОВ)] | |
номер_текущего_лифта += ЧИСЛО_ЛИФТОВ | |
я.кнопки_на_этажах = {(этаж, направление): КнопкаНаЭтаже() for этаж in range(ЛИФТ_ПЕРВЫЙ_ЭТАЖ, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1) for направление in [Направление.ВНИЗ, Направление.ВВЕРХ]} | |
def лог(я, строка): | |
лог(я.окружение.now, "Контроллер лифтов: " + строка) | |
def нажать_кнопку(я, этаж, направление): | |
кнопка = я.кнопки_на_этажах[(этаж, направление)] | |
if кнопка.нажата: | |
return | |
я.лог("Нажата кнопка на %d этаже в направлении %s." % (этаж, направление)) | |
кнопка.нажата = True | |
# Назначаем лифт на эту кнопку. | |
лифт = None | |
расстояние = None | |
for спящий_лифт in я.лифты: | |
if спящий_лифт.состояние == СостояниеЛифта.СОН: | |
if not расстояние or расстояние > abs(спящий_лифт.текущий_этаж - этаж): | |
лифт = спящий_лифт | |
расстояние = abs(спящий_лифт.текущий_этаж - этаж) | |
if not лифт: | |
лифт = random.choice(я.лифты) | |
кнопка.назначенный_лифт = лифт | |
if лифт.состояние == СостояниеЛифта.СОН: | |
if лифт.текущий_этаж == этаж: | |
кнопка.занята = True | |
лифт.состояние = СостояниеЛифта.ОТКРЫТИЕ_ДВЕРЕЙ | |
лифт.действие.interrupt() | |
else: | |
лифт.обновить_направление_2() | |
лифт.состояние = СостояниеЛифта.ДВИЖЕНИЕ | |
лифт.действие.interrupt() | |
class КонтроллерПассажиров(object): | |
def __init__(я, окружение): | |
я.окружение = окружение | |
я.действие = окружение.process(я.работа()) | |
я.контроллеры = [] | |
я.пассажиры = {этаж: [] for этаж in range(ЛИФТ_ПЕРВЫЙ_ЭТАЖ, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1)} | |
def лог(я, строка): | |
лог(я.окружение.now, "Контроллер пассажиров: " + строка) | |
def добавить(я, где, куда): | |
я.лог("Добавляем пассажира на этаже %d, который едет на этаж %d." % (где, куда)) | |
пассажир = Пассажир(где, куда, я.окружение.now) | |
я.пассажиры[где].append(пассажир) | |
for контроллер in я.контроллеры: | |
контроллер.нажать_кнопку(где, пассажир.направление()) | |
def добавить_случайного(я): | |
где = random.randint(ЛИФТ_ПЕРВЫЙ_ЭТАЖ, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ) | |
куда = random.choice([этаж for этаж in range(ЛИФТ_ПЕРВЫЙ_ЭТАЖ, ЛИФТ_ПОСЛЕДНИЙ_ЭТАЖ + 1) if этаж != где]) | |
я.добавить(где, куда) | |
def работа(я): | |
yield я.окружение.timeout(1) | |
for этаж, пассажиры in я.пассажиры.items(): | |
for пассажир in пассажиры: | |
for контроллер in я.контроллеры: | |
контроллер.нажать_кнопку(этаж, пассажир.направление()) | |
def run_test(): | |
global время_в_очереди | |
время_в_очереди = [] | |
global время_до_цели | |
время_до_цели = [] | |
окружение = simpy.Environment() | |
пассажиры = КонтроллерПассажиров(окружение) | |
контроллеры = [КонтроллерЛифтов(окружение, пассажиры) for i in range(0, 2)] | |
пассажиры.контроллеры.extend(контроллеры) | |
окружение.run(until=1) | |
время = 1 | |
время_2 = 1 | |
# пассажиры.добавить_случайного() | |
# пассажиры.добавить_случайного() | |
# пассажиры.добавить_случайного() | |
# пассажиры.добавить_случайного() | |
# пассажиры.добавить_случайного() | |
# пассажиры.добавить_случайного() | |
# пассажиры.добавить_случайного() | |
# окружение.run(until=3600) | |
время += random.randint(30, 60) | |
время_2 += random.randint(5, 20) | |
while время < 3600 and время_2 < 3600: | |
if время < время_2: | |
окружение.run(until=время) | |
for i in range(0, random.randint(1, 3)): | |
пассажиры.добавить_случайного() | |
время += random.randint(30, 60) | |
elif время_2 < время: | |
окружение.run(until=время_2) | |
for i in range(0, random.randint(3, 6)): | |
где = 0 | |
куда = random.choice([1, 2, 3, 4, 5, 6, 7]) | |
пассажиры.добавить(где, куда) | |
время_2 += random.randint(5, 20) | |
else: | |
время += random.randint(30, 60) | |
время_2 += random.randint(5, 20) | |
while время < 15600: | |
окружение.run(until=время) | |
for i in range(0, random.randint(1, 3)): | |
пассажиры.добавить_случайного() | |
время += random.randint(30, 60) | |
время_2 = время + random.randint(5, 20) | |
while время < 18300 and время_2 < 18300: | |
if время < время_2: | |
окружение.run(until=время) | |
for i in range(0, random.randint(1, 3)): | |
пассажиры.добавить_случайного() | |
время += random.randint(30, 60) | |
elif время_2 < время: | |
окружение.run(until=время_2) | |
for i in range(0, random.randint(3, 6)): | |
if время_2 <= 1350: | |
где = random.choice([0, 1, 2, 3, 4, 5, 7]) | |
куда = 6 | |
else: | |
где = 6 | |
куда = random.choice([0, 1, 2, 3, 4, 5, 7]) | |
пассажиры.добавить(где, куда) | |
время_2 += random.randint(5, 20) | |
else: | |
время += random.randint(30, 60) | |
время_2 += random.randint(5, 20) | |
while время < 33000: | |
окружение.run(until=время) | |
for i in range(0, random.randint(1, 3)): | |
пассажиры.добавить_случайного() | |
время += random.randint(30, 60) | |
время_2 = время + random.randint(5, 20) | |
while время < 36600 and время_2 < 36600: | |
if время < время_2: | |
окружение.run(until=время) | |
for i in range(0, random.randint(1, 3)): | |
пассажиры.добавить_случайного() | |
время += random.randint(30, 60) | |
elif время_2 < время: | |
окружение.run(until=время_2) | |
for i in range(0, random.randint(3, 6)): | |
где = random.choice([1, 2, 3, 4, 5, 6, 7]) | |
куда = 0 | |
пассажиры.добавить(где, куда) | |
время_2 += random.randint(5, 20) | |
else: | |
время += random.randint(30, 60) | |
время_2 += random.randint(5, 20) | |
сумма = 0 | |
for i in время_в_очереди: | |
сумма += i | |
среднее_время_в_очереди = сумма / len(время_в_очереди) | |
сумма = 0 | |
for i in время_до_цели: | |
сумма += i | |
среднее_время_до_цели = сумма / len(время_до_цели) | |
print("Среднее время в очереди: " + str(среднее_время_в_очереди)) | |
print("Среднее время до цели: " + str(среднее_время_до_цели)) | |
return среднее_время_в_очереди, среднее_время_до_цели | |
сумма_очередь = 0 | |
сумма_цель = 0 | |
for i in range(0, 100): | |
очередь, цель = run_test() | |
сумма_очередь += очередь | |
сумма_цель += цель | |
print() | |
print("Среднее среднее время в очереди: " + str(сумма_очередь / 100)) | |
print("Среднее среднее время до цели: " + str(сумма_цель / 100)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment