0

Mein Anliegen ist der Teil zwischen den beiden Hash-Linien. Der folgende Code wird zu lange ausgeführt, damit ich auf die Ausgabe warten kann. Wenn ich den problematischen Teil durch einen anderen Codeabschnitt ersetze, läuft das Programm in ein paar Sekunden (siehe das Ende dieses Beitrags). Mein Ziel ist es, 90 Datenpunkte gleichmäßig in einem Einheitsquadrat zu generieren (var1, var2) und dann 12 Punkte zu generieren, die zufällig in einem Kreis mit dem Radius 1/8 platziert werden, der vollständig innerhalb des Einheitsquadrats liegt (cir1,)) und schließe schließlich diese zwei Sätze an (sph1, sph2).Python - warum dauert dieser Code so lange?

Ich habe in diesem Code seit gestern und ad bin ich wirklich sicher, dass es richtig ist (anscheinend ist es nicht). Mir fehlt wahrscheinlich etwas wirklich offensichtlich ...

#!/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) 

Dies ist ein weiterer (in Betrieb) chunk, dass ich den obigen Code erstellen geändert:

############################################################################# 
     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)) 
############################################################################# 
+0

Welche Version von Python verwenden Sie? – RoadieRich

+1

Sie können zufällige Punkte in einem Kreis auch effizienter erzeugen, indem Sie 'x = sqrt (r) * cos (theta); y = sqrt (r) * sin (Theta) '. Siehe http://mathworld.wolfram.com/DiskPointPicking.html und http://stats.stackexchange.com/q/120527/842, http://stackoverflow.com/q/5837572/190597. – unutbu

+0

@unutbu Das ist cool – corey979

Antwort

2

Sie verwenden Python 2.x so 1/64==0 (In Python 2 ergibt die Division zweier Ganzzahlen ein ganzzahliges Ergebnis). Wenn es Ihnen möglich ist, führen Sie ein Upgrade auf Python 3.x durch, oder ändern Sie den zu verwendenden Test 1./64