Добавление атрибутов к сгенерированному объекту?

Я определил генератор, который генерирует коэффициенты прихода Пуассона в систему. Я хочу, чтобы каждое сгенерированное прибытие (клиент) имело случайное (x, y), которое показывает местоположение прибывшего клиента в системе. то есть я хочу сгенерировать скорость поступления Пуассона в систему, где каждое прибытие происходит из случайного места. Предположим, что x находится в диапазоне 50, а y — в диапазоне 60.

Как я могу добавить это в следующий код?

class Arrival(object):

    def __init__(self, stream_defin, referrer):
        self.service = stream_defin["service"]
        self.arrival_rate = stream_defin["rate"]
        self.referrer = referrer

    def sim_init(self, env,sim_stats):
        self.sim_stats = sim_stats
        self.env = env
        self.env.process(self.sim_arrival_generator())

    def sim_arrival_generator(self):
            i = 0
            while True:
                interarrival = spstats.expon(scale=1/self.arrival_rate).rvs()
                yield self.env.timeout(interarrival)
                i+=1

person shirin elahi    schedule 19.09.2020    source источник
comment
Где остальная часть кода? Что здесь представляет собой приход? Если interarrival - это прибытие, о котором вы говорите, почему бы просто не сделать это словарем, назначить задержку, которую вы вычисляете, ключу delay, а затем также вычислить два случайных значения для ключей x и y в словаре, чтобы представить случайное местоположение.   -  person CryptoFool    schedule 19.09.2020
comment
Спасибо Стив за ответ. Это длинный код, в котором я пытаюсь имитировать прибытия и услуги в компании. Есть ли лучший способ имитировать поступления Пуассона в систему и добавлять атрибуты к каждому отдельному приходу в систему? –   -  person shirin elahi    schedule 19.09.2020
comment
Лучший способ, чем что? Вы ничего не показываете здесь.   -  person CryptoFool    schedule 19.09.2020
comment
Если бы вы хотели смоделировать пуассоновское вступление в систему, где каждое вступление имеет (x, y), как бы вы это сделали?   -  person shirin elahi    schedule 19.09.2020
comment
Я все еще не знаю, чего ты хочешь, но позволь мне попробовать. Поскольку в комментарии сложно вставлять код, я продолжу и напишу ответ. Если это не то, что вы ищете, я продолжу работу над этим или удалю его...   -  person CryptoFool    schedule 20.09.2020


Ответы (1)


Ваш код ссылается на ряд объектов и методов, для которых вы не предоставляете определения. Это затрудняет точное определение того, что вы ищете. Кроме того, я не уверен, что даже понимаю, что вы хотите концептуально. Но если я возьму простейшую интерпретацию того, о чем вы просите, вот что я бы предложил:

Я предполагаю, что эта строка в настоящее время создает прибытие, на которое ссылается переменная interarrival:

interarrival = spstats.expon(scale=1/self.arrival_rate).rvs()

Это значение, по-видимому, в настоящее время является значением задержки, так что шаблон последовательных задержек покрывает шаблон распределения Пуассона. Вместо просто значения времени вы хотите, чтобы в этот момент в вашем коде создавалась задержка вместе со случайным положением, заданным координатами x и y, и чтобы они вместе представляли прибытие.

Я бы предложил создать объект словаря Python для представления каждого прибытия. Вот как вы можете это сделать:

interarrival = {
    'delay': spstats.expon(scale=1 / self.arrival_rate).rvs(),
    'position': {
        'x': random.randint(self.min_x, self.max_x),
        'y': random.randint(self.min_y, self.max_y)
    }
}

Выполнение кучи кода в ответе — это не то, что С.О. действительно о чем-то, но вы застали меня в момент скуки, и я ненавижу предоставлять код, который я на самом деле не запускал, так что...

Я позволил себе много вольностей и заполнил ваш код так, чтобы он действительно запускался и что-то делал, хотя все, что он делает, — это задержка между поступлениями и вывод значения каждого поступления по мере его поступления. Я предположил, что вы хотите увидеть реальную задержку из-за вашего вызова self.env.timeout и потому, что ваш генератор никогда не прекращает генерировать прибытия. Без задержки или длительной обработки этот код быстро выдал бы тысячи поступлений, которые вы не смогли бы прочитать.

Я переименовал ваш класс с Arrival на Arrivals, потому что код внутри имеет дело с потоком прибытий, а не с одним прибытием, и я не мог придумать хороший способ изменить это, не внося еще много изменений. Я пытался в основном добавить код и как можно меньше изменить предоставленный вами код. Имея все это в виду, вот что я придумал:

import scipy.stats as spstats
import random
import json
import time

class Arrivals(object):

    def __init__(self, stream_defin, referrer):
        self.service = stream_defin["service"]
        self.arrival_rate = stream_defin["rate"]
        self.min_x, self.max_x = stream_defin["min_x"], stream_defin["max_x"]
        self.min_y, self.max_y = stream_defin["min_y"], stream_defin["max_y"]
        self.referrer = referrer

    def sim_init(self, env, sim_stats):
        self.sim_stats = sim_stats
        self.env = env
        self.env.process(self.sim_arrival_generator())
        return self

    def sim_arrival_generator(self):
            i = 0
            while True:
                interarrival = {
                    'index': i,
                    'delay': spstats.expon(scale=1 / self.arrival_rate).rvs(),
                    'position': {
                        'x': random.randint(self.min_x, self.max_x),
                        'y': random.randint(self.min_y, self.max_y)
                    }
                }
                yield self.env.timeout(interarrival)
                i += 1

class Env():
    def process(self, arrivals):
        for arrival in arrivals:
            # Do whatever needs to be done with each arrival
            print('Processing arrival: ')
            print(json.dumps(arrival, indent=4))

    def timeout(self, arrival):
        # Delay the arrival by its delay time before delivering for processing
        print("Delaying %2.2f seconds..." % (arrival['delay']))
        time.sleep(arrival['delay'])
        return arrival

def main():

    stream_defin = {
        'service': 'service',

        'rate': 0.5,

        'min_x': 5,
        'max_x': 50,
        'min_y': 10,
        'max_y': 60
    }

    stats = [] # a place to collect results, I assume
    Arrivals(stream_defin, 'referrer').sim_init(Env(), stats)

main()

Эта штука работает вечно, поэтому вам нужно нажать CTRL-C, чтобы остановить ее. Было бы легко добавить значение конфигурации iterations, чтобы ограничить количество итераций. Вы можете либо добавить это к самому генератору, либо просто выйти из метода process(), когда будет достигнуто указанное количество итераций.

Пример результатов (с фактическими задержками вывода, как указано):

Delaying 5.39 seconds...
Processing arrival: 
{
    "index": 0,
    "delay": 5.394974068076859,
    "position": {
        "x": 34,
        "y": 29
    }
}
Delaying 1.51 seconds...
Processing arrival: 
{
    "index": 1,
    "delay": 1.5095025601339542,
    "position": {
        "x": 24,
        "y": 24
    }
}
Delaying 1.48 seconds...
Processing arrival: 
{
    "index": 2,
    "delay": 1.4840036046166114,
    "position": {
        "x": 28,
        "y": 57
    }
}
Delaying 4.09 seconds...
Processing arrival: 
{
    "index": 3,
    "delay": 4.08649062133332,
    "position": {
        "x": 37,
        "y": 14
    }
}
...
person CryptoFool    schedule 19.09.2020
comment
Большое спасибо, Стив, за вашу помощь, я очень ценю это, и мне жаль, если я не смог разместить весь код, поскольку у меня нет на это разрешения. - person shirin elahi; 20.09.2020