Python 写优化函数
我正试图写一个网球预订系统,但我被这个问题绊住了。 比如说,你有一些球员在球场号码、日期和时间方面有自己的首选项。 此外,每个玩家都有排名,因此如果有一天/小时的时段,并且有几个玩家 对于此插槽的首选项,应选择具有最高优先级的插槽。 我正在考虑使用一些优化算法来解决这个问题,但我不确定使用什么样的成本函数和/或算法最好。 有什么建议吗? 还有一件事我更喜欢使用Python,但也欢迎一些语言不可知的建议。 谢谢 编辑: 一些澄清- 优先级较高的人获胜,失败者被移动到最近的位置, 相当灵活的时段问题Python 写优化函数,python,algorithm,Python,Algorithm,我正试图写一个网球预订系统,但我被这个问题绊住了。 比如说,你有一些球员在球场号码、日期和时间方面有自己的首选项。 此外,每个玩家都有排名,因此如果有一天/小时的时段,并且有几个玩家 对于此插槽的首选项,应选择具有最高优先级的插槽。 我正在考虑使用一些优化算法来解决这个问题,但我不确定使用什么样的成本函数和/或算法最好。 有什么建议吗? 还有一件事我更喜欢使用Python,但也欢迎一些语言不可知的建议。 谢谢 编辑: 一些澄清- 优先级较高的人获胜,失败者被移动到最近的位置, 相当灵活的时段问题
是的,最大限度地增加获得最高优先时间的人数,我认为这是一个NP完全问题,因此不可能对任何大型数据集有一个非常快速的算法 还有一个问题,你可能有一个无法制定的时间表。考虑到情况并非如此,类似这样的伪代码可能是您的最佳选择:
sort players by priority, highest to lowest
start with empty schedule
for player in players:
for timeslot in player.preferences():
if timeslot is free:
schedule.fillslot(timeslot, player)
break
else:
#if we get here, it means this player couldn't be accomodated at all.
#you'll have to go through the slots that were filled and move another (higher-priority) player's time slot
在回答这个问题之前,我要问几个问题:
- 如果发生冲突,即一名较差的球员先预订,然后一名较好的球员预订同一场地,会发生什么情况?谁赢了?失败者会怎样
- 你是让最好的球员在比赛进行的时间内上场,还是有固定的时间段
- 调度运行的频率是多少?它是以交互方式运行的吗?因此,可能有人会被告知他们可以玩,但却被告知他们不能玩;或者它是以更批量的方式运行的——您输入请求,然后稍后会被告知是否可以使用插槽。或者用户是否设置了一些首选时间,然后系统必须最大限度地增加获得他们最喜欢的时间的人数
另一方面,您可以通过将时间重新写入整数索引(因此您处理的是整数而不是时间)来稍微降低复杂性。根据谁付的钱最多来分配时段。在抽签的情况下,不要让他们中的任何一个拥有该插槽。您描述的是一个匹配问题。可能的参考文献包括和。如果玩家的数量与球场的数量相等,则可以达到稳定的匹配-。其他公式变得更难。我建议使用评分算法。基本上构造一个公式,将您描述的所有值拉入一个数字。最终得分最高的人将赢得该位置。例如,一个简单的公式可能是:
FinalScore = ( PlayerRanking * N1 ) + ( PlayerPreference * N2 )
其中N1、N2是控制公式的权重
这将让你很快得到好的(不是完美的)结果。我们在更复杂的系统上使用这种方法,并取得了很好的效果
您可以通过添加玩家赢得或失去插槽的次数,或者(如有人建议的)玩家支付的金额等因素来增加更多种类
此外,您还可以使用多个通行证来分配一天中的时段。使用一种按时间顺序排列的策略,一种按逆时间顺序排列的策略,一种先做上午的策略,一种先做下午的策略,等等。然后将获得分数的球员的分数相加,然后你就可以决定提供最佳结果的策略。基本上,你的优势是球员有优先权;因此,您可以按优先级降序对玩家进行排序,然后开始为他们分配插槽。第一个得到他们喜欢的位置,然后下一个在免费的位置中得到他喜欢的位置,依此类推。这是一个O(N)算法。基本算法 我会根据排名对球员进行排序,因为排名靠前的球员总是会排挤排名靠后的球员。然后你从排名最高的球员开始,给他他想要的(如果他真的是最高的,他总是会赢,因此你也可以给他任何他想要的)。然后我会从第二高的开始。如果他要的东西已经被最高者拿走了,试着在附近找一个位子,把这个位子分配给他。现在是第三高的。如果他要的东西已经被最高的那个拿走了,把他移到附近的一个位置。如果这个位置已经被第二高的那个占据了,把他移到更远的位置。继续与所有其他玩家一起 需要考虑的一些调整: 如果多个玩家可以拥有相同的排名,您可能需要实现一些“公平”。如果您使用快速排序等方式对所有排名相同的玩家进行排序,则他们之间会有一个随机顺序。你可以得到一些公平,如果你不为玩家而做,而是为等级而做。你从最高级别和该级别的第一个玩家开始。处理他的第一个请求。然而,在你处理他的第二个请求之前,先处理下一个排名最高的玩家的第一个请求,然后再处理排名最高的第三个玩家的第一个请求。算法与上述相同,但假设您有10名玩家,玩家1-4为最高级别,玩家5-7为较低级别,玩家8-10为极低级别,并且每个玩家提出3个请求,您将按照以下方式处理它们:
Player 1 - Request 1
Player 2 - Request 1
Player 3 - Request 1
Player 4 - Request 1
Player 1 - Request 2
Player 2 - Request 2
:
这样你就公平了。你也可以每次在一个排名类中随机选择,这也可以提供一些公平性
您甚至可以跨级别实现公平性。如果你有4个等级,你可以说
Rank 1 - 50%
Rank 2 - 25%
Rank 3 - 12,5%
Rank 4 - 6,25%
(仅作为示例值,您可以使用与始终乘以0.5不同的键,例如乘以0.8,导致数字减少的速度变慢)
现在你可以说,你开始处理排名1,但是一旦所有排名1的请求中有50%得到了满足,你就转到排名2,并确保他们的请求中有25%得到了满足,依此类推。这样,即使排名4的用户也可以赢得排名1的用户,这在一定程度上击败了初始算法,但是您提供了一些公平性。即使一个排名4的玩家有时也能得到他的请求,他不会“跑光”。否则,排名1的玩家会同时安排每个请求