我一直在使用这种变化的动态规划来解决背包问题:
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
OPL遵循类似于IBM CPLEX的LP语法,它是广泛使用的优化软件,所以你可以获得关于如何使用这个LP建模LP的好参考,而且这是建立在RGLPK之上的.