编程那点事
看到了有人说提红包问题,通过偏移量改变随机区间,最后一次为补偿,如果随机失败(前面偏移量太大)则重新生成,然后加了Foo类,通过提高补偿率提高计算效率,
class Package
def initialize total, num, min, max
@total = total
@package_num = num
@max = max
@min = min
@origin_base = total / num
end
def generate_package
packages = []
@package_num.times do |i|
new_package = random_package
if @package_num == 1
packages << @total.round(2)
@total = 0
@package_num -= 1
next
end
packages << new_package
@total -= new_package
@package_num -= 1
end
packages
end
private
def low_rate
(@max - @origin_base).to_f / (@max - @min).to_f
end
def random_heigh
if offset_rate > 0
rand((@origin_base.to_f + (@max - @origin_base) * offset_rate)..@max.to_f).round 2
else
rand(@origin_base.to_f..(@max.to_f + (@max - @origin_base) * offset_rate)).round 2
end
end
def random_low
if offset_rate > 0
rand((@min.to_f + (@origin_base - @min) * offset_rate)..@origin_base.to_f).round 2
else
rand(@min.to_f..(@origin_base.to_f + (@origin_base - @min) * offset_rate)).round 2
end
end
def offset_rate
rate = ((@total / @package_num) - @origin_base) / @origin_base
raise if rate > 1 || rate < -1
-rate
end·
def random_package
rand(0.0..1.0) <= low_rate ? random_low : random_heigh
end
end
class Foo
# 分批生成红包,提高补偿比例,提升效率
def initialize(total, num, min, max)
@total = total
@num = num
@min = min
@max = max
@avg = total / num
end
def optimized_generate
num_10 = @total / 10
num_left = @total % 10
packages = []
num_10.times do
packages << get_packages(10 * @avg, 10)
end
packages << get_packages(num_left * @avg, num_left) if num_left > 0
packages.flatten
end
def get_packages sub_total, sub_num
while true do·
begin
packages = Package.new(sub_total, sub_num, @min, @max).generate_package
return packages if packages.sum == sub_total
rescue
end
end
end
end
time_start = Time.now.to_f
result = Foo.new(100000, 50000, 1, 5).optimized_generate
time_end = Time.now.to_f
p result
puts "package count: " + result.length.to_s
puts "package sum: " + result.sum.to_s
puts "cost time: #{time_end - time_start}s"
发表于 2018.11.30
© 自由转载 - 非商用 - 非衍生 - 保持署名