Làm thế nào để tạo các mẫu thống nhất một cách ngẫu nhiên từ nhiều biến rời rạc chịu các ràng buộc?


8

Tôi muốn tạo ra một quy trình Monte Carlo để lấp đầy một chiếc bình với N quả bóng màu I, C [i]. Mỗi màu C [i] có số lượng bóng tối thiểu và tối đa nên được đặt trong bình.

Ví dụ, tôi đang cố gắng đặt 100 quả bóng vào trong bình và có thể lấp đầy nó bằng bốn màu:

  • Đỏ - Tối thiểu 0, Tối đa 100 # NB, không thể nhận ra mức tối đa thực tế.
  • Màu xanh lam - Tối thiểu 50, tối đa 100
  • Vàng - Tối thiểu 0, Tối đa 50
  • Màu xanh lá cây - Tối thiểu 25, tối đa 75

Làm cách nào tôi có thể tạo N mẫu được đảm bảo phân phối đồng đều trên các kết quả có thể?

Tôi đã thấy các giải pháp cho vấn đề này trong đó các quả bóng không có tối thiểu hoặc tối đa, hoặc cách khác, có cùng cực tiểu và cực đại ngầm. Xem ví dụ, cuộc thảo luận này về một chủ đề hơi khác:

Tạo trọng số phân bố đồng đều mà tổng hợp?

Nhưng tôi đang gặp vấn đề về việc khái quát hóa giải pháp này.


1
Bởi "phân phối ngẫu nhiên" bạn có nghĩa là phân phối ngẫu nhiên thống nhất ?
whuber

1
Mô tả của bạn không rõ ràng lắm. Bạn có phải là kiểu lấy mẫu ngẫu nhiên tương ứng với siêu âm đa biến, hay cái gì khác không?
Glen_b -Reinstate Monica

@whuber - vâng, phân phối ngẫu nhiên thống nhất. Làm rõ ở trên.
GPB

Một bộ lấy mẫu giống như Gibbs sẽ thực hiện công việc độc đáo ngay cả đối với các phiên bản lớn hơn nhiều của vấn đề này.
whuber

Câu trả lời:


3

Gọi là số bi có màu . Ngoài ra, hãy để và lần lượt là số lượng bóng tối thiểu và tối đa của . Chúng tôi muốn lấy mẫu thống nhất theo chủ đề ngẫu nhiên theo các ràng buộc sau:C i m i M i C i ( n 1 , Mạnh , n I )niCimiMiCi(n1,,nI)

  1. miniMi
  2. i=1Ini=N

Trước hết, bạn có thể loại bỏ các ràng buộc ràng buộc thấp hơn (ví dụ: ) bằng cách chọn các bóng có màu ban đầu. Điều này sửa đổi hai ràng buộc như sau:m i C iminimiCi

  1. 0nibi=Mimi
  2. i=1Ini=B=Ni=1Imi

Đặt biểu thị phân phối thống nhất mà chúng ta quan tâm. Chúng ta có thể sử dụng quy tắc chuỗi và lập trình động để lấy mẫu từ cách hiệu quả. Đầu tiên, chúng tôi sử dụng quy tắc chuỗi để viết như sau: trong đó là phân phối biên của . Lưu ý rằngP P P ( n 1 , ĐI , n IB , b 1 : I )P(n1,,nIB,b1:I)PP P(ntôi|B,b1:Tôi)=Σ n 1 ,..., n tôi - 1 P(n1,...,ntôi|B,b1:Tôi)ntôiP(ntôi|B,b1:I)nIB-

P(n1,,nIB,b1:I)=P(nIB,b1:I)P(n1,,nI1nI,B,b1:I)=P(nIB,b1:I)P(n1,,nI1BnI,b1:I1)(1)
P(nI|B,b1:I)=n1,,nI1P(n1,,nI|B,b1:I)nIP(nI|B,b1:I)là một phân phối rời rạc và có thể được tính toán hiệu quả bằng cách sử dụng lập trình động. Ngoài ra, lưu ý rằng thuật ngữ thứ hai trong (1) có thể được tính toán đệ quy. Chúng tôi lấy mẫu trong vòng đầu tiên của đệ quy, cập nhật tổng số bóng thành và tái diễn thành mẫu trong vòng tiếp theo.nIn tôi - 1BnInI1

