2017-01-23 2 views
1

Ich möchte zwei ganze Zahlen x und y nach dem Zufallsprinzip aus einem Intervall [1, N], so dass | x-y | > = D, für einige D < N. Der Code unten (geschrieben in R) ist, was ich benutzt habe, aber es ist schrecklich ineffizient. Gibt es bessere Methoden für diese Art der Probenahme? Danke in adv.Random Sampling mit Abstand Bedingung

N <- 100; D <- 10; 

i <- sample(1:N, 2) 

while (abs(i[1] - i[2]) < D){ 
    i <- sort(sample(1:N, 2)) 
} 
+0

scheint nicht ineffizient überhaupt - warum sagst du das? für eine Entfernung von 10 und Werte von 1 bis 100, die meisten Male müssen Sie nur "Probe" einmal aufrufen – rawr

+0

Ich denke, (Effizienz) hängt von der spezifischen Anwendungsfall, aber am wichtigsten ist dieser Algorithmus nicht konstante Zeit seit ' P (| xy |> = D) 'für jeden Aufruf zum Abtasten (1: N, 2) ist etwas entlang der Linie von '1 - [(Nx)/N + (x-0)/N + 2D/N] ', mit P (x) = 1/N, für jedes x, y in [1: N] und D miraculixx

Antwort

1

Ich denke, der Schlüssel ist zu erkennen, dass y von x abhängt (oder umgekehrt). Hier ist der Algorithmus, der höchstens drei Schritte arbeiten sollte:

1. sample x from [1:N] 
2. sample y from [1:(x-D)] if (x-D) >= 1 
    sample y from [x + D:N] if (x+D) <= N 
3. If both conditions for y are met, choose one of the generated y uniform at random 

Die Idee ist, dass, sobald x abgetastet wurde, y im Bereich sein muss [1: (xD)] oder [x + D: N] um | xy | zu befriedigen > = D.

Beispiele:

N = 100; D = 10

a) x is close to N 

1. x is sampled from 1:N as 95 
2. to satisfy |x-y| >= D, y can be at most 85, so the range to sample y is [1:85] 

b) x is close to 1 

1. x is sampled from 1:N as 9 
2. y must be at least 19, so the range to sample y is [19:N] 

c) x is close to 50 

1. x is sampled from 1:N as 45 
2. y must be either at most 35, or at least 55, so the ranges to sample from are [1:35] and [55:N] 
0

I dies zufällig durch ersten Ansatz wäre, einen Unterschied zwischen den Zahlen Abtastung größer als oder gleich D. Mit anderen Worten, wir wollen Zahlen zwischen und N-1 mit Ersatz abtasten.

difference <- sample(D:(N-1), 20, replace = TRUE) 

Jetzt alles, was wir tun müssen, um unsere niedrigere Zahl auswählen, indem Sie eine Zahl zwischen 1 und N - difference auswählen. Wir können dies mit vapply tun.

lowerval <- vapply(N - difference, sample, numeric(1), 1) 

Schließlich erhalten wir den oberen Wert, indem wir die Differenz zum niedrigeren Wert hinzufügen.

upperval <- lowerval + difference 
+0

Eine Sache zu beachten ist, dass die Verteilung, die diesen Algorithmus verwendet, anders sein wird als die Verteilung, die OP-Algorithmus verwendet. In Abhängigkeit von anderen Anforderungen, die von der Zufallsstichprobe benötigt werden, kann dies sein oder nicht sein, was sie wollen. – Dason