【问题标题】:How to simulate a martingale process problem in R?如何在 R 中模拟鞅过程问题?
【发布时间】:2021-10-02 19:29:41
【问题描述】:

100个人在看戏。演出结束时,所有人都到衣帽间去拿他们的外套。衣帽间工作的人完全随机地把人们的外套还给他们。他们的参与者选对了外套就走。选错了的人把外套还给他,男的又随机还给了外套。当剧院的所有顾客都拿回了他们正确的外套时,这个过程就结束了。

我想在 R 中模拟这个鞅过程,以便找到这个过程结束的预期时间。 但我不知道如何。有什么帮助吗? 比如:



# 100 customers
x = seq(1,100,by=1);x
# random sample from x 
y = sample(x,100,replace=FALSE)
x==y
# for the next iteration exclude those how are TRUE and run it again until everyone is TRUE


预期时间是需要多少次迭代。

或者类似的东西:


n = 100
X = seq(1,100,by=1)
martingale = rep(NA,n)

iterations = 0
accept     = 0
while (X != n) {
  iterations =  iterations + 1
  y = sample(1:100,100,replace=FALSE)
  if (X = y){ 
    accept = accept + 1
    X = X+1
    martingale [X] = y
  }
}
accept
iterations

【问题讨论】:

  • 对这个问题最清晰但不一定最有效的解决方案是运行一个while循环来模拟这个过程;每次通过循环,对当前客户和当前外套进行采样,并使用if 语句相应地更新客户和外套列表(如果不匹配则保持不变,否则从客户列表/向量中删除客户和外套列表/向量中的外套)
  • 好的,您刚刚添加的解决方案看起来很合理。它有效吗?如果不是,它有什么作用?
  • @BenBolker 不,它当然不起作用。我把它当作伪代码。但你的描述看起来更好。但我仍然不知道该怎么做。
  • @BenBolker 您是说会有两个向量:a)客户和 b)外套。每次我必须从两个向量中排除匹配项。当两个向量都将结束时,该过程将结束是空的。对吧?我在想有一个向量并删除每个迭代匹配。但我不知道我是否正确。
  • 是的,我认为你可以用一个向量来做到这一点。您将从留下的向量中独立地抽取两个样本ij;如果i == j 然后remaining <- remaining[-i]

标签: r random simulation


【解决方案1】:

一种方法如下(以10人为例,打印语句是不必要的,只是为了展示每次迭代做了什么):

set.seed(0)
x <- 1:10
count <- 0
while(length(x) > 0){
  x <- x[x != sample(x)]
  print(x)
  count <- count + 1
}

# [1]  1  2  3  4  5  6  7  9 10
# [1] 3 4 5 6 7 9
# [1] 3 4 5 6 7
# [1] 3 4 5 6 7
# [1] 3 4 5 6 7
# [1] 3 4 5 6 7
# [1] 3 4 5 6 7
# [1] 3 4 5 6 7
# [1] 3 6
# 
count
# [1] 10

对于循环中的每一步,它都会删除客户被随机分配外套的 x 值,直到没有剩余。

要使用此代码获取 100 人的预期时间,您可以将其扩展为:

set.seed(0)
nits <- 1000 #simulate the problem 1000 times
count <- 0
for (i in 1:nits){
  x <- 1:100
  while(length(x) > 0){
    x <- x[x != sample(x)]
    count <- count + 1/nits
  } 
}
count
# [1] 99.901

我在没有证据的情况下假设 n 人的预期时间是 n 次迭代 - 当我尝试 50、100 或 200 人时,它似乎非常接近。

【讨论】:

  • 非常有用、简单且有意义的代码,但只有一个问题。从第 3 次到第 9 次迭代,它没有找到匹配项。因为 3,4,5,6,7 仍然没有匹配项。
  • 是的,只是随机模拟的运气,有几次没有正确分配的迭代。如果你想找到预期的时间,你需要多次运行整个代码(不包括set.seed)并取平均计数
【解决方案2】:

我没有关注你上面的讨论,我不完全确定这是否是你想要的,但我的理由如下:

  • 您有 N 个人并排队。
  • 在第一轮比赛中,第一人有 1/N 的机会获得正确的衣服。
  • 此时您有两个选择。 Eitehr 人 1 的衣服穿对与否。
  • 如果第 1 个人穿对了衣服,那么第 2 个人有 1/(N-1) 的机会穿对了衣服。如果第 1 个人没有穿上正确的衣服,第 1 个人会留在池中(最后),第 2 个人也有 1/N 的概率可以穿上正确的衣服。
  • 您继续分配这些概率,直到所有 N 个人都见过店员一次。然后你挑选出那些穿对了衣服的人,并在第 1 步重复,直到每个人都穿对了。
  • 出于模拟目的,您当然会重复整个过程 1000 或 10000 次。

如果我的理解正确,您对迭代次数感兴趣,即店员必须多久完成一次整个队列(或剩下的队列),直到每个人都穿好衣服。

图书馆(tidyverse)

people <- 100
results <- data.frame(people     = 1:people,
                      iterations = NA)

counter <- 0
finished <- 0

while (finished < people)
{
  loop_people <- results %>%
    filter(is.na(iterations)) %>%
    pull(people)

  loop_prob <- 1/length(loop_people)
  loop_correct <- 0

  for (i in 1:length(loop_people))
  {
    correct_clothes_i <- sample(c(0,1), size = 1, prob = c(1-loop_prob, loop_prob))
    if (correct_clothes_i == 1)
    {
      results[loop_people[i], 2] <- counter + 1
      loop_correct <- loop_correct + 1
      loop_prob <- 1/(length(loop_people) - loop_correct)
    }
  }
  counter <- counter + 1
  finished <- length(which(!is.na(results$iterations)))
}

max(results$iterations)

[1] 86

head(results)

  people iterations
1      1          7
2      2         42
3      3         86
4      4         67
5      5          2
6      6          9

results$iterations 列包含每个人正确穿衣服的迭代次数,因此max(results$iterations) 为您提供循环总数。

我没有证据,但根据经验和直觉,所需的迭代次数应该接近 N。

【讨论】:

  • 他们不在队列中。总共有N=100。第一次匹配后会剩下97。以此类推……问题是店员随机分享了多少次外套,直到每个人都选对了。
  • 但是店员随便挑衣服吧?然后他一次给一个人看。如果店员同时向所有人展示,那么在第一次迭代中有人会挑选合适的衣服的概率为 1。在第二次迭代中,您的概率再次为 1。但是您恰好有 N 次迭代,但我认为这不是您想要的?
  • 不。我很抱歉造成混乱。只是给随机的人随机的外套。如果有匹配,他们会离开。剩下的客户继续处理。
  • 在这种情况下,@Miff 的解决方案似乎是正确的。但是理论上的结果还是一样的。从长远来看,您需要 N 次迭代,直到每个人都穿上合适的衣服。
猜你喜欢
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 2017-06-27
  • 2019-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多