Ruby - 在数组中选择一个元素,a[0] 的几率为 50%,a[1] 的几率为 25% [英] Ruby - Picking an element in an array with 50% chance for a[0], 25% chance for a[1]

查看:33
本文介绍了Ruby - 在数组中选择一个元素,a[0] 的几率为 50%,a[1] 的几率为 25%的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

没什么太复杂的,基本上我只想从数组中选择一个元素,就好像我正在为每个索引掷硬币并在我第一次得到正面时选择索引.也没有头意味着我选择最后一个垃圾箱.

Nothing too complicated, basically I just want to pick an element from the array as if I were making coin tosses for each index and and choosing the index when I first get a head. Also no heads means I choose the last bin.

我想出了以下内容,并想知道是否有更好/更有效的方法来做到这一点.

I came up with the following and was wondering if there was a better/more efficient way of doing this.

def coin_toss(size)
  random_number = rand(2**size)
  if random_number == 0
    return size-1
  else
    return (0..size-1).detect { |n| random_number[n] == 1 }
  end
end

推荐答案

首先猜测...在 1 和 2**size 之间随机选择一个数,找到它的对数基数 2,然后从末尾选择元素数.

First guess...pick a random number between 1 and 2**size, find the log base 2 of that, and pick the number that many elements from the end.

原谅我可怕的红宝石技能.

Forgive my horrible ruby skillz.

return a[-((Math.log(rand(2**size-1)+1) / Math.log(2)).floor) - 1]

如果 rand 返回 0,则应选择最后一个元素.1 或 2,倒数第二.3、4、5 或 6,倒数第三个.等等.假设随机数分布均匀,每个元素被选中的机会是其后元素的两倍.

if rand returns 0, the last element should be chosen. 1 or 2, the next to last. 3, 4, 5, or 6, third from the end. Etc. Assuming an even distribution of random numbers, each element has twice as much chance of being picked as the one after it.

实际上,似乎有一个 log2 函数,所以我们不必做 log/log(2) 的事情.

Actually, it seems there's a log2 function, so we don't have to do the log/log(2) thing.

return a[-(Math.log2(rand(2**size - 1)+1).floor) - 1]

你可以像

return a[-((rand(2**size-1)+1).to_s(2).length)]

但是您正在创建一个额外的String.不确定这是否比复杂的数学更好.:)

But you're creating an extra String. Not sure whether that's better than complicated math. :)

实际上,如果您要走字符串路线,则可以完全去掉 +1 和 -1.它会使概率更准确,因为最后两个元素应该有相等的被选中机会.(如果未选择倒数第二个值,则始终是最后一个值.)

Actually, if you're going to go the string route, you can get rid of the +1 and -1 altogether. It'd make the probabilities more accurate, as the last two elements should have an equal chance of being chosen. (If the next-to-last value isn't chosen, the last value would always be.)

我们还可以将 ** 转换为位移,这应该会快一点(除非 Ruby 已经足够聪明,可以这样做).

We could also turn the ** into a bit shift, which should be a little faster (unless Ruby was smart enough to do that already).

return a[-(rand(1<<size).to_s(2).length)]

这篇关于Ruby - 在数组中选择一个元素,a[0] 的几率为 50%,a[1] 的几率为 25%的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