Come si può generare dire 1000 punti casuali con una distribuzione come quella di città e città in es. Ohio?
Ho paura di non poter definire "distribuito come città" con precisione; centri distribuiti uniformemente + piccoli nuvole gaussiane sono semplici ma ad hoc.
Aggiunto: deve esistere una famiglia di distribuzioni 2d con un parametro di cluster che può essere modificato per corrispondere a un determinato insieme di punti?Genera punti casuali distribuiti come città?
risposta
In java, questo viene fornito tramite new Random().nextGaussian()
. Dal momento che la fonte di Java è disponibile, si può guardare a questo:
synchronized public double nextGaussian() {
// See Knuth, ACP, Section 3.4.1 Algorithm C.
if (haveNextNextGaussian) {
haveNextNextGaussian = false;
return nextNextGaussian;
} else {
double v1, v2, s;
do {
v1 = 2 * nextDouble() - 1; // between -1 and 1
v2 = 2 * nextDouble() - 1; // between -1 and 1
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
Tracciando 30000 case utilizzando
x = r.nextGaussian() * rad/4 + rad;
y = r.nextGaussian() * rad/4 + rad;
rese questa bella città:
Forse si può prendere un guarda Walter Christaller's Theory of Central Places. Immagino ci debba essere un generatore da qualche parte, oppure puoi cucinare da solo.
Inizia con un modello dei giochi d'acqua nella tua area di destinazione (o creane uno, se è per un luogo immaginario), quindi raggruppa le città vicino agli svincoli dei fiumi, lungo le rive dei laghi, le giunzioni dei fiumi. Quindi fai autostrade immaginarie che collegano quelle grandi città. Ora cospargere alcune città intermedie lungo quelle autostrade a distanza ragionevole, preferendo essere vicino alle giunzioni nelle autostrade. Ora cospargere alcune piccole città attraverso gli spazi vuoti.
I grappoli gaussiani con le dimensioni dei cluster di Poisson funzionano abbastanza bene.
Problema: generare punti casuali raggruppati in modo approssimativo come date città, ad esempio negli Stati Uniti.
sottoproblemi:
a) descrivono grappoli con righe di numeri, in modo che "gruppo A è come gruppo B" semplifica a "clusternumbers (A) è come "clusternumbers (B)"
Esecuzione N = 100. poi 1000 punti attraverso fcluster seguito, con ncluster = 25, dà
N 100 ncluster 25: 22 + 3 r 117
sizes: av 4 10 9 8 7 6 6 5 5 4 4 4 ...
radii: av 117 202 198 140 134 64 62 28 197 144 148 132 ...
N 1000 cluster 25: 22 + 3 r 197
sizes: av 45 144 139 130 85 84 69 63 43 38 33 30 ...
radii: av 197 213 279 118 146 282 154 245 212 243 226 235 ...
b) trovare un combiation di generatori casuali con 2 o 3 parametri che può essere variata per generare differenti raggruppamenti.
cluster gaussiana con cluster di Poisson le dimensioni possono corrispondere al raggruppamento delle città abbastanza bene:
def randomclusters(N, ncluster=25, radius=1, box=box):
""" -> N 2d points: Gaussian clusters, Poisson cluster sizes """
pts = []
lam = eval(str(N // ncluster))
clustersize = lambda: np.random.poisson(lam - 1) + 1
# poisson 2: 14 27 27 18 9 4 %
# poisson 3: 5 15 22 22 17 10 %
while len(pts) < N:
u = uniformrandom2(box)
csize = clustersize()
if csize == 1:
pts.append(u)
else:
pts.extend(inbox(gauss2(u, radius, csize)))
return pts[:N]
# Utility functions --
import scipy.cluster.hierarchy as hier
def fcluster(pts, ncluster, method="average", criterion="maxclust"):
""" -> (pts, Y pdist, Z linkage, T fcluster, clusterlists)
ncluster = n1 + n2 + ... (including n1 singletons)
av cluster size = len(pts)/ncluster
"""
# Clustering is pretty fast:
# sort pdist, then like Kruskal's MST, O(N^2 ln N)
# Many metrics and parameters are possible; these satisfice.
pts = np.asarray(pts)
Y = scipy.spatial.distance.pdist(pts) # N*(N-1)/2
Z = hier.linkage(Y, method) # N-1, like mst
T = hier.fcluster(Z, ncluster, criterion=criterion)
clusters = clusterlists(T)
return (pts, Y, Z, T, clusters)
def clusterlists(T):
""" T = hier.fcluster(Z, t) e.g. [a b a b c a]
-> [ [0 2 5] [1 3] ] sorted by len, no singletons [4]
"""
clists = [ [] for j in range(max(T) + 1)]
for j, c in enumerate(T):
clists[c].append(j)
clists.sort(key=len, reverse=True)
n1 = np.searchsorted( map(len, clists)[::-1], 2)
return clists[:-n1]
def radius(x):
""" rms |x - xmid| """
return np.sqrt(np.mean(np.var(x, axis=0)))
# * 100 # 1 degree lat/long ~ 70 .. 111 km
Interessante, grazie. Questo porta a "statistiche spaziali" e "pattern di punti spaziali", che hanno molti documenti e diversi libri ma finora nessun punto di ingresso/nessun codice. – denis