2017-10-28 15 views
2

この関数は乱数を生成しますが、低域を好む確率曲線で:この乱数ジェネレータのカーブを動的に変更するにはどうすればよいですか?

function getRandomLowNumber(min=1,max=100,factor=1){ 
    let num = getRandomDecimal(min,max); 
    let rollDiff = num - min; 
    let percent = (rollDiff)/(max - min); 
    percent = 1 - (1 - percent)/factor; 
    return Math.round(rollDiff * percent + min); 
} 

私は要因がカーブを決定する場所、それが仕事をしたいので、1の要因は、分に沿ってすべての数字を意味し、最大範囲も同様に可能性がありますが、0.5はドロップオフを意味し、2は1の半分、3は2の半分のようになります。私は動的にそれを把握するのに苦労しています。

+0

これは把握することは非常に困難なアルゴリズムです。 1時間以上友達と一緒に仕事をしています。 –

+1

簡単な方法は、配列をあらかじめ入力してそれから描画することです。例: '[1,1,2,2,3]'は3分の1です。 – dandavis

+0

@dandavisによって提案された解決策を試すために私の例を更新しましたが、その結果、テストケースで6より大きい数値が生成されることはありません。私はその問題を解決する方法がわかりませんが、私はコードでそれについてコメントしました。 –

答えて

1

これを単純な算術関数で解くことは可能です。この関数は、等分配された乱数を特別な分布で所望の範囲にマッピングするために使用される。

私たちは、それぞれの後継者のために半分それは確率だ、我々はそのように設定されたイベントを取得しなければなら0.5、とあなたの例を取る場合:最大分間= 0のため

#1 2 3 4 5 6 7 
0 0 0 0 1 1 2 

、最大= 2とそのように= 3:

#1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
0 0 0 0 0 0 0 0 1 1 1 1 2 2 3 

max = 2の場合、セットは7(2^3 - 1)の要素で構成され、max = 3の場合は15(2^4 - 1)です。したがって、任意の最大値に対しては、2^(max+1) - 1要素でイベントセットを取得する必要があります。

だから私たちが今何をする必要があるか

  • が範囲1 .. 2^(max+1)-1(等しいDISTRIB)に
  • マップを乱数を作成しているセットに示すように対応する結果にこの番号

最初のタスクは簡単です。ちょうどgetRandomNumber(1,2^(max+1)-1)を呼び出してください。

// for max==3 you get: 
// rndnum : 1 2 3 4 5 6 7 8 9'0'1'2'3'4'5 
// expflr : 0 1 1 2 2 2 2 3 3 3 3 3 3 3 3 
// rndres : 3 2 2 1 1 1 1 0 0 0 0 0 0 0 0 
int rndnum = getRandomNumber(1, Math.pow(2, max+1) - 1); 
int expflr = Math.floor(log2(rndnum)); 
int rndres = max - expflr; 

min != 0を場合: 秒1は、この乱数の2を底とする対数を計算し、最大の違いから、床を構築することにより行われていますか?
これは扱いが簡単です:maxから減算して最終結果に加算するだけです。

0.5以外のディストリビューションはどうなりますか?
私たちが公式で見た悪名高い2は、1/0.5です。任意の値については、2を1/factor(トピックの要因は0から1までの範囲)に置き換えます。
セット内のイベントの数は(1/factor)^0 + (1/factor)^1 + (1/factor)^2 + ...で与えられ、これは((1/factor)^(max+1) - 1)/(1/factor - 1)に等しい。

決勝任意の分で動作するバージョン、maxとファクター:

double base = 1.0/factor; 
int evtcnt = Math.floor(Math.pow(base, max-min+1) - 1)/(base-1)); 
int rndnum = getRandomNumber(1, evtcnt); 
int expflr = Math.floor(logb((rndnum-1) * (base-1) + 1, base)); 
int rndres = max - expflr; 

log2logbは、Javaには存在しませんが、あなたはlog10(val)/log10(2.0) RESP log10(val)/log10(base)でそれらを定義することができるという。

function logb(val, base) { 
 
    return Math.log10(val)/Math.log10(base); 
 
} 
 
function getRandomNumber(min,max){ 
 
    return Math.floor(Math.random()*(max-min+1)+min); 
 
} 
 
function getRandomLowNumber(min, max, factor) { 
 
    var base = 1.0/factor; 
 
    var evtcnt = Math.floor(Math.pow(base, max-min+1) - 1)/(base-1); 
 
    var rndnum = getRandomNumber(1, evtcnt); 
 
    var expflr = Math.floor(logb((rndnum-1) * (base-1) + 1, base)); 
 
    var rndres = max - expflr; 
 
    return rndres; 
 
} 
 
function runit() { 
 
    var min = document.getElementById('input-min').value; 
 
    var max = document.getElementById('input-max').value; 
 
    var factor = document.getElementById('input-factor').value; 
 
    var times = document.getElementById('input-times').value; 
 
    var list = {}; 
 

 
    for (let i = 0; i < times; i++) { 
 
     var number = getRandomLowNumber(min, max, factor); 
 
     if (typeof list[number] == 'number') { 
 
      list[number]++; 
 
     } else { 
 
      list[number] = 1; 
 
     } 
 
    } 
 
    console.log('Min: ', min); 
 
    console.log('Max: ', max); 
 
    console.log('Factor: ', factor); 
 
    console.log('Iterations: ', times); 
 
    console.log('List: ', list); 
 
} 
 
