Created
May 30, 2018 21:53
-
-
Save ripiuk/372bb7d19c0f574b3ef0a970c04008cd to your computer and use it in GitHub Desktop.
Get probability using triangle distribution, trapezoidal distribution or triangle from trapeze distribution
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 math import sqrt | |
from random import uniform | |
from decimal import Decimal | |
c_min = 20 | |
c_max = 125 | |
max_count = 1000000 | |
c1 = 145 | |
c2 = 70 | |
c3 = 80 | |
class VerifyError(Exception): | |
def __init__(self): | |
super(VerifyError, self).__init__() | |
self.message = self._get_error_message() | |
@staticmethod | |
def _get_error_message() -> str: | |
if c_min > c_max: | |
return f'Cmin {c_min} Повинен буть меншим за Cmax {c_max}' | |
elif c1 > c_max or c1 < c_min: | |
return f'C1 {c1} має буть в діапазоні [{c_min};{c_max}]' | |
elif c2 > c_max or c2 < c_min: | |
return f'C2 {c2} має буть в діапазоні [{c_min};{c_max}]' | |
elif c3 > c_max or c3 < c_min: | |
return f'C3 {c3} має буть в діапазоні [{c_min};{c_max}]' | |
elif c1 >= c2: | |
return f'C1 {c1} має буть менше С2 {c2}' | |
elif c3 >= c_max: | |
return f'C3 {c3} має буть менше Cmax {c_max}' | |
return 'The input data seems ok?' | |
def __str__(self): | |
return self.message | |
def verify_input_data(): | |
if not c_min <= c1 <= c_max and c_min <= c2 <= c_max and \ | |
c_min <= c3 <= c_max and c_min < c_max and c1 != c2 and c3 != c_max: | |
raise VerifyError() | |
def triangle_distribution(m: float=None) -> tuple: | |
if not m: | |
m = Decimal((c1 + c2) / 2) | |
x = math_expect = hits_count = 0 | |
left = (m - c_min) / (c_max - c_min) | |
right = (c_max - m) / (c_max - c_min) | |
for i in range(max_count): | |
fx = Decimal(uniform(0.0, 1.0)) | |
random_trigger = Decimal(uniform(0.0, 1.0)) | |
if random_trigger <= left: | |
x = c_min + (m - c_min) * Decimal(sqrt(fx)) | |
elif random_trigger <= left + right: | |
x = m + (c_max - m) * (1 - Decimal(sqrt(fx))) | |
math_expect += x | |
if c3 <= x <= c_max: | |
hits_count += 1 | |
return math_expect / max_count, hits_count / max_count | |
def trapezoidal_distribution() -> tuple: | |
x = math_expect = hits_count = 0 | |
h = Decimal(2 / (c_max - c_min + c2 - c1)) | |
left = Decimal((h / 2) * (c1 - c_min)) | |
right = Decimal(1 - (h / 2) * (c_max - c2)) | |
for i in range(max_count): | |
fx = Decimal(uniform(0.0, 1.0)) | |
random_trigger = Decimal(uniform(0.0, 1.0)) | |
if left >= random_trigger >= 0: | |
x = c_min + Decimal(sqrt((2 * (c1 - c_min)) / h)) * Decimal(sqrt(fx)) | |
elif right >= random_trigger >= left: | |
x = Decimal(((c_min + c1) / 2)) + (fx / h) | |
elif 1 >= random_trigger >= right: | |
x = c_max - Decimal(sqrt((2 * (c_max - c2)) / h)) * Decimal(sqrt(1 - fx)) | |
math_expect += x | |
if c3 <= x <= c_max: | |
hits_count += 1 | |
return math_expect / max_count, hits_count / max_count | |
def triangle_from_trapeze() -> tuple: | |
u = 2 / (c_max + c2 - c1 - c_min) | |
a = c1 - c_min | |
b = c2 - c_max | |
m = Decimal(((u / a) * c_min - (u / b) * c_max) / ((u / a) - (u / b))) | |
return triangle_distribution(m) | |
if __name__ == '__main__': | |
c_min = int(input('Введіть мінімальну ціну нафти (Cmin) -> ')) | |
c_max = int(input('Введіть максимальну ціну нафти (Cmax) -> ')) | |
c1 = int(input('Введіть мінімальне значення найчастішої ціни нафти (C1) -> ')) | |
c2 = int(input('Введіть максимальне значення найчастішої ціни нафти (C2) -> ')) | |
c3 = int(input('Введіть значення, яке ціна нафти перевищує (C3) -> ')) | |
max_count = int(input('Введіть кількість ітерацій -> ')) | |
verify_input_data() | |
for method in [triangle_from_trapeze]: | |
mathematical_expect, hits_counter = method() | |
print(f'\nМетод: {method.__name__}\n' | |
f'Ймовірність, що ціна нафти перевищить значення C3: {hits_counter}\n' | |
f'Математичне сподівання: {mathematical_expect}\n') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment