def normal_distribution(mu, sigma): stream = distributions.normal(mu, sigma) while True: value = stream.next() # Получение значения # И его обработка try: for function in postprocess: value = function(value) except: continue # Следующее значение yield value
def generate_normal_samples(n, params): try: assert len(params) == 2 u = float(params[0]) s = float(params[1]) assert s >= 0 except (ValueError, AssertionError): abort("invalid normal parameters") count = 0 while count < n: for x in normal(u, s): yield x count += 1
def kiosk(revenue_mean, damage_mean, damage_probability, sigma, revenue_min, revenue_max, times=1): # Потоки выручки revenue_streams = [] for shop in revenue_mean: revenue_streams.append([]) for mean in shop: revenue_streams[-1].append(limited_normal(mean, sigma * mean, mean * (1 + revenue_min * sigma), mean * (1 + revenue_max * sigma))) # Потоки случайных убытков damage_streams = tuple(normal(mean, sigma * mean) for mean in damage_mean) # А что если эти поток отрицательный результат дадут? # Сумматор прибыли по магазинам revenue_total = [0] * len(revenue_mean) # Сумматор квадратов прибыли revenue_squares = [0] * len(revenue_mean) # И раз, ещё раз, и ещё times, times раз... for _ in range(times): for shop, row in enumerate(revenue_streams): # Полная выручка revenue = sum(stream.next() for stream in row) # Случайный убыток if random() < damage_probability[shop]: damage = damage_streams[shop].next() revenue -= damage revenue_total[shop] += revenue revenue_squares[shop] += revenue * revenue # Считаем среднее значение income_mean = tuple(s / times for s in revenue_total) # Считаем среднеквадратическое отклонение income_sigma = tuple(sqrt((M - times * M2) / (times - 1)) for M, M2 in zip(revenue_total, revenue_squares)) # Квантиль K = 1.645 max_guaranteed_costs = tuple(mean - K * sigma for mean, sigma in zip(income_mean, income_sigma))
def distribution(field): 'Распределение' # Определим тип распределения types = ('exponential', 'equal', 'normal') # Допустимые типы try: t = field['type'] except: # Тип не указан t = types[0] else: if not (t in types): raise ValueError(u'Распределение %s неизвестно.' % t) if t == 'exponential': values = validate(field, piece(conditions, ('mean', ))) return distributions.exponential(values['mean']) elif t == 'equal': values = validate(field, piece(conditions, ('from', 'to'))) return distributions.equal(*values.values()) else: return distributions.normal(float(field['mean']))
def simulate(self): gain = 0 # [True] * self.technicals free_sellers = [0] * self.sellers free_technical = [0] * self.technicals free_specialized_technicals = [0] * self.specialized_technicals customers_waiting_sellers = Queue() customers_waiting_technicals = Queue() customers_waiting_specialized_technicals = Queue() client_time = 0 for _ in range(self.journal_duration): # Update client reach time if client_time > 0: client_time -= 1 else: client_time = poisson(20) customers_waiting_sellers.put(select_random_type()) if (customers_waiting_sellers.empty() and customers_waiting_specialized_technicals.empty() and customers_waiting_technicals.empty()): for i in range(len(free_sellers)): free_sellers[ i] = free_sellers[i] - 1 if free_sellers[i] > 0 else 0 for i in range(len(free_technical)): free_technical[i] = free_technical[ i] - 1 if free_technical[i] > 0 else 0 for i in range(len(free_specialized_technicals)): free_specialized_technicals[i] = free_specialized_technicals[i] - 1 \ if free_specialized_technicals[i] > 0 else 0 continue # Update specialized technicals details for i in range(len(free_specialized_technicals)): free_specialized_technicals[i] = free_specialized_technicals[i] - 1 \ if free_specialized_technicals[i] > 0 else 0 if not customers_waiting_specialized_technicals.empty(): for i in range(len(free_specialized_technicals)): if free_specialized_technicals[i] == 0: _ = customers_waiting_specialized_technicals.get() free_specialized_technicals[i] = int(exponential(15)) gain += 500 if customers_waiting_specialized_technicals.empty(): break # Update technicals details for i in range(len(free_technical)): free_technical[ i] = free_technical[i] - 1 if free_technical[i] > 0 else 0 if not customers_waiting_technicals.empty(): for i in range(len(free_technical)): if free_technical[i] == 0: client_type = customers_waiting_technicals.get() free_technical[i] = int(exponential(20)) gain += 0 if client_type == 1 else 350 if customers_waiting_technicals.empty(): break else: for i in range(len(free_specialized_technicals)): if free_specialized_technicals[i] == 0: client_type = customers_waiting_technicals.get() free_specialized_technicals[i] = int( exponential(15)) gain += 0 if client_type == 1 else 350 if customers_waiting_technicals.empty(): break # Update sellers details for i in range(len(free_sellers)): free_sellers[ i] = free_sellers[i] - 1 if free_sellers[i] > 0 else 0 if not customers_waiting_sellers.empty(): for i in range(len(free_sellers)): if free_sellers[i] == 0: client_type = customers_waiting_sellers.get() free_sellers[i] = int(abs(normal(5, 2))) if client_type == 4: gain += 750 else: if client_type == 1 or client_type == 2: customers_waiting_technicals.put(client_type) else: customers_waiting_specialized_technicals.put( client_type) if customers_waiting_sellers.empty(): break return gain
# Main # Lists Initialization uniform_values = np.zeros(iterations) normal_values = np.zeros(iterations) exponential_values = np.zeros(iterations) gamma_values = np.zeros(iterations) binomial_values = np.zeros(iterations) pascal_values = np.zeros(iterations) hypergeometric_values = np.zeros(iterations) poisson_values = np.zeros(iterations) empirical_values = np.zeros(iterations) # Distributions Generation for i in range(iterations): uniform_values[i] = uniform(a, b) normal_values[i] = normal(m, d) exponential_values[i] = exponential(1 / alpha_exp) gamma_values[i] = gamma(k_gamma, alpha_gamma) binomial_values[i] = binomial(n_binomial, p_binomial) pascal_values[i] = pascal(k_pascal, p_pascal) hypergeometric_values[i] = hypergeometric(N_hyper, n_hyper, p_hyper) poisson_values[i] = poisson(L) empirical_values[i] = empirical() print(iterations, "pseudorandom numbers generated of each distribution\n") # Statistics Parameter Tests print("//////////// STATISTICS PARAMETERS TESTS ////////////\n") print('-----UNIFORM DISTRIBUTION------') # print(uniform_values)
def producer(in_stream, mu, sigma, price, cost, total_time): u'Производственная фирма' # Генераторы событий work = [distributions.normal(mean, mean * sigma) for mean in mu] # Технологическая цепочка chain = [[] for mean in mu] ENVIRONMENT = -1 # Новая заявка def event_stream(): 'Поток событий' timer = distributions.exponential(in_stream) # Время появления следующей заявки next_order = next(timer) while True: time, source = next_order, ENVIRONMENT for link, queue in enumerate(chain): if queue and queue[0] < time: time, source = queue[0], link if source == ENVIRONMENT: next_order += next(timer) # Если закончилось время, выходим if time >= total_time: return # Иначе возвращаем результат yield (time, source) def process(time, source): 'Переход заявки в следующее звено технологической цепи' # Обработка канала-источника if source > ENVIRONMENT: chain[source].pop(0) if chain[source]: duration = next(work[source]) chain[source][0] = time + duration # Обработка канала-приёмника dest = source + 1 if dest < len(chain): chain[dest].append(time) if len(chain[dest]) == 1: duration = next(work[dest]) chain[dest][0] += duration else: orders['processed'] += 1 orders = {'processed' : 0} events = event_stream() # Основной цикл for event in events: process(*event) # Статистика заявок orders['rejected'] = sum(map(len, chain)) orders['total'] = sum(orders.values()) return { 'factor' : round((max(mu) - min(mu)) / (sum(mu) / len(mu)), 3), 'profit' : round(orders['processed'] * price - cost, 2), 'orders' : orders, }
def landing_time(): return normal(10, 5)
def takeoff_time(): return normal(10, 5)