Brain Teaser:pr(head)= pのバイアスされたコインを使用して、等しい確率で7つの整数を生成する方法


58

これは、Glassdoorで見つけた質問です。コインを使用して、等しい確率で7つの整数をどのように生成しますか?Pr(Head)=p(0,1

基本的に、あなたは公平かもしれないし、そうでないかもしれないコインを持っています、そしてこれはあなたが持っている唯一の乱数生成プロセスであるので、これらの各整数を得る確率が1から7までの整数を出力する乱数ジェネレータを考え出します1/7です。

データ生成プロセスの効率が重要です。



12
これを達成するための無数の方法があります。質問のより興味深いバージョンでは、明確に定義された意味で最良の方法を求めています。最良の自然な感覚は、生成される整数あたりのフリップの最小予想数です。別の興味深いバージョンは、可能なすべての解決策を説明することです(コインの独立したフリップに依存し、それ以上はありません)。
whuber

1
@whuber良い提案、あなたのコメントを反映するために質問を編集しました。
アマゾンの

<<<基本的に、あなたは公平であるかもしれない、またはそうでないかもしれないコインを持っています、そしてこれはあなたが持っている唯一の乱数生成プロセスです>>>それは別の乱数生成プロセスになるので、対尾は「禁止」されていますか?
TinglTanglBob

9
コインの今年のMod 7。
ナット

回答:


56

コインを2回裏返します。着陸したHH場合TT、または無視して、もう一度2回裏返します。

さて、コインが来るの等しい確率があるHTかをTH。それが現れたらHT、これを呼んでくださいH1。それが現れたらTH、これを呼んでくださいT1

取得を続けるH1T1、3つ連続するまで。これらの3つの結果は、以下の表に基づいた数値を提供します。

H1 H1 H1 -> 1
H1 H1 T1 -> 2
H1 T1 H1 -> 3
H1 T1 T1 -> 4
T1 H1 H1 -> 5
T1 H1 T1 -> 6
T1 T1 H1 -> 7
T1 T1 T1 -> [Throw out all results so far and repeat]

処理中に多くの無駄なスローが発生しますが、これは完全にうまく機能すると主張します!


4
唯一の制約は、ヘッドの確率が「p」であることです。pはまたは可能性があることに注意してください。そのため、これが機能することは保証されていませんが、Sycorax(またはSephan)が機能するのは、そのような場合でもです。101
グング-モニカの復職

8
@gung:頭が2つ、または尾が2つあるコインで働くかどうかわかりません。
S. Kolassa -モニカ元に戻し

6
確率では、有限時間で終了します。1
クラーク

18
これは、フォンノイマンホワイトニングと呼ばれます。
-DonFusili

4
フォンノイマン抽出器を反復処理して、シーケンスからエントロピーをより完全に抽出できます。等...、それにフォン・ノイマン抽出を適用し、すべてのHHおよびTTのペアを収集し、シーケンスことを考える
シモンズ

47

と仮定します。p(0,1)

ステップ1: 。コインを5回投げます。

結果が

1(H,H,H,T,T)、を返して停止します。1

2(H,H,T,T,H)、を返し、停止します。2

3(H,T,T,H,H)、を返し、停止します。3

4(T,T,H,H,H)、を返し停止します。4

5(T,H,H,H,T)、を返し、停止します。5

6(H,H,T,H,T)、を返し、停止します。6

7(H,T,H,T,H)、を返し、停止します。7

ステップ2: 。結果が上記のいずれでもない場合は、手順1を繰り返します。

の値に関係なく、上記の7つの結果はそれぞれ確率であり、コイン投げの予想数はであることに注意してください。。トッサーはの値を知る必要はありません(およびを除く)。7つの整数が、実験の終了時に等しく返される可能性が高いことが保証されています(確率終了することが保証されています)。Q = P 31 - P 2 5p(0,1)q=p3(1p)2 pp0p1157qpp0p11


6
ここで指定されたシーケンスまたは各フリップを反転したシーケンスのいずれかを許可することで、このために予想されるトスの回数を減らすことができます。例:1の場合、(H、H、H、T、T)または(T、T、T、H、H)?
詳細

5
補数を追加することもできます。結果が(H、H、H、T、T)または(T、T、T、H、H)の場合、1を返し、停止するなど。その場合、各結果の確率はq=p3(1p)2+p2(1p)3
セクストゥスエンピリカス

2
結果が(H、H、H、T、T)の配置を欠いていない場合は、別のコインフリップを追加することはできませんか?追加のコイントスでは、(H、H、H、T、T、T)および(H、H、T、T、T、T)および各xT(7-x)Hの組み合わせの別のマッピングが必要になります5つすべてのコインを再投入する代わりに、追加のトスを1つだけ追加しますが、動作するかどうかは
わかり

5
コインを7回即座にフリップするのが最善の方法かもしれません。保証されているよりも、乱数を取り出すことができるからです(したがって、例外は、コインが7回トライアップすることです) 。したがって、7回のトスでは、1から6までのヘッドになります(無意味なので、ここでは0と7のオプションを除外します)。1つのヘッドに(H、T、T、T、T、T、T)の7つの異なる配置がある場合; 2が21の場合; 3が35の場合。4 35頭の場合; 5 21頭の場合; 6 7頭の場合; 組み合わせを失うことなく、それぞれを番号1〜7に完全にマッピングできます。
-TinglTanglBob

2
@TinglTanglBobこれは基本的にマーティン・ウェタリングの答えです
;

22

Dilip Sarwateによって記述されたケースの一般化

他の回答で説明されている方法のいくつかは、「ターン」でnコインのシーケンスを投げるスキームを使用し、結果に応じて1または7の間の数字を選択するか、ターンを捨てて再び投げます。

秘Theは、可能性の拡大において、同じ確率pk(1p)nkで7つの倍数の結果を見つけ、それらを互いに照合することです。

結果の総数は7の倍数ではないため、数に割り当てることができないいくつかの結果があり、結果を破棄してやり直す必要がある可能性があります。


ターンごとに7コインフリップを使用する場合

直観的には、サイコロを7回振るのは非常に興味深いと言えます。27可能性のうち2つを捨てるだけです。つまり、7回のヘッドと0回のヘッドです。

他のすべての可能性については、常に同じ数の頭を持つ7の倍数のケースがあります。つまり、1頭の7ケース、2頭の21ケース、3頭の35ケース、4頭の35ケース、5頭の21ケース、6頭の7ケースです。272

したがって、数値を計算すると(0頭と7頭を破棄)

X=k=17(k1)Ck

ベルヌーイ変数(値0又は1)を分散し、Xモジュロ7は、7つの可能な結果を有する均一な変数です。Ck


ターンごとの異なるコインフリップの数の比較

問題は、1ターンあたりの最適なロール数です。1ターンあたりのサイコロの数を増やすとコストがかかりますが、再度サイコロを振る確率が減ります。

以下の画像は、1ターンあたりの最初の数回のコインフリップの手動計算を示しています。(おそらく分析ソリューションがあるかもしれませんが、コインフリップが7回あるシステムが、必要なコインフリップの数に対する期待値に関して最良の方法を提供すると言っても安全だと思います)

コインフリップの予想数

# plot an empty canvas
plot(-100,-100,
     xlab="flips per turn",
     ylab="E(total flips)",
     ylim=c(7,400),xlim=c(0,20),log="y")
title("expectation value for total number of coin flips
(number of turns times flips per turn)")

# loop 1
# different values p from fair to very unfair 
# since this is symmetric only from 0 to 0.5 is necessary 

# loop 2
# different values for number of flips per turn
# we can only use a multiple of 7 to assign 
#   so the modulus will have to be discarded
#   from this we can calculate the probability that the turn succeeds
#   the expected number of flips is 
#       the flips per turn 
#             divided by 
#       the probability for the turn to succeed 

for (p in c(0.5,0.2,0.1,0.05)) {
  Ecoins <- rep(0,16)
  for (dr in (5:20)){
    Pdiscards = 0
    for (i in c(0:dr)) { 
      Pdiscards = Pdiscards + p^(i)*(1-p)^(dr-i) * (choose(dr,i) %% 7)
    }
    Ecoins[dr-4] = dr/(1-Pdiscards)
  }
  lines(5:20, Ecoins)
  points(5:20, Ecoins, pch=21, col="black", bg="white", cex=0.5)
  text(5, Ecoins[1], paste0("p = ",p), pos=2)
}

早期停止ルールを使用する

注:フリップ数の期待値に対する以下の計算は、公正なコインに対するものであり、異なるに対してこれを行うのは混乱になりますが、原則は同じままです(ただし、ケースが必要です)p=0.5p

(の式の代わりに)ケースを選択して、より早く停止できるようにする必要があります。X

  • 5つのコインフリップを使用して、6つの異なる順序のない頭と尾のセットを用意しています。

    1 + 5 + 10 + 10 + 5 + 1順序付きセット

    そして、10個のケースを持つグループ(つまり、2つの頭を持つグループまたは2つの尾を持つグループ)を使用して、(同じ確率で)数を選択できます。これは、2 ^ 5 = 32の場合のうち14の場合に発生します。これにより、次のことができます。

    1 + 5 + 3 + 3 + 5 + 1順序セット

  • 余分な(6番目の)コインフリップにより、7つの異なる順序のない頭と尾のセットがあります。

    1 + 6 + 8 + 6 + 8 + 6 + 1順序付きセット

    そして、8つのケースを持つグループ(つまり、3つの頭を持つグループまたは3つの尾を持つグループ)を使用して(等しい確率で)数を選択できます。これは、2 *(2 ^ 5-14)= 36ケースのうち14ケースで発生します。これにより、次のことができます。

    1 + 6 + 1 + 6 + 1 + 6 + 1順序セット

  • 別の(7番目の)余分なコインフリップを使用して、8つの可能な異なる順序のない頭と尾のセットを用意しています。

    1 + 7 + 7 + 7 + 7 + 7 + 7 + 1順序付きセット

    そして、7つのケース(すべてのテールとすべてのヘッドのケースを除くすべて)を持つグループを使用して、(同じ確率で)数を選択できます。これは、44件中42件で発生しています。これにより、次のことができます。

    1 + 0 + 0 + 0 + 0 + 0 + 0 + 1順序付きセット

    (これを継続することもできますが、49番目のステップでのみこれが有利になります)

したがって、数字を選択する確率

  • 5回のフリップで1432=716
  • 6回のフリップで9161436=732
  • 7フリップで11324244=231704
  • 7フリップではありません1716732231704=227

これにより、1ターンのフリップ数の期待値が、成功とp = 0.5を条件としています。

5716+6732+7231704=5.796875

フリップの合計数の期待値(成功するまで)は、p = 0.5を条件として、次のようになります。

5716+6732+723170427272=539=5.88889


NcAdamsの答えは、この停止ルール戦略のバリエーションを使用しています(毎回2つの新しいコインフリップを思い付きます)が、すべてのフリップを最適に選択しているわけではありません。

Clidの答えも同様かもしれませんが、2つのコインフリップごとに数字を選択するという不均一な選択ルールがあるかもしれませんが、必ずしも同じ確率ではありません(後のコインフリップ中に修復される矛盾)


他の方法との比較

同様の原理を使用する他の方法は、NcAdamsとAdamOによるものです。

原則は次のとおりです。1〜7の間の数の決定は、一定数の頭と尾の後に行われます。のフリップの後、数字につながる各決定について、数字(同じ数の頭と尾ですが、順序が異なる)につながる同様の確率のある決定があります。頭と尾のいくつかのシリーズは、最初からやり直す決定につながる可能性があります。バツj

そのようなタイプの方法では、ここに配置されたものが最も効率的です(可能な限り早く決定を下すためです(バツ回目のフリップの後、頭と尾の7つの等しい確率シーケンスの可能性があると、番号を決定するためにそれらを使用し、それらのケースのいずれかが発生した場合、さらにフリップする必要はありません)。

これは、以下の画像とシミュレーションで実証されています。

比較

#### mathematical part #####
set.seed(1)


#plotting this method
p <- seq(0.001,0.999,0.001)
tot <- (5*7*(p^2*(1-p)^3+p^3*(1-p)^2)+
       6*7*(p^2*(1-p)^4+p^4*(1-p)^2)+
       7*7*(p^1*(1-p)^6+p^2*(1-p)^5+p^3*(1-p)^4+p^4*(1-p)^3+p^5*(1-p)^2+p^6*(1-p)^1)+
        7*1*(0+p^7+(1-p)^7) )/
             (1-p^7-(1-p)^7)
plot(p,tot,type="l",log="y",
     xlab="p",
     ylab="expactation value number of flips"
     )

#plotting method by AdamO
tot <- (7*(p^20-20*p^19+189*p^18-1121*p^17+4674*p^16-14536*p^15+34900*p^14-66014*p^13+99426*p^12-119573*p^11+114257*p^10-85514*p^9+48750*p^8-20100*p^7+5400*p^6-720*p^5)+6*
          (-7*p^21+140*p^20-1323*p^19+7847*p^18-32718*p^17+101752*p^16-244307*p^15+462196*p^14-696612*p^13+839468*p^12-806260*p^11+610617*p^10-357343*p^9+156100*p^8-47950*p^7+9240*p^6-840*p^5)+5*
          (21*p^22-420*p^21+3969*p^20-23541*p^19+98154*p^18-305277*p^17+733257*p^16-1389066*p^15+2100987*p^14-2552529*p^13+2493624*p^12-1952475*p^11+1215900*p^10-594216*p^9+222600*p^8-61068*p^7+11088*p^6-1008*p^5)+4*(-
          35*p^23+700*p^22-6615*p^21+39235*p^20-163625*p^19+509425*p^18-1227345*p^17+2341955*p^16-3595725*p^15+4493195*p^14-4609675*p^13+3907820*p^12-2745610*p^11+1592640*p^10-750855*p^9+278250*p^8-76335*p^7+13860*p^6-
          1260*p^5)+3*(35*p^24-700*p^23+6615*p^22-39270*p^21+164325*p^20-515935*p^19+1264725*p^18-2490320*p^17+4027555*p^16-5447470*p^15+6245645*p^14-6113275*p^13+5102720*p^12-3597370*p^11+2105880*p^10-999180*p^9+371000
           *p^8-101780*p^7+18480*p^6-1680*p^5)+2*(-21*p^25+420*p^24-3990*p^23+24024*p^22-103362*p^21+340221*p^20-896679*p^19+1954827*p^18-3604755*p^17+5695179*p^16-7742301*p^15+9038379*p^14-9009357*p^13+7608720*p^12-
           5390385*p^11+3158820*p^10-1498770*p^9+556500*p^8-152670*p^7+27720*p^6-2520*p^5))/(7*p^27-147*p^26+1505*p^25-10073*p^24+49777*p^23-193781*p^22+616532*p^21-1636082*p^20+3660762*p^19-6946380*p^18+11213888*p^17-
           15426950*p^16+18087244*p^15-18037012*p^14+15224160*p^13-10781610*p^12+6317640*p^11-2997540*p^10+1113000*p^9-305340*p^8+55440*p^7-5040*p^6)
lines(p,tot,col=2,lty=2)

#plotting method by NcAdam
lines(p,3*8/7/(p*(1-p)),col=3,lty=2)

legend(0.2,500,
       c("this method calculation","AdamO","NcAdams","this method simulation"),
       lty=c(1,2,2,0),pch=c(NA,NA,NA,1),col=c(1,2,3,1))


##### simulation part ######

#creating decision table
mat<-matrix(as.numeric(intToBits(c(0:(2^5-1)))),2^5,byrow=1)[,c(1:12)]
colnames(mat) <- c("b1","b2","b3","b4","b5","b6","b7","sum5","sum6","sum7","decision","exit")

# first 5 rolls
mat[,8] <- sapply(c(1:2^5), FUN = function(x) {sum(mat[x,1:5])})

mat[which((mat[,8]==2)&(mat[,11]==0))[1:7],12] = rep(5,7) # we can stop for 7 cases with 2 heads
mat[which((mat[,8]==2)&(mat[,11]==0))[1:7],11] = c(1:7)   
mat[which((mat[,8]==3)&(mat[,11]==0))[1:7],12] = rep(5,7) # we can stop for 7 cases with 3 heads
mat[which((mat[,8]==3)&(mat[,11]==0))[1:7],11] = c(1:7)    

# extra 6th roll
mat <- rbind(mat,mat)
mat[c(33:64),6] <- rep(1,32)
mat[,9] <- sapply(c(1:2^6), FUN = function(x) {sum(mat[x,1:6])})

mat[which((mat[,9]==2)&(mat[,11]==0))[1:7],12] = rep(6,7) # we can stop for 7 cases with 2 heads
mat[which((mat[,9]==2)&(mat[,11]==0))[1:7],11] = c(1:7)   
mat[which((mat[,9]==4)&(mat[,11]==0))[1:7],12] = rep(6,7) # we can stop for 7 cases with 4 heads
mat[which((mat[,9]==4)&(mat[,11]==0))[1:7],11] = c(1:7)    

# extra 7th roll
mat <- rbind(mat,mat)
mat[c(65:128),7] <- rep(1,64)
mat[,10] <- sapply(c(1:2^7), FUN = function(x) {sum(mat[x,1:7])})

for (i in 1:6) {
  mat[which((mat[,10]==i)&(mat[,11]==0))[1:7],12] = rep(7,7) # we can stop for 7 cases with i heads
  mat[which((mat[,10]==i)&(mat[,11]==0))[1:7],11] = c(1:7)   
}


mat[1,12] = 7           # when we did not have succes we still need to count the 7 coin tosses
mat[2^7,12] = 7


draws = rep(0,100)
num = rep(0,100)
# plotting simulation
for (p in seq(0.05,0.95,0.05)) {
  n <- rep(0,1000)
  for (i in 1:1000) {
    coinflips <- rbinom(7,1,p)  # draw seven numbers
    I <- mat[,1:7]-matrix(rep(coinflips,2^7),2^7,byrow=1) == rep(0,7)                      # compare with the table
    Imatch = I[,1]*I[,2]*I[,3]*I[,4]*I[,5]*I[,6]*I[,7]        # compare with the table 
      draws[i] <- mat[which(Imatch==1),11]                 # result which number
      num[i]   <- mat[which(Imatch==1),12]                 # result how long it took
  }
  Nturn <- mean(num)                   #how many flips we made
  Sturn <- (1000-sum(draws==0))/1000   #how many numbers we got (relatively)
  points(p,Nturn/Sturn)
}

より良い比較のためにp1pでスケーリングされた別の画像:

スケーリングされた期待値との比較

この投稿とコメントで説明されている方法を比較してズームイン

ここで説明する比較方法

「7番目のステップの条件付きスキップ」は、早期停止ルールで行うことができるわずかな改善です。この場合、6回目のフリップの後、等しい確率を持つグループではないものを選択します。確率が等しい6つのグループと、わずかに異なる確率の1つのグループがあります(この最後のグループでは、頭または尾が6つある場合にもう1回余分に反転する必要があり、頭または尾7つを破棄すると終了します)結局同じ確率で)


StackExchangeStrikeによって書かれました。


私は、n = 1よりも良いかもしれないと感じていたので、n = 7の場合の計算を始めようとしていました。賛成です
M.ヘルツカンプ

Ckバツ

そのため、この改善により、必要なコインフリップの数に対する期待値として、コインフリップが6回より少し多くなります。ただし、これが最適なソリューションであることを証明することはさまざまです。CLIDによって作成されたスキームは、コインフリップの特定の数に番号を選択するが、許可ビット発散しない等しい確率で(少なくともその特定のステップのために、それは、後に修正されるであろうが)。
セクストゥスエンピリカス

しかし、最初の5つの結果に基づいて6番目のコインをフリップするかどうかを決定する場合、各セットの確率は、他のセットと同じ6つのフリップになりますか?
蓄積

@Acccumulationでは、7レベルのバイナリツリーとして描画できます。等しい確率の7がある場合にのみノードを選択します。これは、いくつかのブランチを以前に(レベル5または6で)切り刻むようなものです。必要に応じて、以前の代わりに7ステップまで続行できますが、これらの特定のケースでは、6番目と7番目のコインフリップは違いを生じません。
セクストゥスエンピリカス

20

ボックスを7つの等面積領域に分割し、各領域に整数のラベルを付けます。各領域に着地する確率が等しくなるように、コインを箱に投げ込みます。

π

p=1p=0


2
ボックスを7つの等面積領域に分割して、反転、壁の跳ね返りなどによる偏りを最小限に抑える方法を提案できますか?角度360/7の7つのセクター?
smci

1
@smciだから、コインを投げて、各マスにコインが着弾する確率が均一になるようにしなければならないと規定しています。壁の跳ね返りがその確率に影響する場合は、スローでそれを考慮する必要があります。
モニカの

17
はい、私はそれを知っています、そしてそれを達成する方法を正確に定義せずに単に「公平な方法でそれを投げる」と言うことは、本当に完全な答えではないことを指摘しています ...その場合、フリッピングH / Tベースの方法が優れています。
smci

1
「各エリアに着陸する可能性が等しいスローの等しいエリア」は、実際には確立が難しい場合があります。実際には、多数の「練習走行」をマークしてから、ランディングエリアを経験的に等確率のスペースに分割する方が簡単な場合があります(たとえば、700回のスローで、最も遠い100回のスローをカットし、次に100など)。単一のランダムビットを生成するためのこの単純化は、コインを2回投げることです。最初の投球がさらに進んだ場合、ビットは0であり、2番目の投球がさらに進んだ場合は1
Silverfish

4
@TheScienceBoyによる素敵な回答がありますが、これは興味深い代替案で削除されます-事実上、コインをスピナーとして使用し、円周に沿って7つのセクションをマークします-この回答の精神の多くを保持しますが、より物理的に簡単です実行する!
シルバーフィッシュ

8

編集:他のユーザーのフィードバックに基づきます。

ここに興味深い考えがあります:

{1,2,3,4,5,6,7}のリストを設定します。リスト内の各要素のコインを順番に投げます。特定の要素に対して頭を上にして着地した場合は、リストから番号を削除します。リストの特定の反復からすべての数値が削除された場合、サンプリングを繰り返します。番号が1つだけになるまでこれを行います。

drop.one <- function(x, p) {
  drop <- runif(length(x)) < p
  if (all(drop))
    return(x)
  return(x[!drop])
}

sample.recur <- function(x, p) {
  if (length(x) > 1)
    return(sample.recur(drop.one(x, p), p))
  return(x)
}

# x <- c(1:7,7:1)
x <- 1:7
p <- 0.01

out <- replicate(1e5, sample.recur(x, p))

round(prop.table(table(out)), 2)

ほぼ均一な分布が得られます

> round(prop.table(table(out)), 2)
out
   1    2    3    4    5    6    7 
0.14 0.14 0.15 0.14 0.14 0.14 0.14 

N


コイン投入数の期待値の評価

バツy

M=[q700000117p1q6q600000021p2q56p1q5q50000035p3q415p2q45q4q4000035p4q320p3q310p2q34p1q3q300021p5q215p4q210p3q26p2q23p1q2q2007p6q16p5q15p4q14p3q13p2q12p1q100p7p6p5p4p3p200]

Mv=0

以下は、コイン投げの期待値が NcAdamsからの回答と比較する画像です。En=247p1p

コインフリップの期待値の比較

p>2/3

wxMaximaで見つかった解決策

M: matrix(
 [(1-p)^7,        0,          0,0,0,0,1,1], 
 [7* p*(1-p)^6,   (1-p)^6,        0,0,0,0,0,0], 
 [21*p^2*(1-p)^5, 6*p*(1-p)^5,    (1-p)^5,0,0,0,0,0], 
 [35*p^3*(1-p)^4, 15*p^2*(1-p)^4, 5*p*(1-p)^4,(1-p)^4,0,0,0,0], 
 [35*p^4*(1-p)^3, 20*p^3*(1-p)^3, 10*p^2*(1-p)^3,4*p*(1-p)^3,(1-p)^3,0,0,0], 
 [21*p^5*(1-p)^2, 15*p^4*(1-p)^2, 10*p^3*(1-p)^2,6*p^2*(1-p)^2,3*p*(1-p)^2,(1-p)^2,0,0], 
 [7* p^6*(1-p)^1, 6*p^5*(1-p),    5*p^4*(1-p),4*p^3*(1-p),3*p^2*(1-p),2*(1-p)*p,0,0], 
 [p^7,        p^6,        p^5,p^4,p^3,p^2,0,0]
);
z: nullspace(M-diagmatrix(8,1));
x : apply (addcol, args (z));
t : [7,6,5,4,3,2,0,0];
plot2d(t.x/x[7],[p,0,1],logy);

Rでの計算

# plotting empty canvas
plot(-100,-100,
     xlab="p",
     ylab="E(total flips)",
     ylim=c(10,1000),xlim=c(0,1),log="y")

# plotting simulation
for (p in seq(0.1,0.9,0.05)) {

  n <- rep(0,10000)
  for (i in 1:10000) {
    success  = 0
    tests = c(1,1,1,1,1,1,1)     # start with seven numbers in the set
    count = 0
    while(success==0) {
      for (j in 1:7)  {
        if (tests[j]==1) {
          count = count + 1
          if  (rbinom(1,1,p) == 1) {
            tests[j] <- 0        # elliminate number when we draw heads
          }
        }
      }
      if (sum(tests)==1) {
        n[i] = count
        success = 1              # end     when 1 is left over
      }
      if (sum(tests)==0) {
        tests = c(1,1,1,1,1,1,1) # restart when 0 are left over
      }
    }
  }
  points(p,mean(n))
}

# plotting formula
p <- seq(0.001,0.999,0.001)

tot <- (7*(p^20-20*p^19+189*p^18-1121*p^17+4674*p^16-14536*p^15+34900*p^14-66014*p^13+99426*p^12-119573*p^11+114257*p^10-85514*p^9+48750*p^8-20100*p^7+5400*p^6-720*p^5)+6*
    (-7*p^21+140*p^20-1323*p^19+7847*p^18-32718*p^17+101752*p^16-244307*p^15+462196*p^14-696612*p^13+839468*p^12-806260*p^11+610617*p^10-357343*p^9+156100*p^8-47950*p^7+9240*p^6-840*p^5)+5*
    (21*p^22-420*p^21+3969*p^20-23541*p^19+98154*p^18-305277*p^17+733257*p^16-1389066*p^15+2100987*p^14-2552529*p^13+2493624*p^12-1952475*p^11+1215900*p^10-594216*p^9+222600*p^8-61068*p^7+11088*p^6-1008*p^5)+4*(-
    35*p^23+700*p^22-6615*p^21+39235*p^20-163625*p^19+509425*p^18-1227345*p^17+2341955*p^16-3595725*p^15+4493195*p^14-4609675*p^13+3907820*p^12-2745610*p^11+1592640*p^10-750855*p^9+278250*p^8-76335*p^7+13860*p^6-
    1260*p^5)+3*(35*p^24-700*p^23+6615*p^22-39270*p^21+164325*p^20-515935*p^19+1264725*p^18-2490320*p^17+4027555*p^16-5447470*p^15+6245645*p^14-6113275*p^13+5102720*p^12-3597370*p^11+2105880*p^10-999180*p^9+371000
   *p^8-101780*p^7+18480*p^6-1680*p^5)+2*(-21*p^25+420*p^24-3990*p^23+24024*p^22-103362*p^21+340221*p^20-896679*p^19+1954827*p^18-3604755*p^17+5695179*p^16-7742301*p^15+9038379*p^14-9009357*p^13+7608720*p^12-
 5390385*p^11+3158820*p^10-1498770*p^9+556500*p^8-152670*p^7+27720*p^6-2520*p^5))/(7*p^27-147*p^26+1505*p^25-10073*p^24+49777*p^23-193781*p^22+616532*p^21-1636082*p^20+3660762*p^19-6946380*p^18+11213888*p^17-
  15426950*p^16+18087244*p^15-18037012*p^14+15224160*p^13-10781610*p^12+6317640*p^11-2997540*p^10+1113000*p^9-305340*p^8+55440*p^7-5040*p^6)
lines(p,tot)

#plotting comparison with alternative method
lines(p,3*8/7/(p*(1-p)),lty=2)

legend(0.2,500,
       c("simulation","calculation","comparison"),
       lty=c(0,1,2),pch=c(1,NA,NA))

1
賢いアイデア(+1)。対称性は特定の数値への偏りを無効にするように見えるため、直感的に機能するはずです。それでも、私は証拠を見たいです。
モニカを

6
このアイデアは本当に素晴らしいですが、頭の可能性が高い(その数をノックアウトする)行の最後の数が「生き残る」可能性が最も高いと思います。たぶん、コインを順番に投げるのではなく、xのすべての数字を並行して投げることで変更できるでしょうか?スクリプトの実行時間は長くなると思います:)
TinglTanglBob

2
私は@TinglTanglBobに同意する-私が設定したときにp <- 0.99、私は出力を得る0.89 0.02 0.02 0.02 0.02 0.02 0.02
紙魚

6
「ラウンド」で消去を実行すると、バイアスの問題は解決しませんか?7つの数字から始めます。残りのすべての番号のコインを投げ、頭を投げるものを排除します。残りのすべての数字がラウンドで除去された場合、そのラウンドの結果をスクラッチして、再試行してください。私はそれを証明する方法がわかりませんが、直感的に数字の順序は、それらが「勝者」であるかどうかでは重要ではありません
Phil

1
p=0.01

5

質問は少し曖昧で、「等しい確率で7以下のランダムな整数を生成する」か、「等しい確率で7つのランダムな整数を生成する」かを尋ねますか?-しかし、整数の空間は何ですか?!?

前者であると仮定しますが、その問題が解決されれば、後者のケースにも同じロジックを適用できます。

バイアスコインを使用すると、次の手順に従って公平なコインを生成できます。https : //en.wikipedia.org/wiki/Fair_coin#Fair_results_from_a_biased_coin

7以下の数字は、3桁の{0,1}桁の2進数で記述できます。そのため、上記の手順を3回実行し、生成された2進数を10進数に戻すだけです。


1
私の答えを@NcAdamsと比較すると、望ましい結果として0を含めていることが明らかです!
Cam.Davidson.Pilon

あなたの答えがどう違うかわかりません。{0,0,0}-> 1を含めると、{1,1,1}は何にマッピングされますか?8つの可能性があります。
AdamO

1
000は0にマッピングされるため、可能な値として0を含めることに関する私のコメント。これはOP編集の前に投稿され、ほぼ同時にNcAdamsとして投稿されました。
Cam.Davidson.Pilon

この回答の半分はコメントであり、回答の実際の内容はリンクのみです。単にリンクするのではなく、実際の答えを綴ってください。
キュービック

3

フリップを無駄にしないソリューションは、非常に偏りのあるコインに大いに役立ちます。

このアルゴリズムの欠点は(少なくとも書かれているように)、任意精度の演算を使用していることです。実際には、整数オーバーフローまでこれを使用し、それを捨てて最初からやり直します。

また、バイアス何であるかを知る必要があります...たとえば、ほとんどの物理現象のように温度に依存する場合はそうではありません。


頭のチャンスは、例えば、30%であると仮定します。

  • rangeから始めます[1, 8)
  • コインを裏返します。頭の場合は、左の30%を使用するため、新しい範囲は[1, 3.1)です。それ以外の場合は、適切な70%を使用するため、新しい範囲は[3.1, 8)です。
  • 範囲全体の整数部分が同じになるまで繰り返します。

完全なコード:

#!/usr/bin/env python3
from fractions import Fraction
from collections import Counter
from random import randrange


BIAS = Fraction(3, 10)
STAT_COUNT = 100000


calls = 0
def biased_rand():
    global calls
    calls += 1
    return randrange(BIAS.denominator) < BIAS.numerator


def can_generate_multiple(start, stop):
    if stop.denominator == 1:
        # half-open range
        stop = stop.numerator - 1
    else:
        stop = int(stop)
    start = int(start)
    return start != stop


def unbiased_rand(start, stop):
    if start < 0:
        # negative numbers round wrong
        return start + unbiased_rand(0, stop - start)
    assert isinstance(start, int) and start >= 0
    assert isinstance(stop, int) and stop >= start
    start = Fraction(start)
    stop = Fraction(stop)
    while can_generate_multiple(start, stop):
        if biased_rand():
            old_diff = stop - start
            diff = old_diff * BIAS
            stop = start + diff
        else:
            old_diff = stop - start
            diff = old_diff * (1 - BIAS)
            start = stop - diff
    return int(start)


def stats(f, *args, **kwargs):
    c = Counter()
    for _ in range(STAT_COUNT):
        c[f(*args, **kwargs)] += 1

    print('stats for %s:' % f.__qualname__)
    for k, v in sorted(c.items()):
        percent = v * 100 / STAT_COUNT
        print('  %s: %f%%' % (k, percent))


def main():
    #stats(biased_rand)
    stats(unbiased_rand, 1, 7+1)
    print('used %f calls at bias %s' % (calls/STAT_COUNT, BIAS))


if __name__ == '__main__':
    main()

3
[01]00006666k

単一の出力でも同じですよね?複数の方がいいですか?私が思うにそれを書きdiff *= 7ます...実際、各試行に同じベースを使用する必要は特にありません。
o11c

はい、単一の出力が必要な場合も同じです。複数のものが必要な場合にのみ効率が向上します。
フェデリコポロニ

pp

単一の出力が必要な場合、これは絶対にフリップを無駄にします。公正なコインの場合、標準的な手法(コインを3回転がし、TTTを取得したら繰り返す)により、24/7 = 3 + 3/7ロールの予想数が得られます。この算術コーディングスタイルの手法を使用する場合、HHHまたはTTTを取得しない限り、少なくとも4回ロールします。これにより、15/4 = 3 + 3/4ロールを超える予想数が得られます。
ピーターショー

3

以前のコメントで述べたように、このパズルは、ジョン・フォン・ノイマンの1951年の論文「ランダムな数字に関連して使用されるさまざまな技術」に関連しています。

ここに画像の説明を入力してください

pfpf fp={12p}N トライアルの。


2

p1p0

NcAdamsの回答のプロセスを使用して、(おそらく)不公平なコインをまず公正なコインに変えます

コインを2回裏返します。着陸したHH場合TT、または無視して、もう一度2回裏返します。

さて、コインが来るの等しい確率があるHTかをTH。それが現れたらHT、これを呼んでくださいH1。それが現れたらTH、これを呼んでくださいT1

01H1=1T1 =00.H1 H1 T10.110

1/7

1/7=0.001001001

2/7=0.010010010

3/7=0.011011011

4/7=0.100100100

5/7=0.101101101

6/7=0.110110110

nn/7n1/717


1
1/7

1
1/7k=11/8k=17

1
nTn=2n62nn3
3+n=31Tn=4.5
8733.42

2

AdamOの答えに触発されて、バイアスを回避するPythonソリューションを以下に示します。

def roll(p, n):
    remaining = range(1,n+1)
    flips = 0
    while len(remaining) > 1:
        round_winners = [c for c in remaining if random.choices(['H','T'], [p, 1.0-p]) == ['H']]
        flips += len(remaining)
        if len(round_winners) > 0:
            remaining = round_winners
        p = 1.0 - p
    return remaining[0], flips

主な変更点は2つあります。主な変更点は、ラウンドですべての数字が破棄された場合、ラウンドを繰り返すことです。また、毎回、ヘッドとテールのどちらを選択するかを選択します。これにより、p = 0.999の場合、pが0または1に近い場合に必要なフリップの数が〜70%削減されます。


2
「頭と尾のどちらを選ぶかを毎回反転します。これにより、p = 0.999のときにpが0または1に近い場合に必要な反転の数が〜70%減少します」-賢明な思考!
シルバーフィッシュ

1
ヘッドまたはテールを交互に配置することは、常にヘッドを常に破棄するよりも確実に改善されますが、おそらく、残りのオプションごとにコインを裏返した後、それらがすべて同じである場合、すべてを反転させ、それ以外の場合は少なくともテールと同じ数のヘッドを使用して、ヘッドに対応する残りのオプションを削除します。そうでない場合、テールに対応する残りのオプションを削除します。
デビッドケーリー

2

フリップするたびに、各フリップの結果のマッピングを変更することが許可されているようです。したがって、便宜上、最初の7つの正の整数を使用して、次の順序を指定します。

H1
H2

H7
H1

T


APT

PAP整数は生成されません=1p7

Nb

カウントAP無駄なフリップ7Nb1p7

Bpn=5p31p2

PDS整数は生成されません=17p31p2

無駄なフリップの数はここで傾向があります

カウントDS無駄なフリップ5Nb[17p31p2]

AP

カウントAP無駄なフリップ<カウントDS無駄なフリップ

7Nb1p7<5Nb[17p31p2]

71p7<5[17p31p2]

p>0.0467AP

pAPDSp0.5967

カウントAP無駄なフリップカウントDS無駄なフリップ

0.67p=0.10.3p=0.20.127p=0.4


p01

1
@Sycorax何かを追加しましたが、あなたが提案した通りかどうかはわかりません。
アレコスパパドプロス

H

1
この(非常に擬似的な) "乱数"ジェネレーターの解釈(1、2、3、4、5、6、7の等量を持つシーケンスと同様)に進むと、コインをフリップすることはできません。直接番号数字列を取得します12345679999999

1
p17p
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.