Ruby中的一致加权映射

时间:2017-07-21 21:01:49

标签: ruby random

所以我目前有以下方法,根据加权概率(based on this)随机返回一个字符串(一组已知的字符串):

def get_response(request)
  responses = ['text1', 'text2', 'text3', 'text4', 'text5', 'text6']
  weights = [5, 5, 10, 10, 20, 50]
  ps = weights.map { |w| (Float w) / weights.reduce(:+) }
  # => [0.05, 0.05, 0.1, 0.1, 0.2, 0.5]

  weighted_response_hash = responses.zip(ps).to_h
  # => {"text1"=>0.05, "text2"=>0.05, "text3"=>0.1, "text4"=>0.1, "text5"=>0.2, "text6"=>0.5}

  response = weighted_response_hash.max_by { |_, weight| rand ** (1.0 / weight) }.first

  response
end

现在不是随机加权输出,而是希望输出在输入字符串的基础上保持一致,同时保持响应的加权概率。例如,调用如:

get_response("This is my request")

应始终产生相同的输出,同时保持输出文本的加权概率。

我认为Modulo可以在某种程度上使用,哈希映射到相同的结果,但我有点丢失。

1 个答案:

答案 0 :(得分:0)

@maxpleaner试图用this说的是

  

srand可用于确保程序的不同运行之间可重复的伪随机数序列。

因此,如果您为随机生成器播种,您将始终获得相同的结果。

例如,如果你这样做

func randomQuote(){
    //Make an array from database keys
    var authorArray = Array(database.keys)

    //Pick a random author
    let author = authorArray[Int(arc4random_uniform(UInt32(authorArray.count)))]

    //Make an array from values based on the author we've picked 
    let quoteArray = database[author]!

    //Pick a random quote from the choses author
    let quote = quoteArray[Int(arc4random_uniform(UInt32(quoteArray.count)))]

    print(author)
    print(quote)
}

每当您传入相同的random = Random.new(request.hash) response = weighted_response_hash.max_by { |_, weight| random.rand ** (1.0 / weight) }.first 时,您总会得到相同的response

旧代码

request

新代码,播种随机

3.times.collect { get_response('This is my Request') }
# => ["text6", "text1", "text6"]
3.times.collect { get_response('This is my Request 2') }
# => ["text6", "text4", "text5"]

输出仍然是加权的,刚才有一些可预测性:

3.times.collect { get_response('This is my Request') }
# => ["text4", "text4", "text4"]
3.times.collect { get_response('This is my Request 2') }
# => ["text1", "text1", "text1"]