【问题标题】:Ruby - Optimize code finding the optimal choice from an arrayRuby - 优化代码从数组中找到最佳选择
【发布时间】:2014-09-25 13:02:52
【问题描述】:

我问了一个基本上是背包问题的问题 - 我需要找到几个不同的对象数组的组合,以提供最佳输出。因此,例如,相对于每个对象的“成本”限制,来自对象的最高总“价值”。我在这里收到的答案如下 -

a.product(b,c)
.select{ |arr| arr.reduce(0) { |sum,h| sum + h[:cost] } < 30 }
.max_by{ |arr| arr.reduce(0) { |sum,h| sum + h[:value] } } 

效果很好,但是当我进入 6 个数组,每个数组有大约 40 个选项时,可能的组合会超过 400 万个,并且处理时间太长。我对代码进行了一些更改,使处理速度更快 -

#creating the array doesn't take too long
combinations = a.product(b,c,d,e)
possibles = []

combinations.each do |array_of_objects|
#max_cost is a numeric parameter, and I can't have the same exact object used twice   
if !(array_of_objects.sum(&:salary) > max_cost) or !(array_of_objects.uniq.count < array_of_objects.count)
      possibles << array_of_objects
    end
 end

  possibles.max_by{ |ar| ar.sum(&:std_proj) }

将它分成两个单独的数组对性能有很大帮助,因为我只需要检查 max_by 以了解符合标准的许多不太可能的组合。

有人看到优化此代码的方法吗?由于我通常处理数万或数百万个组合,因此任何一点点都会有很大帮助。谢谢。

【问题讨论】:

  • 有没有人看到优化上述代码以使其处理速度更快的方法?有时代码中有数百万种可能的组合,所以任何一点点都可以提供帮助。
  • 数组从何而来?也许你应该在数据库查询中这样做?
  • 数组确实来自数据库,但它们不是瓶颈。就是代码中的处理。
  • 你的previous question 清楚地表明你有一个背包问题,有一个额外的要求,使它成为NP-complete。在优化方面,“关闭”只算马蹄铁。尽可能聪明地枚举,你无法逃避这样一个事实,即组合的数量随着数组的数量和大小呈指数增长。您无法解决您提到的大小问题(8 个数组,50 个元素)。
  • @sawa,如果您无法在令人满意的时间内计算出最优值,那么请务必使用启发式方法来尝试获得“好的”解决方案。然而,这不是我们这里所拥有的。上面的代码解决了一个没有附带条件的背包问题。然而,为此,有一个更有效的直接动态编程解决方案(请参阅上一个问题)。然而,OP 想要添加一个额外的条件,有效地使得不可能获得感兴趣的问题大小的最佳解决方案,但他对启发式方法不感兴趣。

标签: ruby arrays optimization knapsack-problem


【解决方案1】:

如果我们谈论数百万行,并且操作就像唯一和最大。

我建议您在查询中使用 DISINCT 和 MAX() 来解决它,您甚至可以使用 WHERE 按成本过滤。

在 Ruby 中循环对象显然更昂贵。

【讨论】:

  • 问题是我没有在数据库中存储所有可能的组合,我通过我的产品方法在 ruby​​ 中这样做。你知道在数据库中生成类似的东西吗?
猜你喜欢
  • 2012-12-05
  • 1970-01-01
  • 2013-12-16
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
相关资源
最近更新 更多