Betrachten wir eine Verallgemeinerung dieses Problems. Es gibt Farbdosen mit verschiedenen Farben und Kugeln. Kann bis zu Bälle halten? Sie möchten Konfigurationen von Kugeln in den Dosen mit mindestens Kugeln in der Dose für jedes erzeugen , wobei jede Konfiguration mit gleicher Wahrscheinlichkeit erfolgt.m=4m=4n(0)=100ia(0)i=(100,100,50,75)bi=(0,50,0,25)ii
Solche Konfigurationen stimmen eins zu eins mit den Konfigurationen die nach dem Entfernen von Kugeln aus der Dose , wodurch verbleibende Bälle zu höchstens pro Dose. Ich werde diese daher einfach generieren und Sie sie anschließend anpassen lassen (indem Sie Bälle für jedes wieder in can legen ). i n = n ( 0 ) - ∑ i b i = 100 - ( 0 + 50 + 0 + 25 ) = 25 a i = a ( 0 ) i - b i = ( 100 , 50 , 50 , 50 ) b i i ibiin=n(0)−∑ibi=100−(0+50+0+25)=25ai=a(0)i−bi=(100,50,50,50)biii
Um diese Konfigurationen hochzuzählen, korrigieren Sie alle bis auf zwei Indizes, z. B. und . Angenommen, es gibt bereits Bälle in Dose für jedes sich von und . Das lässt Bälle. Abhängig davon, wo sich die anderen Kugeln befinden, sind diese gleichmäßig in den Dosen und . Die möglichen Konfigurationen sind in der Anzahl (siehe die Kommentare) und reichen von der Platzierung so vieler Bälle in Doseijskkkijsi+sjn−(si+sj)ij1+min(ai+aj−si−sj,si+sj)iwie möglich den ganzen Weg so viele Bälle in Dose durch Platzieren wie möglich.j
Wenn Sie möchten, können Sie die Gesamtzahl der Konfigurationen zählen, indem Sie dieses Argument rekursiv auf die verbleibenden Dosen anwenden . Um Proben zu erhalten, müssen wir diese Anzahl jedoch nicht einmal kennen. Alles, was wir tun müssen, ist, wiederholt alle möglichen ungeordneten Paare von Dosen zu besuchen und die Verteilung der Kugeln innerhalb dieser beiden Dosen zufällig (und gleichmäßig) zu ändern. Dies ist eine Markov-Kette mit einer begrenzten Wahrscheinlichkeitsverteilung, die über alle möglichen Zustände gleichmäßig ist (wie mit Standardmethoden leicht gezeigt werden kann). Daher reicht es aus, in einem zu beginnenm−2{i,j}Führen Sie die Kette so lange aus, bis die Grenzverteilung erreicht ist, und verfolgen Sie dann die von diesem Verfahren besuchten Zustände. Wie üblich sollte diese Folge von Zuständen "verdünnt" werden, um eine serielle Korrelation zu vermeiden, indem sie übersprungen (oder zufällig wiederholt werden). Das Ausdünnen um den Faktor etwa der Hälfte der Anzahl der Dosen funktioniert in der Regel gut, da nach durchschnittlich vielen Schritten jede Dose betroffen ist und eine wirklich neue Konfiguration entsteht.
Dieser Algorithmus kostet Aufwand, um durchschnittlich jede zufällige Konfiguration zu generieren. Obwohl andere -Algorithmen existieren, hat dieser den Vorteil, dass die kombinatorischen Berechnungen nicht vorher durchgeführt werden müssen.O(m)O(m)
Lassen Sie uns als Beispiel eine kleinere Situation manuell herausarbeiten. Sei zum Beispiel und . Es gibt 15 gültige Konfigurationen, die als Zeichenfolgen von Belegungsnummern geschrieben werden können. Zum Beispiel werden zwei Kugeln in die zweite Dose und eine Kugel in der vierten Dose. Betrachten wir das Argument und betrachten wir die Gesamtbelegung der ersten beiden Dosen. Wenn das Bälle ist, bleiben für die letzten beiden Dosen keine Bälle übrig. Das gibt die Staatena=(4,3,2,1)n=30201
s1+s2=3
30**, 21**, 12**, 03**
wobei **
alle möglichen Belegungsnummern für die letzten beiden Dosen darstellt: nämlich 00
. Wenn , sind die Zuständes1+s2=2
20**, 11**, 02**
wo **
kann jetzt entweder 10
oder sein 01
. Das ergibt weitere Zustände. Wenn , sind die Zustände3×2=6s1+s2=1
10**, 01**
wo jetzt **
sein kann 20
, 11
aber nicht 02
(wegen der Grenze von einer Kugel in der letzten Dose). Das ergibt weitere Zustände. Wenn schließlich , befinden sich alle Kugeln in den letzten beiden Dosen, die bis zu ihren Grenzen von und voll sein müssen . Die gleich wahrscheinlichen Zustände sind daher2×2=4s1+s2=0214+6+4+1=15
3000, 2100, 1200, 0300; 2010, 2001, 1110, 1101, 0210, 0201; 1020, 1011, 0120, 0111; 0021.
Unter Verwendung des folgenden Codes wurde eine Folge von solcher Konfigurationen erzeugt und auf jede dritte verdünnt, wodurch Konfigurationen der Zustände erzeugt wurden. Ihre Frequenzen waren die folgenden:10,009333715
State: 3000 2100 1200 0300 2010 1110 0210 1020 0120 2001 1101 0201 1011 0111 0021
Count: 202 227 232 218 216 208 238 227 237 209 239 222 243 211 208
Ein Test der Gleichmäßigkeit ergibt einen Wert von , ( Freiheitsgrade): Das ist eine schöne Übereinstimmung mit der Hypothese, dass dieses Verfahren gleich wahrscheinliche Zustände erzeugt.χ2χ211.2p=0.6714
Dieser R
Code ist so eingerichtet, dass er die jeweilige Situation behandelt. Ändern Sie sich a
und n
arbeiten Sie mit anderen Situationen. Stellen N
Sie den Wert so ein, dass die Anzahl der nach dem Ausdünnen erforderlichen Realisierungen generiert wird .
Dieser Code betrügt ein wenig, indem er systematisch alle Paare durchläuft . Wenn Sie über das Ausführen der Markow - Kette zu streng sein wollen, erzeugen , und zufällig, in dem kommentierten Code als gegeben. (i,j)i
j
ij
#
# Gibbs-like sampler.
#
# `a` is an array of maximum numbers of balls of each type. Its values should
# all be integers greater than zero.
# `n` is the total number of balls.
#------------------------------------------------------------------------------#
g <- function(j, state, a) {
#
# `state` contains the occupancy numbers.
# `a` is the array of maximum occupancy numbers.
# `j` is a pair of indexes into `a` to "rotate".
#
k <- sum(state[j]) # Total occupancy.
x <- floor(runif(1, max(0, k - a[j[2]]), min(k, a[j[1]]) + 1))
state[j] <- c(x, k-x)
return(state)
}
#
# Set up the problem.
#
a <- c(100, 50, 50, 50)
n <- 25
# a <- 4:1
# n <- 3
#
# Initialize the state.
#
state <- round(n * a / sum(a))
i <- 1
while (sum(state) < n) {
if (state[i] < a[i]) state[i] <- state[i] + 1
i <- i+1
}
while (sum(state) > n) {
i <- i-1
if (state[i] > 0) state[i] <- state[i] - 1
}
#
# Conduct a sequence of random changes.
#
set.seed(17)
N <- 1e5
sim <- matrix(state, ncol=1)
u <- ceiling(N / choose(length(state), 2) / 2)
i <- rep(rep(1:length(state), each=length(state)-1), u)
j <- rep(rep(length(state):1, length(state)-1), u)
ij <- rbind(i, j)
#
# Alternatively, generate `ij` randomly:
# i <- sample.int(length(state), N, replace=TRUE)
# j <- sample.int(length(state)-1, N, replace=TRUE)
# ij <- rbind(i, ((i+j-1) %% length(state))+1)
#
sim <- cbind(sim, apply(ij, 2, function(j) {state <<- g(j, state, a); state}))
rownames(sim) <- paste("Can", 1:nrow(sim))
#
# Thin them for use. Each column is a state.
#
thin <- function(x, stride=1, start=1) {
i <- round(seq(start, ncol(x), by=stride))
x[, i]
}
#
# Make a scatterplot of the results, to illustrate.
#
par(mfrow=c(1,1))
s <- thin(sim, stride=max(1, N/1e4))
pairs(t(s) + runif(length(s), -1/2, 1/2), cex=1/2, col="#00000005", pch=16)