简体   繁体   中英

Finding the optimal combination from a list of lists that maximally disperses repeating elements

I have a list of lists, where each individual list represents which people are available to take a work schedule shift. My actual data is for a list of 50 shifts:

[['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', 'P 5', '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']]

I am trying to end in a final list of 50 (ie, ['P3', 'P2', 'P4', 'P1', 'P5', 'P2', ...] with either one of two criteria:

Option A: Repeating elements are maximally dispersed

Option B: Each repeating element is at a minimum spaced apart by 2 index spaces, ie that ['P1', 'P1'] or ['P1', 'P2', 'P1] are not acceptable, but ['P1, 'P2', 'P3', 'P1'] is ok.

I don't know how to approach Option A tbh. For Option B, here is what I have so far:

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)

But the problem with my approach is I think it reaches some lists where there is one choice that causes an infinite loop. Any tips for either approach much appreciated!

To implement Option A, I suggest introducing a score or penalty that is assigned to a list. Depending on how you define "maximally dispersed", you can select the right score or penalty function. By choosing a proper one, Option B can be automatically satisfied. Consider the following system: you assign a penalty point based on:

  1. Penalty(list) = 1/(2-max(dist,2)) , where dist is the distance of the closest elements of the same type
  2. Penalty(list) = Σ_i 1/(2-max(dist_i,2) , and i goes on the same index as P_i, and dist_i is the smallest distance of the P_i instances within the list.
  3. Penalty(list) = Σ_i 1/pow(2-max(dist_i,2),2) , where you apply pow(...,2) on the previous one.

You can assign the penalty points to each list, and choose the ones with the lowest penalty. Where distance is 1 or 2, the penalty is infinity.

From the 1st to the 2nd, you consider not only the closest 2 points, but you also consider other points which are more distant, and their penalty will also contribute less.

From the 2nd to the 3rd, you penalize closeness even further.

You can also normalize the penalty, bc it is now trivial that the more points you have, the more penalty you give. Or maybe you don't want to consider this effect, but from this point, it is up to you, what your penalty points look like.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM