Ruby ‘;散列中的散列和

Ruby ‘;散列中的散列和,ruby,Ruby,我有一个贪婪的算法: banknotes = { 5 => 6, 10 => 7, 20 => 8, 50 => 9 } amount = 335 a = CardCalculation.new(banknotes: banknotes) a.greedy_alg( amount: amount ) class CardCalculation def greedy_alg( amount ) result = {}

我有一个贪婪的算法:

  banknotes = { 5 => 6, 10 => 7, 20 => 8, 50 => 9 }
  amount = 335
  a = CardCalculation.new(banknotes: banknotes)
  a.greedy_alg( amount: amount )

  class CardCalculation
     def greedy_alg( amount )
       result = {}
        banknotes.each do | face, value |
         needed_value = amount - hash_summator( result )
         quantity     = ( needed_value / face )
         quantity     = value if quantity > value
         result[face] = quantity
       end
      result
    end

    def hash_summator(hash)
      hash.inject(0){|memo, (k, v)| memo += k * v}
    end
结果我明白了

    result = { 50 => 6, 20 => 1, 10 => 1, 5 => 1 }
您看,我取了335(amount:),遍历了散列,并从每个键及其值中选择了最大值

但现在我需要“扩散”算法,我需要这个结果,例如:

    result = { 50 => 4, 20 => 4, 10 => 4, 5 => 3}

我需要每把钥匙的中间号码。。我对循环有想法,但可能有人有想法?

此解决方案可能是一个起点,我没有测试如何避免无限循环:

banknotes = { 5 => 6, 10 => 7, 20 => 8, 50 => 9 }
amount = 335

min = banknotes.keys.min
init_avg = amount / banknotes.keys.sum # calculate the initial average
result = banknotes.transform_values { init_avg } # initialize with average
delta = amount - result.sum { |k,v| k * v }

if delta > 0 # start distribution
  loop do
    banknotes.keys.reverse_each do |val|
      if delta - val >= 0 and result[val] + 1 < banknotes[val]
        delta -= val
        result[val] += 1
      end
    end
    break if delta < min
  end
end

result
#=> {5=>3, 10=>4, 20=>4, 50=>4}
banks={5=>6,10=>7,20=>8,50=>9}
金额=335
min=banknotes.keys.min
init_avg=金额/banknotes.keys.sum#计算初始平均值
结果=banknotes.transform_值{init_avg}#用平均值初始化
delta=数量-result.sum{| k,v | k*v}
如果增量>0#开始分布
环道
钞票.钥匙.反面|每个都有| val|
如果delta-val>=0,结果[val]+1<纸币[val]
delta-=val
结果[val]+=1
终止
终止
如果增量<最小值,则中断
终止
终止
后果
#=> {5=>3, 10=>4, 20=>4, 50=>4}
完成版

   banknotes = {5 => 10, 10 => 10, 20 => 10, 50 => 10, 100 => 5}
   amount = 435



def spreaded_alg(amount)
   validate_money!(amount: amount)
   min    = banknotes.keys.min
   avg    = amount / banknotes.keys.sum.round(0)
   result = banknotes.transform_values {avg}
   delta  = amount - result.sum {|k, v| k * v}

if delta > 0
  loop do
    banknotes.keys.each do |value|
      if delta - value >= 0 && result[value] > banknotes[value]
        delta += value
        result[value] -= 1
      end
      if delta - value >= 0 && result[value] + 1 <= banknotes[value]
        delta -= value
        result[value] += 1
      end
    end
    break if delta < min
  end
end
result
end
banks={5=>10,10=>10,20=>10,50=>10100=>5}
金额=435
def喷洒量(数量)
验证你的钱!(金额:金额)
min=banknotes.keys.min
平均值=金额/钞票。键。总和。四舍五入(0)
结果=banknotes.transform_值{avg}
delta=数量-result.sum{| k,v | k*v}
如果增量>0
环道
钞票。钥匙。每个都有价值|
如果delta-value>=0&&result[value]>钞票[value]
增量+=值
结果[值]-=1
终止

如果delta-value>=0&&result[value]+1喜欢每个值的中值吗?是的。。你以(原文如此)开始提问是对的,“我有以下代码:”,对读者来说是一种浪费时间的行为,并由此引申为一种激励,促使他们忽略你的问题。这是因为他们没有告诉我们代码要解决什么问题。我假设它是这样的,“给定不同面额的特定数量的纸币,我们希望找到一个总数为给定数量的纸币组合。”用这样的话开始这个问题会非常有帮助。顺便说一句,我想这是一个NP完全问题。你的方法太棒了!它工作得很好!谢谢你的帮助,伊吉安!但我看到一个错误。。。它可能需要更多的值​​比…中的更多。。。如果我有{100=>1,50=>9,20=>8,10=>7,5=>6}和give-amount=615,它会给我结果{100=>3,50=>4,20=>3,10=>4,5=>3},但我没有100=>3,只有100=>1。。。但是你开始这个算法的时候做得很好。