Vamos considerar uma generalização desse problema. Existem latas de tinta de cores distintas e bolas. Pode pode conter até bolas. Você deseja gerar configurações de bolas nas latas com pelo menos bolas em can para cada , cada configuração com igual probabilidade.m = 4 n ( 0 ) = 100 i a ( 0 ) i = ( 100 , 100 , 50 , 75 ) b i = ( 0 , 50 , 0 , 25 ) i im=4m=4n(0)=100ia(0)i=(100,100,50,75)bi=(0,50,0,25)ii
Essas configurações estão em correspondência individual com as configurações obtidas após a remoção de bolas do can , limitando bolas restantes para no máximo por lata. Portanto, apenas e deixarei ajustá-los depois (colocando bolas volta no can para cada ). i N = N ( 0 ) - Σ i b i = 100 - ( 0 + 50 + 0 + 25 ) = 25 um i = um ( 0 ) i - b i = ( 100 , 50 , 50 , 50 )biin=n(0)−∑ibi=100−(0+50+0+25)=25ai=a(0)i−bi=(100,50,50,50) i ibiii
Para contar essas configurações, corrija todos os índices, com exceção de dois, digamos e . Suponhamos que existem bolas já no pode para cada diferindo e . Isso deixa bolas. Condicional em que o outro bolas são, estes são distribuídos uniformemente dentro de latas e . As configurações possíveis são em número (ver as observações), variando de colocar o maior número de bolas pode emj s k k k i j s i + s j n - ( s i + s j ) i jijskkkijsi+sjn−(si+sj)ij1+min(ai+aj−si−sj,si+sj)iquanto possível durante todo o tempo de colocar o maior número de bolas em lata quanto possível.j
Se desejar, você pode contar o número total de configurações aplicando esse argumento recursivamente às latas restantes . No entanto, para obter amostras , nem precisamos saber essa contagem. Tudo o que precisamos fazer é visitar repetidamente todos os possíveis pares não ordenados de latas e alterar aleatoriamente (e uniformemente) a distribuição de bolas nessas duas latas. Esta é uma cadeia de Markov com uma distribuição de probabilidade limitadora que é uniforme em todos os estados possíveis (como é facilmente mostrado usando métodos padrão). Portanto, basta iniciar em qualquerm−2{i,j}estado, execute a cadeia por tempo suficiente para alcançar a distribuição limitadora e depois acompanhe os estados visitados por este procedimento. Como de costume, para evitar correlação serial, essa sequência de estados deve ser "reduzida", pulando-os (ou revisitados aleatoriamente). O desbaste por um fator de cerca da metade do número de latas tende a funcionar bem, porque depois disso muitas etapas, em média, cada lata pode ser afetada, produzindo uma configuração genuinamente nova.
Esse algoritmo custa esforço para gerar cada configuração aleatória em média. Embora existam outros algoritmos , este possui a vantagem de não precisar fazer os cálculos combinatórios antecipadamente.O(m)O(m)
Como exemplo, vamos resolver uma situação menor manualmente. Deixe que e , por exemplo. Existem 15 configurações válidas, que podem ser escritas como cadeias de números de ocupação. Por exemplo, coloca duas bolas na segunda lata e uma bola na quarta lata. Emulando o argumento, vamos considerar a ocupação total das duas primeiras latas. Quando são bolas, nenhuma bola é deixada para as duas últimas latas. Isso dá aos estadosa=(4,3,2,1)n=30201
s1+s2=3
30**, 21**, 12**, 03**
onde **
representa todos os números de ocupação possíveis para as duas últimas latas: a saber 00
,. Quando , os estados sãos1+s2=2
20**, 11**, 02**
onde agora **
pode ser um 10
ou outro 01
. Isso dá mais estados. Quando , os estados são3×2=6s1+s2=1
10**, 01**
onde agora **
pode estar 20
, 11
mas não 02
(devido ao limite de uma bola na última lata). Isso dá mais estados. Finalmente, quando , todas as bolas estão nas duas últimas latas, que devem estar cheias até o limite de e . Os estados igualmente prováveis são, portanto,2×2=4s1+s2=0214+6+4+1=15
3000, 2100, 1200, 0300; 2010, 2001, 1110, 1101, 0210, 0201; 1020, 1011, 0120, 0111; 0021.
Usando o código abaixo, uma sequência de dessas configurações foi gerada e reduzida a cada terceira, criando configurações dos estados. Suas frequências eram as seguintes: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 teste de uniformidade dá uma valor de , ( graus de liberdade): o que é belo acordo com a hipótese de que este procedimento produz estados igualmente prováveis.χ 2 11,2χ2χ211.2p=0.6714
Este R
código está configurado para lidar com a situação na pergunta. Mude a
e n
trabalhe com outras situações. Defina N
como grande o suficiente para gerar o número de realizações necessárias após o desbaste .
Esse código engana um pouco, alternando sistematicamente todos os pares . Se você quiser ser rigoroso sobre o funcionamento da cadeia de Markov, gerar , e de forma aleatória, tal como consta no código comentado. (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)