Ruby加权循环

时间:2017-03-24 01:51:16

标签: ruby

我有一些未知的东西,比方说100个苹果都具有相同的质量。

我有两个水桶,总重量我试图在所有苹果都在水桶中时 - 桶1占总重量的60%,水桶2占40%。

我需要一个简单的ruby算法将苹果逐个放入桶中。我需要在填充它们时尽可能保持两个桶的均匀分布。

我无法一次完成所有这些,所以我不知道哪个是最后一个进入最后一桶的苹果。但我总能知道每个桶中苹果的总数。

(这是我正在努力解决的一个真正的问题,而不是一个家庭作业问题 - 我只是这样说,所以它很容易理解。)

2 个答案:

答案 0 :(得分:2)

bucket_1, bucket_2 = add_apple(bucket_1, bucket_2, percentage_ratio)

def add_apple(bucket_1, bucket_2, percentage_ratio)

  if bucket_1 + bucket_2 == 0
    if percentage_ratio >= 50.0
      bucket_1 += 1
    else
      bucket_2 += 1
    end
    return bucket_1, bucket_2
  end

  if bucket_1.to_f * 100 / (bucket_1 + bucket_2) < percentage_ratio
    bucket_1 += 1
  else
    bucket_2 += 1
  end
  return bucket_1, bucket_2
end

答案 1 :(得分:1)

根据提供给参数的加权规则,定义一个将项添加到两个变量的方法:

def fill_with_ratio(weighting1, weighting2, items)

  b1 = 0
  b2 = 0
  ratio = weighting1.fdiv weighting2
  steps = []

  #step 1 empty buckets
  if b1 + b2 == 0
    if ratio <= 1.0
      b2 += 1
    else
      b1 += 1
    end
  end

  steps << { step: 1, b1: b1, b2: b2, ratio: b1.fdiv(b2).round(2) }

  #steps 2 to items
  (items-1).times.with_index(2) do |_,i|

    r1 = b1.succ.fdiv b2
    r2 = b1.fdiv b2.succ

    if (r1 - ratio).abs <= (r2 - ratio).abs
      b1 += 1
    else
      b2 += 1
    end

    steps << { step: i, b1: b1, b2: b2, ratio: b1.fdiv(b2).round(2) }

  end
  steps
end

if表达式决定将哪些变量加1,以实现与定义的分布最接近的匹配。 steps数组仅用于显示每次添加后的步骤。它可以省略而不起作用。

关键方法: Integer#fdivInteger#timesEnumerator#with_indexInteger#succInteger#abs

示例一:

require 'pp' #pp prints everything nicely.

pp fill_with_ratio(60, 40, 100)
#[{:step=>1, :b1=>1, :b2=>0, :ratio=>0.0},
# {:step=>2, :b1=>1, :b2=>1, :ratio=>1.0},
# {:step=>3, :b1=>2, :b2=>1, :ratio=>2.0},
# {:step=>4, :b1=>2, :b2=>2, :ratio=>1.0},
# {:step=>5, :b1=>3, :b2=>2, :ratio=>1.5},
# .
# .
# .
# {:step=>98, :b1=>59, :b2=>39, :ratio=>1.51},
# {:step=>99, :b1=>59, :b2=>40, :ratio=>1.48},
# {:step=>100, :b1=>60, :b2=>40, :ratio=>1.5}]

示例二:

pp fill_with_ratio(30, 40, 21)
#[{:step=>1, :b1=>0, :b2=>1, :ratio=>Infinity},
# {:step=>2, :b1=>1, :b2=>1, :ratio=>1.0},
# {:step=>3, :b1=>1, :b2=>2, :ratio=>0.5},
# {:step=>4, :b1=>2, :b2=>2, :ratio=>1.0},
# {:step=>5, :b1=>2, :b2=>3, :ratio=>0.67},
# {:step=>6, :b1=>3, :b2=>3, :ratio=>1.0},
# {:step=>7, :b1=>3, :b2=>4, :ratio=>0.75},
# {:step=>8, :b1=>3, :b2=>5, :ratio=>0.6},
# {:step=>9, :b1=>4, :b2=>5, :ratio=>0.8},
# {:step=>10, :b1=>4, :b2=>6, :ratio=>0.67},
# {:step=>11, :b1=>5, :b2=>6, :ratio=>0.83},
# {:step=>12, :b1=>5, :b2=>7, :ratio=>0.71},
# {:step=>13, :b1=>6, :b2=>7, :ratio=>0.86},
# {:step=>14, :b1=>6, :b2=>8, :ratio=>0.75},
# {:step=>15, :b1=>6, :b2=>9, :ratio=>0.67},
# {:step=>16, :b1=>7, :b2=>9, :ratio=>0.78},
# {:step=>17, :b1=>7, :b2=>10, :ratio=>0.7},
# {:step=>18, :b1=>8, :b2=>10, :ratio=>0.8},
# {:step=>19, :b1=>8, :b2=>11, :ratio=>0.73},
# {:step=>20, :b1=>9, :b2=>11, :ratio=>0.82},
# {:step=>21, :b1=>9, :b2=>12, :ratio=>0.75}]