教えて!Gooについて回答とか疑問とか

教えて!Gooについて回答とか疑問とか

qa5752707 確率 について

2010-03-15 16:11:10 | 日記
qa5752707 確率
こんなプログラムを書いてみました。
実行結果も示します。


(2)回目の試行後
(0)=847660528
(16)=124692750
(17)=244296000
(18)=263381625
(19)=143071500
(20)=30045015
(40)=42173638
確率(千分率):49

(3)回目の試行後
(0)=1076017653276847424
(22)=30545324589780000
(23)=82860786328320000
(24)=111864923974732500
(25)=85643950494960000
(26)=38287113096053250
(27)=10271284971948000
(28)=1688428190699250
(29)=151390821582000
(30)=5550996791340
(40)=714698899811981084
確率(千分率):664


package test;

import java.math.BigInteger;

public class QA5752707 {

  /**
   * @param args
   */
  public static void main(String[] args) {
    // 現在の状態
    java.math.BigInteger[] mx =  new java.math.BigInteger[42];
    // 試行後の状態
    java.math.BigInteger[] mnext  =  new java.math.BigInteger[42];
    //まず初期化
    for(int i=0;i<41;i++){       mnext[i]  =  BigInteger.ZERO;
    }
    mnext[10]  =  BigInteger.ONE;
    mnext[0]  =  BigInteger.ONE;
    //計算用ワーク
    java.math.BigInteger ret;
    int   addidx;
    //何回か繰り返す
    for(int kaisu  =  2;kaisu<5;kaisu++){       for(int i=0;i<41;i++){         mnext[i]  =  BigInteger.ZERO;
      }
      //現在の状態から、試行後の状態を計算
      for(int i = 10; i < 41; i++){      
        if(mx[i]    != BigInteger.ZERO){
          //10枚中印の付いたカードが0枚~10枚
          for(int xx = 0; xx <= 10; xx++){
            //5枚以上印が付いていないなら
            if(xx < 5 && i < 35){
              //印の付いたカードが(10-x)枚増える
              addidx =  i  +  10 -  xx;
            }else{
              addidx =  40;
            }
            //遷移後の確率を計算
            //整数演算するために、10C40倍する
            if(i  != 40){
              ret   =  mx[i].multiply(ccom(i,xx));
              ret   =  ret.multiply(ccom(40-i,10-xx));
            }else{
              ret   =  mx[i].multiply(ccom(40,10));
            }
            //ret    =  ret.divide(ccom(40,10));
            //試行後の値を加算
            mnext[addidx]  =  mnext[addidx].add(ret);
            //合計を加算
            mnext[0]    =  mnext[0].add(ret);
          }
        }
      }
      System.out.println("(" + kaisu + ")回目の試行後");
      for(int i = 0; i < 41; i++){      
        if(mnext[i]   != BigInteger.ZERO){
          System.out.println("("+i+")="+mnext[i].toString());
        }
      }
      ret   =  mnext[40].multiply(BigInteger.valueOf(1000)).divide(mnext[0]);
      System.out.println("確率(千分率):" + ret.toString());
      System.out.println("");

    }
    
  }
  /**
   * 組み合わせを計算する
   * @param a   
   * @param m   
   *     異なる a 個のものから異なる m 個のものを選ぶ
   * @return
   *     組み合わせ数      
   */
  public static BigInteger  ccom(long a,long m){
    java.math.BigInteger ret  = factorial2(BigInteger.valueOf(a)) ;
    ret=ret.divide(factorial2(BigInteger.valueOf(m)));
    ret=ret.divide(factorial2(BigInteger.valueOf(a-m)));
    return ret;
    
    
  }
  /**
   * 階乗を計算する。
   * @param  val  階乗を計算する値
   * @return  val!
   */
  public static BigInteger factorial2(BigInteger val) {
    if (val.compareTo(BigInteger.ONE) <= 0) {
      // val が 1以下になったら再帰呼び出しを終了する。
      return BigInteger.ONE;
    } else {
      // val * (val - 1)!
      return val.multiply(factorial2(val.subtract(BigInteger.ONE)));
    }
  }

}