Algorithm 团队集合组合算法
我们有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 01 0 0 0 1 0 0 0 0 10010101010 0 0 1 0 0 1 0 0 011010010 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 1 100 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 01101001 0 0 0 0 1 0 0 1 0Algorithm 团队集合组合算法,algorithm,combinations,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 01 0 0 0 1 0 0 0 0 10010101010 0 0 1 0 0 1 0 0 011010010 0 0 0 0 1 0 0
其中1表示哪个学生曾经与其他学生一起工作,我可以生成组合,其中团队中相互合作的最大学生数等于最大值的m/2吗?我认为解决此问题的最佳方法是为每个学生分配一个团队号。因此,如果你有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]--;
}
}
}
}
IEnumerable CombineTeams(int numberOfStudents,int teamSize){
int numberOfTeams=学生人数/团队规模;
int[]studentsInTeam=new int[numberOfTeams];//用于避免将超过团队规模的学生分配到同一个团队中
studentsInTeam[0]=1;//第一个学生最初从一开始就被分配到团队0。
List teams=new List();//这里将存储所有可能的团队
int[]currentTeam=new int[numberOfStudents];//用于将团队编号分配给studend
分配团队(团队大小、当前团队、团队、1、0、学生团队);//开始分配第二个学生的团队编号,因为第一个学生始终在团队0中
返回队;
}
无效分配团队(int teamSize,int[]currentTeam,List teams,int currentStudent,int maxTeam,int[]studentsInTeam){
如果(currentStudent==currentTeam.Length){
int[]新团队=新int[currentStudent];
对于(int s=0;s 对于(int t=0;t)你的例子是对的吗?你对N和M的大小有什么限制吗?仍然,N=6,N=2这是什么意思?N=学生人数(1,2,3,4,5,6)M=每个集合中选择了多少个数字else条件中的“s”变量代表什么?int[]currentTeam=new int[];该数组的大小是多少?抱歉,修复了这些错误。使用9,3运行代码时,它会将4个成员分配给团队0作为开始组合修复边缘情况。第一个学生始终分配给团队0,我没有在1中设置团队0的初始成员数。