如何动态改变这个随机数生成器的曲线?

2024-01-14

该函数生成一个随机数,但概率曲线倾向于较低范围:

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 的可能性是 1 的一半可能为 2,依此类推。不过,我在动态地弄清楚它时遇到了很多麻烦。


可以用一个简单的算术函数来解决这个问题。该函数将用于将均匀分布的随机数映射到具有特殊分布的所需范围。

如果我们以 0.5 为例,对于每个后继者,其概率应减半,我们会得到如下事件集:

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

对于 min=0、max=2 以及 max=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(均等分配)
  • 将此数字映射到集合中所示的相应结果

第一个任务很简单,只需调用getRandomNumber(1,2^(max+1)-1)。 第二个是通过计算该随机数以 2 为底的对数并从差值到最大值构建下限来完成的:

// 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;

What if min != 0?
这很容易处理:我们只需从 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).

适用于任意最小值、最大值和因子的最终版本:

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;

注意log2 and logbJava 中不存在,但您可以使用以下命令定义它们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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何动态改变这个随机数生成器的曲线? 的相关文章

  • 取消html5浏览器中的单图请求

    我正在动态加载 大 图像以绘制到 html5 画布中 如下所示 var t new Image t onload t src http myurl 但每隔一段时间就会想取消图片请求完全地 我想出的唯一方法是设置src to i e t sr
  • 动态速度计 javascript 或 jquery 插件

    我希望有动态ajax插件在页面上显示速度计 一个想法是我设置一个背景并旋转针 有人知道相关插件吗 这里有一些供您参考 http bernii github com gauge js http bernii github com gauge
  • 如何使用 JavaScript 中的值填充下拉列表?

    我在 Tridion CMS 扩展中的功能区工具栏按钮中添加了一个按钮 单击该按钮后 将显示一个弹出页面 其中包含两个下拉菜单 通过更改第一个下拉控件中的值 我应该填充第二个下拉控件的值 就我而言 我正在使用ASP drop down li
  • 在Javascript中按降序对字符串进行排序(最有效)?

    W3Schools 有这个例子 var fruits Banana Orange Apple Mango fruits sort fruits reverse 这是在 Javascript 中按降序对字符串进行排序的最有效方法吗 Updat
  • 在网页上的文本框中键入内容时删除所有空格

    我如何在用户打字时即时删除输入到文本框中的空格 function var txt myTextbox var func function txt val txt val replace s g txt keyup func blur fun
  • jquery 验证错误位置

    这看起来很简单 但我无法弄清楚 我正在使用 jquery 验证插件 我验证所有文件 但我想要的是在输入文本行中显示验证消息警报 例如在电子邮件输入中 请填写电子邮件地址 但现在它出现在所有字段下 在我的html中
  • Jquery从下拉列表中获取所选值的id

    我有一个下拉列表 可以从数据库获取值 如下所示 get getJobs function jobs seljobs jobs var i 0 jobs forEach function n alert job id n id 32 67 4
  • 如何使用 jest 模拟第三方库

    我正在开发一个node js应用程序使用nestjs我有一堂课叫LoggerService如下 export class LoggerService private logger Rollbar constructor this logge
  • Ember.js 处理 View 事件后转换到路由

    Setup 我有一个 Ember 应用程序 支持使用 Imgur API 上传图像 我已经有一个工作路线和模板来处理任何 Imgur ID 但我想在上传新图像后转换到此路线 使用返回的 Imgur ID 这是该应用程序的相关部分 http
  • 检查 touchend 是否在拖动后出现

    我有一些代码可以更改表的类 在手机上 有时表格对于屏幕来说太宽 用户将拖动 滚动来查看内容 但是 当他们触摸并拖动表格时 每次拖动都会触发 touchend 如何测试触摸端是否是触摸拖动的结果 我尝试跟踪dragstart和dragend
  • Node.js - console.log 不显示数组中的项目,而是显示 [Object]

    我在注销对象内数组的内容时遇到问题 实际的物体看起来像这样 var stuff accepted item1 item2 rejected response Foo envelope from The sender to new item1
  • HTML2canvas 和 Canvas2image,下载的屏幕截图不显示我的 HTML 图像

    我一直在开发一个 HTML 页面 我想将其转换为图像 我一直在使用 html2canvas 和 canvas2image 脚本并采用此代码http jsfiddle net 8ypxW 3 http jsfiddle net 8ypxW 3
  • 通过 node-http-proxy 保留基于 cookie 的会话

    我有一个简单的基于 Express 的 Node js Web 服务器 用于开发 JavaScript 应用程序 我将服务器设置为使用 node http proxy 来代理应用程序向在不同域和端口上运行的 Jetty 服务器发出的 API
  • JS用正则表达式替换数字

    我有元素的标识符 如下所示 form book 1 2 3 我想要的是用其他值替换该标识符中的第二个数字 我将函数 match 与以下正则表达式一起使用 var regexp d d d 但它返回我包含的数组 1 2 3 2 因此 当我尝试
  • 将数组排序为第一个最小值、第一个最大值、第二个最小值、第二个最大值等

    编写一个JS程序 返回一个数组 其中第一个元素是第一个最小值 第二个元素是第一个最大值 依此类推 该程序包含一个函数 该函数接受一个参数 一个数组 该函数根据要求返回数组 输入示例 array 2 4 7 1 3 8 9 预期输出 1 9
  • 当用户单击链接时,如何记录 MixPanel 事件?

    当用户单击某种类型的链接时 我试图在 MixPanel 中记录一个事件 我正在使用 JQuery 不引人注意地完成此操作 据我所知 我需要添加一个回调函数 以便在记录事件后将用户带到 URL 这是我正在使用的代码 不幸的是
  • JavaScript onresize 事件多次触发

    我在尝试仅在触发 onresize 事件时运行一次函数时遇到一些麻烦 我已经看过这个问题DOM onresize 事件 https stackoverflow com questions 1500312 javascript onresiz
  • 单击引导分页链接时调用 jquery 函数

    我想在单击引导分页链接时调用 jquery 函数 假设我想从第1页遍历到第2页 应该调用一个jquery函数 我正在使用以下代码 但它不起作用 ul pagination on click li function alert page ch
  • 防止文本区域出现新行

    我正在开发聊天功能 使用 Vue 并使用文本区域作为输入 以便溢出换行 并且对于编写较长消息的用户来说更具可读性 不幸的是 当用户按下 Enter 键并提交时 光标会在提交之前移动到新行 从而使用户体验感觉不佳 关于如何使用普通 Javas
  • 单击列表时使用 bootstrap Dropdown 防止下拉菜单消失

    我正在使用使用引导下拉菜单 http twitter github com bootstrap javascript html dropdowns生成下拉菜单 我想防止点击菜单时菜单消失 我已经实现了以下代码 但它不起作用 知道如何修复它吗

随机推荐