Проблема перевода кода 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
Другие вопросы по тегам