Weekly group assignment algorithm with odd number of participants

最后都变了- 提交于 2019-12-19 04:58:04

问题


There is a round-robin solution to a question I asked before. It works great with even number of people but none of the suggestions seem to work once you implement the algorithm and try them out. I've tried many variations and (grouping the last one with a whole bunch of other people, the second group the last group, different combinations, the 2 and 4 to the last of the bottom row, I thought this would give me the most optimal solution but still many duplicates). Can someone suggest a way to go, or a proof that there cannot be a solution without 2 people working together more than once so I can stop trying to make it work. If you want the algorithm in java I can post it so you can play with it.

Thanks.


回答1:


14 weeks for 23 students in groups of 2 and one 3 is sufficiently undemanding that local search is able to find a solution.

 18  1 11|  3  4|  5  7|  9  6|  0 17|  2 12| 10 19| 15 16| 21  8| 14 20| 13 22|
  6 13 18| 17  4|  5  0| 20  1| 12 11| 10  9|  2 14| 15  7|  3  8| 19 16| 21 22|
 21 17  7| 19 22|  3  1|  2  8|  0 10| 14 12| 13 11|  6 16|  5 15| 18 20|  9  4|
  8  1 13| 18  2|  6 11| 20  0| 12 10| 14 15|  5 17|  9 21|  4 19|  3 22| 16  7|
  0  4 16| 17 20| 21  3|  7 18| 13 19|  1  5|  9 11| 15  2| 14  8| 10  6| 12 22|
 12  1 17| 15  4|  8  6| 16 18|  9  0| 11 22|  5 14|  3  2|  7 13| 19 20| 21 10|
  4  1 22| 12  8| 15  6|  7  0|  9 17| 11  3| 13  2|  5 18| 10 14| 19 21| 20 16|
  0  1  6| 13 21| 15 12| 17  8| 20 10| 11  4|  3 14|  5 16|  7  2| 19  9| 18 22|
 13 16  3|  2  9| 11 20|  6 17| 22 10|  5 12|  0 14| 15  1|  8 18| 19  7| 21  4|
 14  1  7|  2  4|  5  9|  3  6|  8 10| 13 12| 21  0| 17 16| 22 20| 19 18| 11 15|
 14 18 21| 12  4|  5  6|  2 19|  8 20|  1  9| 13  0| 11 16| 17 15|  3 10|  7 22|
 21  6  2|  3 20|  5 13| 16  8| 18 17|  0 12| 22 14| 10  1|  9 15|  7  4| 11 19|
  0 11  2|  6  4| 16 14|  7  8| 17 10|  1 19| 13  9|  3 18| 21 12| 20  5| 15 22|
  1 16  2| 14 13|  3  7|  8  4| 11 10|  9 12|  0 18| 15 19| 17 22|  6 20| 21  5|

Here's the Java code that made it.

public class Schedule {
  private final int weekCount;
  private final int groupCount;
  private final int personCount;
  private final int groupFirstSlot[];
  private final int weekSlotPerson[][];

  public Schedule(int weekCount, int groupCount, int personCount) {
    this.weekCount = weekCount;
    this.groupCount = groupCount;
    this.personCount = personCount;
    int remainingPersonCount = personCount;
    this.groupFirstSlot = new int[groupCount + 1];
    for (int remainingGroupCount = groupCount;
         remainingGroupCount > 0;
         remainingGroupCount--) {
      groupFirstSlot[remainingGroupCount] = remainingPersonCount;
      remainingPersonCount -= remainingPersonCount / remainingGroupCount;
    }
    this.weekSlotPerson = new int[weekCount][personCount];
    for (int week = 0; week < weekCount; week++) {
      for (int person = 0; person < personCount; person++) {
        weekSlotPerson[week][person] = person;
      }
    }
  }

  public int getWeekCount() {
    return weekCount;
  }

  public int getGroupCount() {
    return groupCount;
  }

  public int getPersonCount() {
    return personCount;
  }

  public int getGroupFirstSlot(int group) {
    return groupFirstSlot[group];
  }

  public int getWeekSlotPerson(int week, int slot) {
    return weekSlotPerson[week][slot];
  }

  public void swapWeekSlotPerson(int week, int slotOne, int slotTwo) {
    int temp = weekSlotPerson[week][slotOne];
    weekSlotPerson[week][slotOne] = weekSlotPerson[week][slotTwo];
    weekSlotPerson[week][slotTwo] = temp;
  }

  public int getConflictCount() {
    int pairCount[][] = new int[personCount][personCount];
    for (int week = 0; week < weekCount; week++) {
      for (int group = 0; group < groupCount; group++) {
        for (int slotOne = groupFirstSlot[group];
             slotOne < groupFirstSlot[group + 1];
             slotOne++) {
          int personOne = weekSlotPerson[week][slotOne];
          for (int slotTwo = groupFirstSlot[group];
               slotTwo < groupFirstSlot[group + 1];
               slotTwo++) {
            int personTwo = weekSlotPerson[week][slotTwo];
            pairCount[personOne][personTwo]++;
          }
        }
      }
    }
    int conflictCount = 0;
    for (int personOne = 0; personOne < personCount; personOne++) {
      for (int personTwo = personOne + 1;
           personTwo < personCount;
           personTwo++) {
        int pc = pairCount[personOne][personTwo];
        conflictCount += pc * (pc - 1) / 2;
      }
    }
    return conflictCount;
  }

  public static void main(String[] args) {
    Schedule sched = new Schedule(14, 11, 23);
    java.util.Random rand = new java.util.Random();
    int oldCc = sched.getConflictCount();
    while (oldCc > 0) {
      int week = rand.nextInt(sched.getWeekCount());
      int slotOne = rand.nextInt(sched.getPersonCount());
      int slotTwo = rand.nextInt(sched.getPersonCount());
      sched.swapWeekSlotPerson(week, slotOne, slotTwo);
      int newCc = sched.getConflictCount();
      if (newCc < oldCc) {
        oldCc = newCc;
      } else {
        sched.swapWeekSlotPerson(week, slotOne, slotTwo);
      }
    }
    for (int week = 0; week < sched.getWeekCount(); week++) {
      for (int group = 0; group < sched.getGroupCount(); group++) {
        for (int slot = sched.getGroupFirstSlot(group);
             slot < sched.getGroupFirstSlot(group + 1);
             slot++) {
          System.out.printf("%3d",
                            sched.getWeekSlotPerson(week, slot));
        }
        System.out.print('|');
      }
      System.out.println();
    }
  }
}


来源:https://stackoverflow.com/questions/15823106/weekly-group-assignment-algorithm-with-odd-number-of-participants

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!