【问题标题】:Finding the optimal combination from a list of lists that maximally disperses repeating elements从最大分散重复元素的列表列表中找到最佳组合
【发布时间】:2022-01-20 03:54:08
【问题描述】:

我有一个列表列表,其中每个单独的列表代表哪些人可以参加工作计划轮班。我的实际数据是 50 个班次的列表:

[['P3', 'P2', 'P4', 'P5'], ['P1', 'P3', 'P2', 'P4'], ['P1', 'P3', ' P2','P4'],['P1'],['P5'],['P1','P3','P5','P2','P4'],['P1','P3' , 'P5', 'P2', 'P4'], ['P3', 'P2', 'P4', 'P5'], ['P3', 'P2', 'P4', 'P5'], ['P2', 'P5'], ['P1', 'P2', 'P5'], ['P1', 'P2', 'P5'], ['P1', 'P3', 'P5' , 'P2', 'P4'], ['P5'], ['P2'], ['P1', 'P3', 'P4', 'P5'], ['P1', 'P3', ' P4','P5'],['P1','P3','P4','P5'],['P1','P3','P5','P2','P4'],[' P1','P3','P5','P2','P4'],['P1','P3','P5','P2','P4'],['P1','P3' , 'P2', 'P4'], ['P1', 'P3', 'P2', 'P4'], ['P1', 'P3', 'P2', 'P4'], ['P1' , 'P3', 'P5', 'P2', 'P4'], ['P1', 'P3', 'P5', 'P2', 'P4'], ['P1', 'P3', ' P5','P2','P4'],['P1','P3','P5','P2','P4'],['P1','P3','P5','P2' , 'P4'], ['P1', 'P3', 'P4'], ['P1', 'P3', 'P2', 'P4'], ['P1', 'P2', 'P4' ],['P1','P2','P4','P5'],['P1','P2','P5'],['P1','P3','P2','P5' ],['P1','P3','P2','P5'],['P1','P3','P5','P2','P4'],['P1','P3' , 'P5', 'P2', 'P4'], ['P1', 'P3', 'P5', 'P2', 'P4'], ['P1', 'P3', 'P5', 'P2', 'P4'], ['P1', 'P3', 'P5', 'P2', 'P4'], ['P2'], ['P4'], ['P1' ', 'P3', 'P5', 'P2', 'P4'], ['P1', 'P3', 'P5', 'P2', 'P4'], ['P1', 'P3', 'P5', 'P2', 'P4'], ['P1', 'P3', 'P5', 'P2', 'P4'], ['P1', 'P3', 'P5', 'P2' ', 'P4'], ['P1', 'P3', 'P5', 'P2', 'P4'], ['P1', 'P3', 'P2', 'P4'], ['P1 ', 'P3', 'P2', 'P4']]

我试图以 50 个最终列表结束(即 ['P3', 'P2', 'P4', 'P1', 'P5', 'P2', ...]两个标准:

选项 A:重复元素最大程度地分散

选项 B:每个重复元素至少间隔 2 个索引空间,即 ['P1', 'P1'] 或 ['P1', 'P2', 'P1] 是不可接受的,但 [ 'P1, 'P2', 'P3', 'P1'] 没问题。

我不知道如何处理选项 A tbh。对于选项 B,这是我目前所拥有的:

AssignList = []
for ix, x in enumerate(AvailableList):
    randx = random.choice(x)
    if len(AssignList)==1:
        while randx==AssignList[0]:
            randx=random.choice(x)
    if len(AssignList)>1:
        while (randx==AssignList[-1]) | (randx==AssignList[-2]):
            randx=random.choice(x)
    AssignList.append(randx)
print(AssignList)

但是我的方法的问题是我认为它到达了一些列表,其中有一个选择会导致无限循环。非常感谢任何一种方法的提示!

【问题讨论】:

  • 您是否希望您的最终列表是包含 50 个元素的单个列表,您能否举一个输入较少且预期完整输出的简单示例以说明清楚,您可以根据这两个你有的选择,
  • 是的,相信我在上面确实提到了预期结果是一个包含 50 个元素的列表,我说作为示例,输出将是:['P3', 'P2', 'P4', ' P1','P5','P2',...]。关于两个选项的不同输出,我认为选项 A 有点难以展示,但以上将满足选项 B 对前 6 个元素的要求。
  • 此列表中的所有子列表中有超过 50 个元素。可以将这个列表展平并从那个大池中选择 50 个吗?
  • 不,抱歉应该更好地澄清这一点。目标是从每个子列表中选择 1 个元素,总共 n 个元素,其中 n 是较大列表的长度(在这种情况下,我认为是 50 或 51)。每个子列表代表可以轮班工作的人员(P1、P2 等),因此目标是将每个子列表中的 1 分配给轮班。

标签: python random schedule


【解决方案1】:

要实施选项 A,我建议引入分配给列表的分数或罚分。根据您定义“最大分散”的方式,您可以选择正确的得分或罚分函数。通过选择一个合适的选项,可以自动满足选项 B。考虑以下系统:您根据以下条件分配罚分:

  1. Penalty(list) = 1/(2-max(dist,2)),其中dist是同类型元素最近的距离
  2. Penalty(list) = Σ_i 1/(2-max(dist_i,2),并且 i 与 P_i 在同一索引上,并且 dist_i 是列表中 P_i 实例的最小距离。
  3. Penalty(list) = Σ_i 1/pow(2-max(dist_i,2),2),您将 pow(...,2) 应用于前一个。

您可以将罚分分配给每个列表,并选择罚分最低的那些。如果距离为 1 或 2,则惩罚为无穷大。

从第1到第2,你不仅考虑最近的2分,还考虑距离较远的其他点,他们的点球贡献也会更少。

从第 2 次到第 3 次,你会进一步惩罚亲密关系。

您还可以将惩罚标准化,因为现在您拥有的分数越多,您给予的惩罚就越多,这是微不足道的。或者你可能不想考虑这种影响,但从这一点来看,你的罚分是什么样的取决于你。

【讨论】:

    猜你喜欢
    • 2021-01-01
    • 2017-02-13
    • 2020-09-02
    • 2021-10-10
    • 1970-01-01
    • 2022-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多