Skip to content

Instantly share code, notes, and snippets.

@ripiuk
Created May 30, 2018 21:53
Show Gist options
  • Save ripiuk/372bb7d19c0f574b3ef0a970c04008cd to your computer and use it in GitHub Desktop.
Save ripiuk/372bb7d19c0f574b3ef0a970c04008cd to your computer and use it in GitHub Desktop.
Get probability using triangle distribution, trapezoidal distribution or triangle from trapeze distribution
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