我对Python是全新的,似乎它有很多灵活性,比传统的RDBMS系统更快。在
在一个非常简单的过程中创建随机幻想团队。我来自RDBMS背景(oraclesql),对于这种数据处理来说,这似乎不是最佳选择。在
我用pandas从csv文件中读取数据帧,现在有了一个包含两列的简单数据框:Player、Salary:
` Name Salary
0 Jason Day 11700
1 Dustin Johnson 11600
2 Rory McIlroy 11400
3 Jordan Spieth 11100
4 Henrik Stenson 10500
5 Phil Mickelson 10200
6 Justin Rose 9800
7 Adam Scott 9600
8 Sergio Garcia 9400
9 Rickie Fowler 9200`
我想通过python(pandas)来制作6个玩家的所有组合,他们的薪水在45000-50000之间。在
在查找python选项时,我发现itertools的组合很有趣,但它会生成一个庞大的组合列表,而不会过滤工资总额。在
在传统的SQL中,我会执行一个大规模的合并笛卡尔连接w/SUM,但是我会让玩家在不同的位置。。在
比如A,B,C然后,C,B,A。。在
我的传统SQL不能很好地工作,如下所示:
^{pr2}$在Pandas/Python中有没有一种方法可以做到这一点?在
任何可以指出的文档都是很棒的!在
我对6个组合进行了测试,结果没有一个团队满意。我用了5个。在
这会让你达到目的:
这是一个使用简单算法的非Pandas解决方案。它从按薪水排序的玩家列表递归地生成组合。这使得它可以跳过生成超过薪资上限的组合。在
正如piRSquared提到的,没有6人的团队在问题中提到的薪水限制之内,所以我选择了限制来产生一小部分团队。在
输出
^{pr2}$如果使用的Python旧版本不支持
yield from
语法,则可以替换它与
正如评论中提到的,这是一个约束满足问题。它有一个组合部分,但由于您没有定义最小化或最大化的目标,所以它不是一个优化问题(还没有)。你可以用很多方法来解决这个问题:你可以尝试像piRSquared这样的暴力,或者使用像pm2ring这样的启发式算法。我将提出一个0-1线性规划的解决方案,并使用PuLP库来建模和解决问题。在
为了对问题建模,首先需要定义决策变量。这里,决策变量将是每个玩家的指示变量:如果选择了该玩家,则为1,否则为0。下面是如何在纸浆中做到这一点:
^{pr2}$接下来,您将创建一个问题:
正如我前面提到的,你的问题没有说明任何目标。你只想创建所有可能的团队。因此,我们将定义一个任意目标函数(我将再次回到这个任意函数)。在
主要有两个约束:
1)球队将有5名球员:
记住,玩家字典存储我们的决策变量。
players[player]
为1(如果该玩家在团队中)或0(否则)。因此,如果你把它们加起来,结果应该等于5。在2)工资总额应在45k到50k之间
这与第一个约束类似。在这里,我们不计算工资,而是将工资相加(当球员在队中时,该值将为1,因此将乘以相应的工资。否则,值将为零,乘法也将为零)。在
主要建模在这里完成。如果您调用
prob.solve()
,它将找到满足这些约束的解决方案。通常,在优化问题中,我们提供一个目标函数,并试图使其最大化或最小化。例如,假设你有玩家技能的分数。你的预算是有限的,你不能继续选择前5名球员。因此,在我们所说的prob += 0
的部分中,您可以定义一个目标函数来最大化总技能分数。但那不是你想要的,所以我们继续吧。在找到解决方案后,可以向问题添加另一个约束,声明下一个解决方案应该与此不同,您可以生成所有解决方案。在
prob.solve()
是解决问题的方法。基于结果,它返回一个整数。如果找到一个最优解,结果是1。对于不可行或无限解,有不同的代码。所以只要我们能找到新的解决方案,我们就继续循环。在在循环中,我们首先将当前解决方案附加到
feasible_solutions
列表中。然后,我们添加另一个约束:对于这5个玩家,变量之和不能超过4(最大值5,如果是5,我们知道这是相同的解)。在如果你运行这个,你会得到和piRSquared相同的结果。在
那么,这有什么好处呢?在
我们使用整数/二进制线性规划的主要原因是组合的数量增长非常快。这叫做combinatorial explosion。看看可能的团队数量(没有任何限制):
几乎不可能评估所有的组合。在
当然,当你想列出满足这些约束的所有组合时,你仍然在冒这个风险。如果满足约束条件的组合数量很大,则需要花费大量时间进行计算。你无法避免。但是,如果这个子集很小或者仍然很大,但是你正在计算这个集合上的一个函数,它会更好。在
例如,考虑以下数据帧:
75287520个解决方案中有268个满足薪资限制。在我的电脑里花了44秒才把它们列出来。用暴力手段找到他们需要几个小时(更新:It需要8小时21分钟)。在
默认情况下,PuLP使用开源解算器Cbc。还有其他开源/商业替代解决方案可以与PuLP一起使用。商业化的通常比预期的更快(尽管它们非常昂贵)。在
另一种选择是我在评论中提到的约束编程。对于这类问题,您可以找到许多聪明的方法,通过约束编程来减少搜索空间。我对整数编程很满意,所以我展示了一个基于此的模型,但是我应该注意到约束编程可能会更好。在
相关问题 更多 >
编程相关推荐