Considérons une généralisation de ce problème. Il y a pots de peinture de couleurs distinctes et boules. Puis- tenir jusqu'à balles. Vous souhaitez générer des configurations de billes dans les canettes ayant au moins billes en can pour chaque , chaque configuration avec une probabilité égale.m=4m=4n(0)=100ia(0)i=(100,100,50,75)bi=(0,50,0,25)ii
De telles configurations sont en correspondance biunivoque avec les configurations obtenues après avoir boules de la boîte , limitant les balles restantes à au plus par boîte. Je vais donc simplement les générer et vous laisser les ajuster ensuite (en remettant les boules dans le can pour chaque ).biin=n(0)−∑ibi=100−(0+50+0+25)=25ai=a(0)i−bi=(100,50,50,50)biii
Pour compter ces configurations, corrigez tous les indices sauf deux, disons et . Supposons qu'il y ait déjà balles dans la boîte pour chaque différent de et . Cela laisse des boules . À condition que se trouvent les autres boules, celles-ci sont réparties uniformément dans les boîtes et . Les configurations possibles sont en nombre (voir les commentaires), allant de la mise en place d'autant de balles dans le canijskkkijsi+sjn−(si+sj)ij1+min(ai+aj−si−sj,si+sj)iautant que possible tout en plaçant le plus de balles possible dans la boîte .j
Si vous le souhaitez, vous pouvez compter le nombre total de configurations en appliquant cet argument de manière récursive aux boîtes restantes . Cependant, pour obtenir des échantillons, nous n'avons même pas besoin de connaître ce nombre. Tout ce que nous devons faire est de visiter à plusieurs reprises toutes les paires possibles non ordonnées de boîtes et de modifier de manière aléatoire (et uniforme) la distribution des boules à l'intérieur de ces deux boîtes. Il s'agit d'une chaîne de Markov avec une distribution de probabilité limite uniforme sur tous les états possibles (comme cela est facilement montré en utilisant des méthodes standard). Par conséquent , il suffit de commencer dans unem−2{i,j}, exécutez la chaîne suffisamment longtemps pour atteindre la distribution limite, puis suivez les états visités par cette procédure. Comme d'habitude, pour éviter une corrélation sérielle, cette séquence d'états doit être "amincie" en les sautant (ou revisitée au hasard). L'amincissement d'un facteur d'environ la moitié du nombre de boîtes a tendance à bien fonctionner, car après cela, de nombreuses étapes en moyenne, chaque boîte a été affectée, produisant une configuration véritablement nouvelle.
Cet algorithme coûte effort pour générer chaque configuration aléatoire en moyenne. Bien qu'il existe d'autres algorithmes , celui-ci présente l'avantage de ne pas avoir à effectuer au préalable les calculs combinatoires.O(m)O(m)
Par exemple, travaillons manuellement sur une situation plus petite. Soit et , par exemple. Il existe 15 configurations valides, qui peuvent être écrites sous forme de chaînes de nombres d'occupation. Par exemple, place deux balles dans la deuxième boîte et une balle dans la quatrième boîte. En émulant l'argument, considérons l'occupation totale des deux premières boîtes. Lorsque c'est balles, aucune balle n'est laissée pour les deux dernières boîtes. Cela donne aux Étatsa=(4,3,2,1)n=30201
s1+s2=3
30**, 21**, 12**, 03**
où **
représente tous les numéros d'occupation possibles pour les deux dernières boîtes: à savoir 00
. Lorsque , les états sonts1+s2=2
20**, 11**, 02**
où maintenant **
peut être soit 10
ou 01
. Cela donne états supplémentaires. Lorsque , les états sont3×2=6s1+s2=1
10**, 01**
où maintenant **
peut être 20
, 11
mais pas 02
(en raison de la limite d'une balle dans la dernière boîte). Cela donne états supplémentaires. Enfin, lorsque , toutes les boules sont dans les deux dernières boîtes, qui doivent être pleines jusqu'à leurs limites de et . Les états également probables sont donc2×2=4s1+s2=0214+6+4+1=15
3000, 2100, 1200, 0300; 2010, 2001, 1110, 1101, 0210, 0201; 1020, 1011, 0120, 0111; 0021.
En utilisant le code ci-dessous, une séquence de ces configurations a été générée et réduite à un tiers, créant configurations des états. Leurs fréquences étaient les suivantes: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
A tests d'uniformité donne une valeur de , ( degrés de liberté): ce qui est beau accord avec l'hypothèse que cette procédure produit également des états probables.χ2χ211.2p=0.6714
Ce R
code est configuré pour gérer la situation dans la question. Changer a
et n
travailler avec d'autres situations. Défini N
pour être suffisamment grand pour générer le nombre de réalisations dont vous avez besoin après l'amincissement .
Ce code triche un peu en parcourant systématiquement toutes les paires . Si vous voulez être stricte sur l' exécution de la chaîne de Markov, générer , et au hasard, comme indiqué dans le code commenté. (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)