function runClippy() { 
 
    var name = 'Clippy'; 
 
    if (clippy.load._data[name]) { 
 
     return; 
 
    } 
 
    clippy.load(name, function(agent) { 
 
     var animations = agent.animations(); 
 
     $('.js-states').text(animations.join(' ')); 
 
     agent.show(); 
 
     agent.moveTo(400, 30); 
 
     agent.speak("Hello, I see you're trying to run this sample. My name is " + name + " and yacc sent me here to help."); 
 
     agent.moveTo(200, 100); 
 
     agent.speak("There are four input fields to put parameters."); 
 
     agent.moveTo(300, 50); 
 
     agent.gestureAt(-100,50); 
 
     agent.speak("The first two specify the minimum and maximum random value."); 
 
     agent.moveTo(90,50); 
 
     agent.gestureAt(0,-50); 
 
     agent.speak("I'll put starting values for you here."); 
 
     agent._addToQueue(function(complete) { 
 
      $('.input-min').val("1"); 
 
      $('.input-max').val("100"); 
 
      complete(); 
 
     }); 
 
     agent.gestureAt(-100,50); 
 
     agent.speak("The next field specifies the factor that will decrease the probability for each successor. It should range between 0 (exclusively) and 1. Let's try a value here."); 
 
     agent._addToQueue(function(complete) { 
 
      $('.input-factor').val("0.5"); 
 
      complete(); 
 
     }); 
 
     agent.moveTo(550, 70); 
 
     agent.gestureAt(-100,50); 
 
     agent.speak("The final input field is used to specify the amount of random numbers to generate. I'll fill it in for you."); 
 
     agent._addToQueue(function(complete) { 
 
      $('.input-times').val("100"); 
 
      complete(); 
 
     }); 
 
     agent.speak("Now, did you notice the big button at the bottom of the form? You can push it to start the calculation."); 
 
     agent.moveTo(50, 120); 
 
     agent.gestureAt(-100,50); 
 
     
 
     agent.moveTo(90,50); 
 
     agent.gestureAt(0,-50); 
 
     agent.speak("Be careful with the amount of calculations. If the task takes too long, it might be aborted."); 
 
     agent.moveTo(630, 200); 
 
     agent.speak("So, now you can start on your own calculation of randoms. Be sure to fill in the fields properly, so that min <= max, or 0 < factor <= 1. Our lab is so busy at the moment that we spared a few safety belts."); 
 
     agent._addToQueue(function(complete) { 
 
      $('.wmd-input').val("# What are you trying to achieve?"); 
 
      complete(); 
 
     }); 
 
     agent.moveTo(400, 30); 
 
     agent.gestureAt(-100, 50); 
 
     agent.speak("Please describe in short what you are trying to achieve"); 
 
     agent._addToQueue(function(complete) { 
 
      $('.wmd-input').val("# What are you trying to achieve?\n\n# What is the problem you're facing?"); 
 
      complete(); 
 
     }); 
 
     agent.moveTo(400, 70); 
 
     agent.gestureAt(-100, 50); 
 
     agent.speak("Please describe the error you're getting, and/or post the error message you're getting"); 
 
     agent._addToQueue(function(complete) { 
 
      $('.wmd-input').val("# What are you trying to achieve?\n\n# What is the problem you're facing?\n\n#Show the code causing the problem"); 
 
      complete(); 
 
     }); 
 
     agent.moveTo(400, 90); 
 
     agent.gestureAt(-100, 50); 
 
     agent.speak("Please post the code that causes your problem. Try to post it without clutter or unrelated code."); 
 
     
 
     agent.speak("People who answer should be able to use your code to reproduce the error. Please lookup MVCE in the stack overflow help ."); 
 
     agent.moveTo(630, 200); 
 
    }); 
 
} 
 
$(document).ready(function(){ 
 
    // $('.wmd-input').one('focus', function() {runClippy();}); 
 
    $('.input-min').one('focus', runClippy); 
 
    $('.input-max').one('focus', runClippy); 
 
    $('.input-factor').one('focus', runClippy); 
 
    $('.input-times').one('focus', runClippy); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<link rel='stylesheet prefetch' href='https://cdn.rawgit.com/smore-inc/clippy.js/master/build/clippy.css'> 
 
<!--link rel="stylesheet prefetch" href="https://cdn.sstatic.net/Sites/stackoverflow/all.css?v=b0fb54f66683"--> 
 
<script src='https://cdn.rawgit.com/smore-inc/clippy.js/master/build/clippy.min.js'></script> 
 
<div> 
 
Min: <input value="0" id="input-min" class="input-min processed"> 
 
Max: <input value="100" id="input-max" class="input-max processed"><br> 
 
Factor: <input value="0.5" id="input-factor" class="input-factor processed"><br> 
 
#-Runs: <input value="1000000" id="input-times" class="input-times processed"><br> 
 
<button style="float: center;" onclick="runit()">--- Run that algorithm ---</button> 
 
</div>

+0

logbが何をしているのか、それともドキュメントにリンクしているのか説明できますか?私が見つけたところでは、あなたは2つを受け入れるのに対し、1つの入力しか受け付けません。 –

+1

そしてベースは '1.0/factor'ですか? –

+0

「スニペットを回答する」をクリックすると、それを編集して実行することができ、取り消すことができますので、実際に答えに入れないでください。 私は、Node.jsの中から神経回路網を構築することに取り組んでいます。この種の出力は、ニューラルネットワークシステムの進化的トレーニングモデルにとって非常に頻繁に必要となります。 –

関連する問題