我的工作,创建了信混乱的群体,对于这个程序,我创建2台加权信发电机,一个辅音字母,一个元音。
目前,我有使用哈希值进行加权的加权数生成器,我可以来电来函采摘功能与我想它返回的字母数(如pick_vowel(3))
def pick_vowel(x)
vowels = { A: 15, E: 21, I: 13, O: 13, U: 5 }
v_choice = []
vowels.map {|letter, number| number.times {v_choice << letter}}
x.times {print v_choice.shuffle!.pop}
end
我们的想法是,然后向得到的字符串传递给一个功能赋予一定的长度的所有可能的组合,使用以下代码:
def solver(vowel)
puts (2..9).flat_map{|size| board.combination(size).map(&:join)}
end
但是当我传递字符串我得到下面的错误信息(在这种情况下,x = 6):
in `block in solver': undefined method `combination' for 6:Integer (NoMethodError)
我想输出字符串转换为数组,但据我所知没有出现在输出字符串一个整数,所以该阵列方法并不适用于它。
如何防止在最后包含一个整数我的输出?
假设
vowels = { A: 5, E: 8, I: 4, O: 7, U: 3, Y: 1 }
我理解这个散列值绘制相关联的密钥的权重。你首先构造(以不同的方式):
v_choice = vowels.flat_map { |k,v| [k]*v }
#=> [:A, :A, :A, :A, :A,
# :E, :E, :E, :E, :E, :E, :E, :E,
# :I, :I, :I, :I,
# :O, :O, :O, :O, :O, :O, :O,
# :U, :U, :U,
# :Y]
接下来,您执行
x.times {print v_choice.shuffle!.pop}
假设第一洗牌产生以下:
v_choice
#=> [:O, :O, :E, :U, :U, :O, :A, :E, :E, :E, :U, :I, :A, :I,
# :E, :A, :O, :O, :E, :E, :O, :A, :I, :A, :O, :E, :I, :Y]
接着
print v_choice.pop
打印"Y"
,并删除:Y
唯一v_choice
。因此,(与概率1):Y
将随机抽取没有更多的,矛盾的是它具有正权重的事实。
如果vowels
的值不重量,但在数字元音的有限集合一个可以大大简化。计算v_choice
后,只需要编写
puts v_choice.sample(x).join
# EOOYEIIEOI
要么
puts v_choice.shuffle[0,x].join
# EOOUOEEIAE
现在让我们假设vowels
的价值确实是权重。然后,我们只需要编写
x = 10
x.times { print v_choice.sample }
# OAEYEUAOAO
如果vowels
的值大,v_choice
也相应较大。这将影响到内存的要求,但不执行速度。如果对内存的需求非常昂贵(不太可能,也许),一个可以做到以下几点。
tot_wts = vowels.values.sum.to_f
#=> 28.0
cum = 0
cum_dist = vowels.map do |v,wt|
cum_wt = cum + wt/tot_wts
cum = cum_wt
[v, cum_wt]
end
#=> [[:A, 0.17857142857142858],
# [:E, 0.4642857142857143],
# [:I, 0.6071428571428572],
# [:O, 0.8571428571428572],
# [:U, 0.9642857142857143],
# [:Y, 1.0]]
在舍入误差的情况下,我们可能会设置
cum_dist[-1][-1] = 1.0
然后,我们可以生产正是如此加权样本。
x = 10
x.times do
rn = rand
print cum_dist.find { |_,cum| rn < cum }.first
end
# EAAOOEEIOA
注意,我们不能写
print cum_dist.find { |_,cum| rand < cum }.first
因为rand
返回的值将不断find
的块内发生变化。
该技术中,所谓的“逆变换方法”,通常用于产生仿真模型离散随机变元。
问题就在这里:
x.times {print v_choice.shuffle!.pop}
上述打印的值x
倍,并返回x
的值。这是Integer#times
是如何工作的。
相反,你需要:
x.times.map { v_choice.shuffle!.pop }
或更好,
v_choice.shuffle!.pop(x)
因为Array#pop
接受的说法。