Проблема перевода кода Python или языковая разница в генерации случайных чисел
Я новичок в Python и не имею опыта работы с QBasic. Я проводил симуляцию в Python, которая придумала теоретически неправильные значения. Затем я запустил его в QBasic и предложил теоретически предсказанные значения.
Вот тестовые случаи. Я рассчитываю только вероятность P(0,9<% Y <= 1,8), поэтому количество должно попадать в эти значения. 1-random.random () был только для того случая, когда я попытался использовать это для всех случаев, они все еще придумали неправильные значения. Вот теоретические результаты, и вы можете увидеть, как они отличаются:
у ~ у (0,1) = 0,575
у ~exp(2) = 0,3371
x1 ~ u (0,1) x2 ~ u (0,2) = 0,4475
P (y = 0,25)=0,8 P(y=1,5) = 0,2 = 0,32
В Python код моделирования:
def test():
x1,x2,c = 0.0,0.0,0.0
for i in range(10000):
if random.random()< 0.8:
x1 += 0.25
else:
x2 += 1.5
y = x1 + x2
if y>0.9 and y<=1.8:
c = c + 1
return x1,x2,c
print "test: ",test()
def sim(a,b):
#pyab1 = sum([a for a in a if a>0.9 and a<=1.8])/10000
#pyab2 = sum([b for b in b if b>0.9 and b<=1.8])/10000
#print "*****",float(pyab1+pyab2)
#print a+b
#array1 = [[a],[b]]
array1 = a+b
#array1.extend(a)
#array1.extend(b)
#c = 0
#for y in array1:
#if y>0.9 and y<=1.8:
#c = c + 1
pyab = sum([y for y in array1 if y>0.9 and y<=1.8])/10000
print("P(a < x <= b) : {0:8.4f}".format(pyab))
Вот вывод Python, за которым следуют значения, которые он должен дать, но это показывает, насколько далеки результаты.
case 1: P(a < x <= b) : 0.7169 #should be 0.575
case 2: P(a < x <= b) : 0.4282 #should be 0.3371
case 3: P(a < x <= b) : 0.5966 #should be 0.4475
case 4: P(a < x <= b) : 0.5595 #should be 0.32
В QBasic код моделирования:
Случай 1:
RANDOMIZE
FOR i = 1 TO 10000
X1 = RND(1)
X2 = RND(1)
Y = X1+X2
IF (Y>0.9) AND (Y<=1.8) THEN C=C+1
NEXT i
PRINT C/10000
Случай 2:
RANDOMIZE
FOR i = 1 TO 10000
X1 = (-0.5)*(LOG(1-RND(1)))
X2 = (-0.5)*(LOG(1-RND(1)))
Y = X1+X2
IF (Y>0.9) AND (Y<=1.8) THEN C=C+1
NEXT i
PRINT C/10000
Случай 3:
RANDOMIZE
FOR i = 1 TO 10000
X1 = RND(1)
X2 = RND(1)*2
Y = X1+X2
IF (Y>0.9) AND (Y<=1.8) THEN C=C+1
NEXT i
PRINT C/10000
Дело 4:
RANDOMIZE
FOR i = 1 TO 10000
X14 = RND(1)
X24 = RND(1)
IF (X14<0.8) THEN X41=0.25 ELSE X41=1.5
IF (X24<0.8) THEN X42=0.25 ELSE X42=1.5
Y = X1+X2
IF (Y>0.9) AND (Y<=1.8) THEN C=C+1
NEXT i
PRINT C/10000
Вот вывод QBasic, который показывает, как это на самом деле дает правильные результаты.
case 1: P(a < x <= b) : 0.5715
case 2: P(a < x <= b) : 0.3371
case 3: P(a < x <= b) : 0.4413
case 4: P(a < x <= b) : 0.3213
Весь приведенный выше код работает для меня без ошибок. Я не вижу различий в алгоритме, используемом для получения значений. Не уверен, что Python генерирует числа иначе, чем QBasic, и объясняет ли это причину такого поведения.
Я новичок в обоих этих языках, но QBasic кажется очень примитивным, и более вероятно, что Python получит правильный ответ, а QBasic - неправильный. Но происходит обратное. Похоже, это не связано с какой-либо разницей в коде. При переводе они оба говорят одно и то же.
Меня интересует причина, по которой они дают 2 разных результата. Меня больше интересует, почему Python дает неправильные ответы, а QBasic - правильные.
1 ответ
Ваш код Python полностью неверен. Я думаю, что вы хотите, чтобы это было следующее:
- Возьмем два массива, a и b, каждый из которых содержит 10000 чисел, сгенерированных некоторой случайной функцией. (Эквивалентно, каждый массив из 10000 выборок из данных после некоторого данного распределения.)
- Соедините значения в 10000 пар, причем каждая пара берет элемент из a и элемент из b.
- Возьмите сумму каждой пары.
- Посчитайте, сколько из этих 10000 парных сумм лежит между 0,9 и 1,8
- Разделите приведенное выше значение на 10000, чтобы получить вероятность того, что любая данная пара данных, взятая из этих распределений, составит от 0,9 до 1,8, и выведите эту вероятность.
Однако ваша функция sim(a, b) делает что-то совершенно другое. В основном, что вы на самом деле делаете:
- Объедините два массива по 10000 элементов, образуя массив из 20000 элементов.
- Возьмите сумму любых элементов в этом новом массиве из 20000 элементов, которые больше 0,9.
- Разделите эту сумму на 10000 и напечатайте ее.
Этот алгоритм не имеет ничего общего с вашим кодом Q-Basic.
Если я правильно понял вашу проблему, я думаю, что ваша функция сима должна быть такой:
def sim(x_sample, y_sample):
count = 0
for i in range(10000):
if 0.9 <= x_sample[i] + y_sample[i] <= 1.8:
count += 1
probability = count/10000.0
print("P(a < x <= b) : {0:8.4f}".format(probability))
(Почти наверняка есть более элегантные и Pythonic способы реализации вышеуказанной функции, но этот способ должен быть легок для понимания новичком Python.)
Вот результаты тестов, которые я провел в интерпретаторе для ваших случаев с 1 по 3, как я понял из программы QBasic. Я не включил версию теста 4, потому что я не понимал код QBasic для теста 4. Однако результаты первых трех тестов - это то, что вы сказали.
>>> from random import random
>>>
>>> sim([random() for i in range(10000)],
... [random() for i in range(10000)])
P(a < x <= b) : 0.5746
>>>
... from math import log
>>>
>>> sim([-0.5*log(1-random()) for i in range(10000)],
... [-0.5*log(1-random()) for i in range(10000)])
P(a < x <= b) : 0.3405
>>>
... sim([random() for i in range(10000)],
... [2*random() for i in range(10000)])
P(a < x <= b) : 0.4479