2017-02-23 5 views
0

私は頻度カウントに基づいて文字を選択する関数を書こうとしています。ここでランダムな文字の選択機能

、a〜zの文字以下の周波数がありますgetWeightが含まれている文字クラスを、

public Letter chooseOnWeight(List<Letter> letterNew) { 

    int completeWeight = 0; 
    int completeWeightUpdated = 0; 
    List<Integer> updatedWeightList = new ArrayList<>(); 
    for (Letter letter : letterNew) { 
     updatedWeightList = letter.getWeight(); 
     for (int i = 0; i < updatedWeightList.size(); i++) { 
      completeWeight += updatedWeightList.get(i); 

     } 
     completeWeightUpdated += completeWeight; 
    } 

    int countWeightUpdated = 0; 
    List<Integer> updatedCountList = new ArrayList<>(); 
    double r = Math.random() * completeWeight; 
    double countWeight = 0.0; 
    for (Letter letter : letterNew) { 
     updatedCountList = letter.getWeight(); 
     for (int i = 0; i < updatedWeightList.size(); i++) { 
      countWeight += updatedCountList.get(i); 
     } 
     countWeightUpdated += countWeight; 

     if (countWeightUpdated >= r) { 
      return letter; 
     } 
    } 
    throw new RuntimeException("Should never be shown."); 
} 

4778 ,1145 ,1994 ,2075 ,5940 ,762 ,1403 ,1446 ,4263 ,111 ,745 ,3231 ,1625 ,3467 ,3543 ,1455 ,94 ,3678 ,3775 ,3092 ,1883 ,529 ,649 ,139 ,902 ,180 

その重み付き確率に基づいてランダムな文字を生成する関数を()関数:

public class Letter { 
    char name; 
    List<Integer> weight; 

    public Letter(char name){ 
     this.name = name; 
    } 

    public char getName() { 
     return name; 
    } 

    public List<Integer> getWeight() { 
     return weight; 
    } 

    public void setWeight(List<Integer> weight) { 
     this.weight = weight; 
    } 


} 

残念ながら、生成されるのはa-fだけです。何らかの理由で、fの後ろに文字を生成していません。

+0

おそらくあなた 'getWeight'方法 –

+0

はgetWeightを(追加する私たちを見る) – statsguyz

+0

、BのためにA、+ 1145 4778のための4778のキーは、文字の累積重量であるのTreeMap <整数、文字>、(4778作成+ 1145 + 1994 for Cなど)、値は文字です。このためには、リストの1回のパスが必要です。 0と累積加重Zの間の乱数を生成し、この乱数に対応する文字を見つけるためにmap.ceilingEntry()を呼び出します。 –

答えて

1

リセットcountWeight0letterNewにそれぞれLetterを反復する2番目のメインforループが繰り返されるたびにリセットされます。 countWeightをリセットしないと、の期待値は、countWeightの数字をupdatedCountListに増やしたインナーループの後に影響を受けます。この内部ループの後では、のすべてのインスタンスの総重量ではなく、現在のLetterが繰り返されている合計重量の値だけ、countWeightUpdatedを増やす必要があります。たとえば、aの合計ウェイトが1000、bの総ウェイトが1100、cの合計ウェイトが1200の場合、countWeightUpdatedの値を1000 + 1100 + 1200 = 3300にする必要があります。 、b、およびc。ただし、各反復後にcountWeightは各文字の重みではなく、以前に見た文字の総重量になりますので、ループは1000 + 2100 + 3300 = 8400の代わりに次の加算を行います。この場合、2100は(1000 + 1100)に由来し、3300は(1000 + 1100 + 1200)に由来する。その結果、返される文字の範囲がより狭い範囲に制限されます。修正は簡単です、

for (Letter letter : letterNew) { 
    updatedCountList = letter.getWeight(); 
    for (int i = 0; i < updatedWeightList.size(); i++) { 
     countWeight += updatedCountList.get(i); 
    } 
    countWeightUpdated += countWeight; 
    countWeight = 0; //THIS IS THE FIX 
    if (countWeightUpdated >= r) { 
     return letter; 
    } 
} 

はまた、あなたはcompleteWeightUpdatedでループのためのあなたの第一主で同様の問題を抱えているが、それは冗長に思えたので、私はそれを言及しなかったので、それはメソッド内であまり使用されていません。今

関連する問題