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

前端之家收集整理的这篇文章主要介绍了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之上的.

猜你在找的Ruby相关文章