我们有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吗?
答案 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的组合连接的组合(如果存在的话)(没有考虑最后一部分)。希望这对你有用。