Sau đây là một triển khai Matlab của ý tưởng. Độ phức tạp của thuật toán là trong đó . Mã sử ​​dụng s được tạo ngẫu nhiên trong mỗi lần chạy. Do đó, một số trường hợp thử nghiệm được tạo có thể không có bất kỳ giải pháp hợp lệ nào, trong trường hợp đó, mã in ra một thông báo cảnh báo.O(I×B×K)K=maxi=1Ibimi

global dpm b

I = 5; % number of colors
N = 300; % total number of balls

m = randi(50, 1, I)-1; % minimum number of balls from each from each color
M = 99*ones(1, I); % maximum number of balls from each color

% print original constraints
print_constraints(I, N, m, M, 'original constraints');

% remove the lower bound constraints
b = M - m;
B = N - sum(m);
m = zeros(size(m));

% print transformed constraints
print_constraints(I, B, zeros(1, I), b, 'transformed constraints');

% initialize the dynamic programming matrix (dpm)
% if dpm(i, n) <> -1, it denotes the value of the following marginal probability
% \sum_{k=1}^{i-1} P(n_1, ..., n_i |
dpm = -ones(I, B);

% sample the number of balls of each color, one at a time, using chain rule
running_B = B;  % we change the value of "running_B" on the fly, as we sample balls of different colors
for i = I : -1 : 1
    % compute marginal distribution P(n_i)

    % instead of P(n_i) we compute q(n_i) which is un-normalized.
    q_ni = zeros(1, b(i) + 1); % possibilities for ni are 0, 1, ..., b(i)
    for ni = 0 : b(i)
        q_ni(ni+1) = dpfunc(i-1, running_B-ni);
    end
    if(sum(q_ni) == 0)
        fprintf('Impossible!!! constraints can not be satisfied!\n');
        return;
    end
    P_ni = q_ni / sum(q_ni);
    ni = discretesample(P_ni, 1) - 1;
    fprintf('n_%d=%d\n', i, ni);
    running_B = running_B - ni;
end

trong đó hàm print_constraint

function [] = print_constraints(I, N, m, M, note)
    fprintf('\n------ %s ------ \n', note);
    fprintf('%d <= n_%d <= %d\n', [m; [1:I]; M]);
    fprintf('========================\n');
    fprintf('sum_{i=1}^%d n_i = %d\n', I, N);
end

và hàm dpfunc thực hiện tính toán lập trình động như sau:

function res = dpfunc(i, n)
    global dpm b

    % check boundary cases
    if(n == 0)
        res = 1;
        return;
    end
    if(i == 0) % gets here only if n <> 0
        res = 0;
        return;
    end

    if(n < 0)
        res = 0;
        return;
    end

    if(dpm(i, n) == -1) % if <> -1, it has been compute before, so, just use it!
        % compute the value of dpm(i, n) = \sum_{n_1, ..., n_i} valid(n, n_1, ..., n_i)
        % where "valid" return 1 if \sum_{j=1}^i n_i = n and 0 <= n_i <= b_i, for all i
        % and 0 otherwise.
        dpm(i, n) = 0;
        for ni = 0 : b(i)
            dpm(i, n) = dpm(i, n) + dpfunc(i-1, n-ni);
        end
    end
    res = dpm(i, n);
end

và cuối cùng, hàm rời rạc (p, 1) rút ra một mẫu ngẫu nhiên từ phân phối rời rạc . Bạn có thể tìm thấy một triển khai của chức năng này ở đây .p


1
Bạn có thể giải thích lý do tại sao bạn nghĩ rằng phân phối cận biên là đa quốc gia?
whuber

Tôi có nghĩa là phân phối phân loại / rời rạc, cảm ơn bạn đã phát hiện ra nó. Tôi chỉ sửa nó trong câu trả lời của tôi!
Sobi

1
@sobi - Dòng mã có nghĩa là gì: q_ni (ni + 1) = dpfunc (i-1, running_B văn bản mạnh -ni)? Có một số vấn đề định dạng?
GPB

@GPB: không chắc văn bản mạnh đến mức nào ! Nó phải được gỡ bỏ. Cảm ơn vì đã phát hiện ra điều này; đã sửa! Mã này mất một lúc để chạy (một vài giây) bởi vì nó có rất nhiều vòng lặp, nếu các câu lệnh và hàm đệ quy gọi tất cả chúng đều đặc biệt chậm trong Matlab, do đó, việc triển khai C ++ sẽ chạy nhanh hơn nhiều!
Sobi

@Sobi - Tôi đang mã hóa bằng Python, sẽ chia sẻ với bạn khi hoàn thành ....
GPB

2

Chúng ta hãy xem xét một khái quát của vấn đề này. Có lon sơn màu khác biệt và quả bóng. Có thể có thể chứa đến quả bóng. Bạn muốn tạo ra các cấu hình của quả bóng trong lon có ít nhất bóng trong có thể cho mỗi , mỗi cấu hình với xác suất bằng nhau.m = 4 n ( 0 ) = 100 i một ( 0 ) i = ( 100 , 100 , 50 , 75 ) b i = ( 0 , 50 , 0 , 25 ) i im=4m=4n(0)=100iai(0)=(100,100,50,75)bi=(0,50,0,25)ii

Các cấu hình như vậy tương ứng một-một với các cấu hình thu được sau khi loại bỏ các bóng khỏi can , giới hạn quả bóng còn lại tối mỗi . Vì vậy, tôi sẽ chỉ tạo ra những điều này và cho phép bạn điều chỉnh chúng sau đó (bằng cách đặt quả bóng trở lại vào thể cho mỗi ).biin=n(0)ibi=100(0+50+0+25)=25ai=ai(0)bi=(100,50,50,50)biii

Để đếm các cấu hình này, hãy sửa tất cả trừ hai trong số các chỉ số, giả sử và . Giả sử đã có bóng trong can cho mỗi khác với và . Điều đó để lại bóng. Có điều kiện ở nơi có các bóng khác, chúng được phân phối đồng đều trong lon và . Các cấu hình có thể là về số lượng (xem các nhận xét), từ việc đặt càng nhiều bóng vàoijskkkijsi+sjn(si+sj)ij1+min(ai+ajsisj,si+sj)icàng tốt càng tốt thông qua việc đặt càng nhiều quả bóng vào càng tốt càng tốt.j

Nếu bạn muốn, bạn có thể đếm tổng số cấu hình bằng cách áp dụng đệ quy đối số này cho các lon còn lại . Tuy nhiên, để có được các mẫu, chúng tôi thậm chí không cần biết số lượng này. Tất cả những gì chúng ta cần làm là liên tục truy cập tất cả các cặp không có thứ tự có thể của lon và ngẫu nhiên (và thống nhất) thay đổi sự phân phối các quả bóng trong hai lon đó. Đây là chuỗi Markov với phân phối xác suất giới hạn đồng nhất trên tất cả các trạng thái có thể (như được hiển thị dễ dàng bằng các phương pháp tiêu chuẩn). Vì vậy, nó đủ để bắt đầu trong bất kỳm2{i,j}trạng thái, chạy chuỗi đủ lâu để đạt được phân phối giới hạn và sau đó theo dõi các trạng thái được truy cập bởi thủ tục này. Như thường lệ, để tránh tương quan nối tiếp, chuỗi trạng thái này phải được "làm mỏng" bằng cách bỏ qua chúng (hoặc xem lại ngẫu nhiên). Làm loãng theo hệ số khoảng một nửa số lon có xu hướng hoạt động tốt, bởi vì sau đó, nhiều bước trung bình mỗi cái có thể bị ảnh hưởng, tạo ra một cấu hình thực sự mới.

Thuật toán này tốn trung bình để tạo trung bình mỗi cấu hình ngẫu nhiên. Mặc dù các thuật toán tồn tại, nhưng thuật toán này có ưu điểm là không cần phải thực hiện các phép tính tổ hợp trước.O(m)O(m)


Ví dụ, chúng ta hãy giải quyết một tình huống nhỏ hơn bằng tay. Hãy để và , ví dụ. Có 15 cấu hình hợp lệ, có thể được viết dưới dạng chuỗi các số chiếm. Ví dụ, đặt hai quả bóng vào hộp thứ hai và một quả bóng trong hộp thứ tư. Mô phỏng lập luận, chúng ta hãy xem xét tổng công suất của hai lon đầu tiên. Khi đó là quả bóng, không còn quả bóng nào trong hai lon cuối cùng. Điều đó mang lại cho các tiểu bangn = 3 s 1 + s 2 = 3a=(4,3,2,1)n=30201s1+s2=3

30**, 21**, 12**, 03**

trong đó **đại diện cho tất cả các số chiếm hữu có thể cho hai lon cuối cùng: cụ thể là 00. Khi , các trạng thái làs1+s2=2

20**, 11**, 02**

ở đâu bây giờ **có thể là 10hay 01. Điều đó cho trạng thái nữa. Khi , các trạng thái làs 1 + s 2 = 13×2=6s1+s2=1

10**, 01**

bây giờ **có thể 20, 11nhưng không 02 (do giới hạn của một quả bóng trong hộp cuối cùng). Điều đó cho trạng thái nữa. Cuối cùng, khi , tất cả các quả bóng nằm trong hai lon cuối cùng, phải đầy đủ giới hạn và . Do đó, trạng thái có thể xảy ra như nhaus 1 + s 2 = 0 2 1 4 + 6 + 4 + 1 = 152×2=4s1+s2=0214+6+4+1=15

3000, 2100, 1200, 0300; 2010, 2001, 1110, 1101, 0210, 0201; 1020, 1011, 0120, 0111; 0021.

Sử dụng mã dưới đây, một chuỗi gồm cấu hình như vậy đã được tạo và làm mỏng đến từng phần ba, tạo ra cấu hình của trạng thái. Tần số của chúng là như sau:3337 1510,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 

Một kiểm tra thống nhất đưa ra một giá trị , ( bậc tự do): đó là thỏa thuận đẹp với giả thuyết rằng thủ tục này tạo ra trạng thái như nhau có thể xảy ra.χ 2 11,2χ2χ211.214p=0.6714


Đây Rđang được thiết lập để xử lý các tình huống trong câu hỏi. Thay đổi anlàm việc với các tình huống khác. Đặt Nđủ lớn để tạo số lượng thực hiện bạn cần sau khi pha loãng .

Mã này gian lận một chút bằng cách đạp xe một cách có hệ thống qua tất cả các cặp . Nếu bạn muốn trở thành nghiêm ngặt về việc chạy chuỗi Markov, tạo ra , và một cách ngẫu nhiên, như được đưa ra trong các mã nhận xét. (i,j)ijij

#
# 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)

cảm ơn rất nhiều ... Tôi đang xử lý phản hồi này và phản hồi khác tối nay và hy vọng sẽ trở lại vào ngày mai.
GPB

1
Bạn có thể giải thích tại sao số cách có thể để phân phối bóng si + sj trong lon i và j là 1 + ai + aj − si − sj không? Ví dụ: nếu ai = 0, chỉ có một cách có thể (đó là đặt tất cả các bóng si + sj vào can j). Nhưng, theo công thức của bạn, nên có 1 + 0 + aj + 0-sj = 1 + aj-sj các cách có thể, và aj-sj có thể được chọn sao cho số đó lớn hơn tùy ý 1. Ngoài ra, bạn có thể giải thích tại sao thời gian chạy của thuật toán là O (m)?
Sobi

1
@Sobi Có khoảng trống có sẵn và bóng để đặt vào chúng. Các cấu hình tương ứng với đẻ ra khe trong một hàng với một chia giữa chúng (để tách hai lon) và điền vào một tiếp giáp chuỗi các những khe bao gồm hoặc tiếp giáp với chia. Điều đó có nghĩa là khi , giá trị chỉ là , vì vậy đại lượng chính xác là . Tôi đã kết hợp sự thay đổi đó trong câu trả lời này. Cảm ơn bạn đã chỉ ra điều này! Thuật toán, như được gói gọn trong hàm , rõ ràng là . ai+ajsi+sjai+ajsi+sjsi+sj<ai+ajsi+sj+1min(ai+ajsisj,si+sj)+1gO(m)
whuber

1
Xét . Công thức mới cho nhưng chỉ có 2 cách có thể. Tôi nghĩ rằng công thức sau sẽ hoạt động: . Số lượng đầu tiên / giây là số lượng bóng tối đa / tối thiểu mà có thể có. ai=1,aj=3,si+sj=2min(1+32,2)+1=3min(ai,si+sj)max(0,si+sjaj)+1i
Sobi

1
Có, tôi tin rằng thời gian trộn là nhưng không thành vấn đề nếu đó là . Với đủ số lần lặp (mà chúng ta có khi dự tính kết quả tiệm cận), đóng góp đơn vị của sự pha trộn là , không đáng kể. Tuy nhiên, là bởi vì nó tạo ra một trạng thái mới mỗi lần nó chạy và chỉ cần xuất ra một trạng thái là một hoạt động . Thinning cũng không làm tổn thương kết quả. Một cách để làm mỏng là tạo ra một số lượng lớn thực hiện và sắp xếp lại chúng (có lẽ bằng cách di chuyển qua chúng theo chu kỳ với một bước tiến lớn), chỉ mất nỗ lực . O ( f ( m ) ) N O ( f ( m ) / N ) O ( m ) O ( m ) N O ( N )O(m)O(f(m))NO(f(m)/N)gO(m)O(m)NO(N)
whuber
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.