团队集算法的组合

时间:2015-12-05 09:46:20

标签: algorithm combinations

我们有N个学生,每个团队有M个学生,并且肯定N可以被M整除,所以递归组合就可以了。 例如 N = 6,N = 2

  

12,34,56是一个组合

     

13,24,56是另一个

但问题是生成的组合可以重复,如

  

12,34,56

     

34,12,56

是否有任何算法可以生成非重复的组合集?

此外,如果我有一个像

这样的邻接矩阵
  

S1 S2 S3 S4 S5 S6 S7 S8 S9

     

0 1 0 0 0 0 1 0 0 0

     

1 0 0 1 0 0 1 0 1 0

     

0 0 0 1 0 0 0 1 0 0

     

0 1 1 0 0 1 0 1 0 0

     

0 0 0 0 0 1 0 0 1 0

     

0 0 0 1 1 0 0 0 0 1

     

1 1 0 0 0 0 0 0 0 0

     

0 0 1 1 0 0 0 0 0 0

     

0 1 0 0 1 0 0 0 0 1

     

0 0 0 0 0 1 0 0 1 0

如果1代表哪个学生曾与其他学生一起工作,我可以生成一个团队中最大学生人数相互合作的组合最多等于m / 2吗?

1 个答案:

答案 0 :(得分:0)

我认为解决这个问题的最佳方法是为每个学生分配一个团队编号。因此,如果您有6名学生,并且团队必须是2名学生,那么您必须建立3个团队。所以[0,0,1,1,2,2]可以代表学生的合作方式。

这是一个大小为6的数组(学生数),每个位置的值代表指定的团队编号。如果我理解正确,您不希望将该团队与[1,1,2,2,0,0]区分开来,因为同一批学生将合并在一起。

我这样做的方法是从左到右为每个学生分配一个团队编号。第一个学生将始终在0队,而对于任何其他学生,只能分配一个比阵列左侧学生已使用的最大队号多一个的队号。因此,[0,1,1,2,0,2]将成为学生如何合作的候选代表,但[0,2,1,1,0,2]不是,因为位置1的学生被分配到团队2,但团队1尚未开始。

创建此类团队的代码可能类似于:

IEnumerable<int[]> CombineTeams(int numberOfStudents, int teamSize) {
    int numberOfTeams = numberOfStudents / teamSize;
    int[] studentsInTeam = new int[numberOfTeams]; // used to avoid assigning more than teamSize students into a same team
    studentsInTeam[0] = 1; // first student is initially assigned to team 0 from the start.
    List<int[]> teams = new List<int[]>(); // here all the possible teams will be stored
    int[] currentTeam = new int[numberOfStudents]; // used to assign the team numbers to studend
    AssignTeams(teamSize, currentTeam, teams, 1, 0, studentsInTeam); // start assigning team numbers from the second student, as the first will always be in team 0
    return teams;
}

void AssignTeams(int teamSize, int[] currentTeam, List<int[]> teams, int currentStudent, int maxTeam, int[] studentsInTeam) {
    if (currentStudent == currentTeam.Length) {
        int[] newTeam = new int[currentStudent];
        for (int s = 0; s < currentStudent; s++)
            newTeam[s] = currentTeam[s];
        teams.Add(newTeam);
    }
    else {
        for (int t = 0; t <= min(maxTeam+1, studentsInTeam.Length-1); t++) {
            if (studentsInTeam[t] < teamSize) {
                studentsInTeam[t]++;
                currentTeam[currentStudent] = t;
                AssignTeams(teamSize, currentTeam, teams, currentStudent+1, max(maxTeam, t), studentsInTeam);
                studentsInTeam[t]--;
            }
        }
    }
}

由于此代码创建了所有可能的组合组合,因此您可以找到最大化与M / 2的组合连接的组合(如果存在的话)(没有考虑最后一部分)。希望这对你有用。