Python — почему этот код занимает так много времени?

Меня беспокоит часть между двумя хэш-линиями. Следующий код выполняется слишком долго, чтобы я мог дождаться его вывода. Когда я заменяю проблемную часть другим фрагментом кода, программа запускается через несколько секунд (см. конец этого поста). моя цель состоит в том, чтобы сгенерировать 90 точек данных, которые равномерно распределены в единичном квадрате (var1, var2), а затем сгенерировать 12 точек, которые случайным образом размещены в круге радиусом 1/8, полностью лежащем в пределах единичного квадрата (cir1, cir2). ) и, наконец, соедините эти два набора (sph1, sph2).

Я копался в этом коде со вчерашнего дня, и я действительно уверен, что он правильный (видимо, это не так). Я, наверное, упускаю что-то действительно очевидное...

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import random
import math
import numpy as np
import sys
from heapq import merge
import multiprocessing as mp
from multiprocessing import Pool

boot = 2
RRpoints = 90
rrpoints = 12
step = np.arange(-8.0 , 0.5 , 0.5)

def distance_between_points(ite, jte):
    xi, yi = ite
    xj, yj = jte
    x2 = (xi - xj) ** 2
    y2 = (yi - yj) ** 2
    d = math.sqrt(x2 + y2)
    return d

def heaviside_step(n):
    return int(n >= 0)

def myscript(iteration_number):
    RRfile_name = "MC_out_cluster_1/output%d.txt" % iteration_number
    with open(RRfile_name, "w") as RRf:
#############################################################################
        np.random.seed()
        var1 = np.random.uniform(0, 1 , RRpoints)
        var2 = np.random.uniform(0, 1 , RRpoints)
        cir1 = []
        cir2 = []
        x0 = np.random.uniform(0.125 , 0.875)
        y0 = np.random.uniform(0.125 , 0.875)
        while ( len(cir1) < rrpoints and len(cir2) < rrpoints ):
            np.random.seed()
            col1 = np.random.uniform(x0 - 0.125 , x0 + 0.125)
            col2 = np.random.uniform(y0 - 0.125 , y0 + 0.125)
            if (x0 - col1) ** 2 + (y0 - col2) ** 2 <= 1/64:
                cir1.append(col1)
                cir2.append(col2)
        sph1 = list(merge(var1 , cir1))
        sph2 = list(merge(var2 , cir2))
############################################################################
        corr = []
        for k in xrange(0, len(step)):
            h = 0
            for i in xrange(0, RRpoints):
                for j in xrange(1 + i, RRpoints):
                    ite = sph1[i] , sph2[i]
                    jte = sph1[j] , sph2[j]
                    dbp = distance_between_points(ite, jte)
                    h += heaviside_step(math.exp( step[k] ) - dbp)
            corr.append([math.exp(step[k]) , h])

        for item in corr:
            RRf.write("{0}\t{1}\n".format(item[0], item[1]))

x = xrange(boot)
p = mp.Pool()

y = p.imap(myscript, x)
list(y)

Это еще один (рабочий) фрагмент, который я модифицировал, чтобы создать приведенный выше код:

 #############################################################################
        var1 = []
        var2 = []
        while (len(var1) < RRpoints):
            np.random.seed()
            col1 = np.random.uniform(0 , 1)
            col2 = np.random.uniform(0 , 1)
            if ( col1 ** 2 + (col2 - 0.5) ** 2 > 1/16 and (col1 - 1) ** 2 + (col2 - 0.5) ** 2 > 1/16 ):
                var1.append(col1)
                var2.append(col2)
        cir1 = []
        cir2 = []
        while (len(cir1) < rrpoints and len(cir2) < rrpoints):
            np.random.seed()
            new1 = np.random.uniform(0.125 , 0.875)
            new2 = np.random.uniform(0.125 , 0.875)
            if ( new1 ** 2 + (new2 - 0.5) ** 2 >= 0.140625 and (new1 - 1) ** 2 + (new2 - 0.5) ** 2 >= 0.140625 ):
                cir1.append(new1)
                cir2.append(new2)
        sph1 = list(merge(var1 , cir1))
        sph2 = list(merge(var2 , cir2))
 #############################################################################

comment
Какую версию питона вы используете?   -  person RoadieRich    schedule 30.03.2016
comment
Вы также можете более эффективно генерировать случайные точки по кругу, используя x = sqrt(r) * cos(theta); y = sqrt(r) * sin(theta). См. mathworld.wolfram.com/DiskPointPicking.html и stats.stackexchange.com/q/120527/842, stackoverflow.com/q/5837572/190597.   -  person unutbu    schedule 30.03.2016


Ответы (1)


Вы используете Python 2.x, поэтому 1/64==0 (в Python 2 деление двух целых чисел дает целочисленный результат). Если вы можете, обновитесь до Python 3.x или, если это не удастся, измените тест, чтобы использовать 1./64

person Duncan    schedule 30.03.2016