2016-06-26 6 views
5

muszę losowo pick n-wymiarowy wektor o długości 1. Moim najlepszym pomysłem jest, aby wybrać losowy punkt w tej kuli znormalizować go:obliczeniowo zbieranie losowy punkt na hipersfera

import random 

def point(n): 
    sq = 0 
    v = [] 
    while len(v) < n: 
     x = 1 - 2*random.random() 
     v.append(x) 
     sq = sq + x*x 
     if sq > 1: 
      sq = 0 
      v = [] 
    l = sq**(0.5) 
    return [x/l for x in v] 

Jedynym problemem jest to, że volume of an n-ball staje się mniejszy wraz ze wzrostem wymiaru, więc użycie jednolitego rozkładu od random.random zajmuje bardzo długo nawet małe n 17. Czy istnieje lepszy (szybszy) sposób na uzyskanie losowego punktu na n-kuli?

+0

Możesz znaleźć algorytm [tutaj] (http://stackoverflow.com/a/34402858/4081336). –

+0

@ LeandroCaniglia No cóż, ten algorytm zajmuje się tylko n = 3 –

+0

Przez przypadek masz na myśli to, że musi być równomiernie rozprowadzany? Te rzeczy łatwo stają się trudne, więc nie sądzę, że to, co teraz robisz, działa w tym sensie. – Bakuriu

Odpowiedz

5

Według Muller, M. E. "A Note on a Method for Generating Points Uniformly on N-Dimensional Spheres" trzeba by utworzyć wektor n gaussowskich zmiennych losowych i podzielić przez jej długości:

import random 
import math 

def randnsphere(n): 
    v = [random.gauss(0, 1) for i in range(0, n)] 
    inv_len = 1.0/math.sqrt(sum(coord * coord for coord in v)) 
    return [coord * inv_len for coord in v] 

Jak stwierdził @Bakuriu w komentarzach, używając numpy.random może zaoferować przewagę wydajności podczas praca z większymi wektorami.

+0

Szacunek do zmniejszenia wykorzystania podziału. – YBerman

+0

@YBerman Właśnie edytowałem to z powrotem po usunięciu go dla postrzeganej przedwczesnej optymalizacji;) –

+2

Możesz rozważyć użycie 'numpy.random' do obsługi tych wektorów. Prawdopodobnie jest to wydajne. – Bakuriu