微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ruby – 背包:如何添加项目类型到现有的解决方案

我一直在使用这种变化的动态规划来解决背包问题:
KnapsackItem = Struct.new(:name,:cost,:value)
KnapsackProblem = Struct.new(:items,:max_cost)


def dynamic_programming_knapsack(problem)
  num_items = problem.items.size
  items = problem.items
  max_cost = problem.max_cost

  cost_matrix = zeros(num_items,max_cost+1)

  num_items.times do |i|
    (max_cost + 1).times do |j|
      if(items[i].cost > j)
        cost_matrix[i][j] = cost_matrix[i-1][j]
      else
        cost_matrix[i][j] = [cost_matrix[i-1][j],items[i].value + cost_matrix[i-1][j-items[i].cost]].max
      end
    end
  end

  cost_matrix
end

def get_used_items(problem,cost_matrix)
  i = cost_matrix.size - 1
  currentCost = cost_matrix[0].size - 1
  marked = Array.new(cost_matrix.size,0) 

  while(i >= 0 && currentCost >= 0)
    if(i == 0 && cost_matrix[i][currentCost] > 0 ) || (cost_matrix[i][currentCost] != cost_matrix[i-1][currentCost])
      marked[i] = 1
      currentCost -= problem.items[i].cost
    end
    i -= 1
  end
  marked
end

这对上述结构非常有用,您只需提供一个名称,成本和价值.项目可以创建如下:

items = [
      KnapsackItem.new('david lee',8000,30),KnapsackItem.new('kevin love',12000,50),KnapsackItem.new('kemba walker',7300,10),KnapsackItem.new('jrue holiday',12300,KnapsackItem.new('stephen curry',10300,80),KnapsackItem.new('lebron james',5300,90),KnapsackItem.new('kevin durant',2300,KnapsackItem.new('russell westbrook',9300,KnapsackItem.new('kevin martin',8300,15),KnapsackItem.new('steve nash',4300,KnapsackItem.new('kyle lowry',6300,20),KnapsackItem.new('monta ellis',KnapsackItem.new('dirk Nowitzki',25),KnapsackItem.new('david lee',9500,35),KnapsackItem.new('klay thompson',6800,28)
    ]

  problem = KnapsackProblem.new(items,65000)

现在,我遇到的问题是,我需要为每个玩家添加一个职位,而且我必须让背包算法知道,除了有一个新的限制和限制之外,它还需要最大化所有玩家的价值.每个玩家都有一个位置,每个位置只能选择一定的次数.一些职位可以选择两次,另外一次.项目理想地成为这样:

KnapsackItem = Struct.new(:name,:position,:value)

职位将受到如下限制:

PositionLimits = Struct.new(:position,:max)

限制将被实例化,也许像下面这样:

limits = [Struct.new('PG',2),Struct.new('C',1),Struct.new('SF',Struct.new('PF',Struct.new('Util',2)]

每个玩家都可以在Util的位置使这更加棘手一点.如果我们要禁用Util位置,我们将把2设置为0.

我们的原始项目数组将如下所示:

items = [
          KnapsackItem.new('david lee','PF','C','PG',... etc ...
        ]

如何将位置限制添加到背包算法中,以便仍然保留提供的播放器池的最大值?

解决方法

有一些高效的图书馆可用于ruby,可以满足您的任务,很明显,您正在寻找一些 constrain based optimization,有一些ruby的图书馆是一个免费使用的开源,只需将它们包含在您的项目中.所有你需要做的就是从你的约束中产生 Linear programming模型目标函数,并且库的优化器将产生满足所有约束的解决方案,或者说如果没有可以从给定约束中得出结论,则说没有解决方案存在.

一些这样的图书馆可用于ruby

> RGLPK
> OPL
> LP Solve

OPL遵循类似于IBM CPLEX的LP语法,它是广泛使用的优化软件,所以你可以获得关于如何使用这个LP建模LP的好参考,而且这是建立在RGLPK之上的.

原文地址:https://www.jb51.cc/ruby/267202.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