Basic 情報処理試験(ソフトウェア開発技術者)カンニングペーパー


package com.example;

public class ErlangSheet {

  // 打ち切り誤差
  private static double PRECISION = 0.00001;
  
  public static void main(String[] args){
    
    for(double line=1;line <10.0;line++){
      System.out.print(erlang(0.01,line)+"\t");
      System.out.print(erlang(0.05,line)+"\t");
      System.out.print(erlang(0.10,line)+"\t");
      System.out.print(erlang(0.15,line)+"\t");
      System.out.print(erlang(0.20,line)+"\n");
    }
    
  }
  
  /**
   * 回線数と呼損率から収容できる呼量を求める.
   * @param lossRate 呼損率
   * @param line 回線数
   * @return 呼量
   */
  public static double erlang(double lossRate,double line){
    double upperErlan = 1.0;
    double lowerErlan = Double.MIN_VALUE;
    
    // 少なくとも指定された呼損率(lossRate)以上になる呼量を求める
    while(lossRate > lossRate(line,upperErlan)){
      upperErlan *= 10.0;
    }
    
    // 呼損率と呼量の関係は単調増加なので、二分法で呼損率から呼量を求める。
    // 10000回処理を行っても所定の精度に収束しないときには、10000回時点の
    // 値を返す。
    //
    //     Low                  Mid   Ans               Up 
    // ----+---------------------+-----*-----------------+---
    //                           |                       |
    //                          Low   Ans    Mid        Up
    //                          -+-----*------+----------+-
    //                           |            |
    //                          Low   Ans    Up
    //                          -+-----*------+-
    for(int cnt=0 ; cnt<10000 ; cnt++){
      
      // 所定の精度がでていたら終了
      if( upperErlan - lowerErlan < PRECISION ){
        break;
      }
      
      double middle = (upperErlan+lowerErlan)/2.0;
      
      if( lossRate > lossRate(line,middle)){
        lowerErlan = middle;
      }else{
        upperErlan = middle;
      }
    }
    
    return (upperErlan+lowerErlan)/2.0;
  }
  
  /**
   * 回線数と呼量から呼損率を求める.
   * lossRate = P(line,erlang) / ( 1 + P(1,erlang) + P(2,erlang) + ... + P(line,erlang) )
   */
  public static double lossRate(double line,double erlang){
    double denominator = lossRateParts(line,erlang);
    double numerator = 1;
    for(double cnt=1.0;cnt<=line;cnt++){
      numerator += lossRateParts(cnt,erlang);
    }
    return denominator/numerator;
  }
  
  /**
   * アーランの公式の一部分.
   * P(n,a) = a^n / n!
   */
  public static double lossRateParts(double n,double a){
    return Math.pow(a,n) / factorial(n);
  }
  
  /**
   * x の階乗
   */
  public static double factorial(double x){
    double ret = 1;
    for(double cnt=1.0;cnt<=x;cnt++){
      ret *= cnt;
    }
    return ret;
  }
}

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   sitemap
Last-modified: 2007-10-05 (金) 21:17:41 (6041d)
Short-URL: http://hondou.homedns.org/pukiwiki/pukiwiki.php?cmd=s&k=03d5743763
ISBN10
ISBN13
9784061426061