Разделение студентов на группы на основе равных медиан в JavaJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Разделение студентов на группы на основе равных медиан в Java

Сообщение Anonymous »

[РЕШЕНО] См. решение выше.
Я работаю над программой Java, в которой у меня есть класс ClassGenerator, который управляет оценками учащихся с течением времени и должен разделить их на группы на основе на равных медианах. Вот упрощенная версия того, чего я пытаюсь достичь:
У меня есть ученики с оценками за три года, хранящиеся в таких массивах:

Код: Выделить всё

int[] students = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
double[][] marksOverTime = {
{80, 85, 90},
{70, 75, 80},
{60, 65, 70},
{50, 55, 60},
{40, 45, 50},
{30, 35, 40},
{20, 25, 30},
{10, 15, 20},
{0, 5, 10},
{}
};
Мне нужно реализовать метод равныхMediansGroups() в ClassGenerator, который делит учащихся на группы numGroups на основе их прошлогодних оценок, гарантируя, что каждая группа имеет примерно равные медианы.
Вот что у меня есть, но это не дает правильных результатов:

Код: Выделить всё

public List equalMediansGroups() {
int[] studentsWithMarks = getStudentsWithMarks();
Arrays.sort(studentsWithMarks, Comparator.comparingDouble(this::getLastMark).reversed());

int groupSize = studentsWithMarks.length / numGroups;
int remainder = studentsWithMarks.length % numGroups;

List groups = new ArrayList();

int index = 0;
for (int i = 0; i < numGroups; i++) {
int start = index;
int end = start + groupSize + (i < remainder ? 1 : 0);

double median;
if ((end - start) % 2 == 0) {
median = (getLastMark(studentsWithMarks[end - 1]) + getLastMark(studentsWithMarks[start])) / 2.0;
} else {
median = getLastMark(studentsWithMarks[(start + end) / 2]);
}

double[] group = new double[end - start + 1];
group[0] = median;

for (int j = start; j < end; j++) {
group[j - start + 1] = studentsWithMarks[j];
}
groups.add(group);
index = end;
}
return groups;
}

public static void main(String[] args) {
int[] students = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
double[][] marksOverTime = {
{80, 85, 90},
{70, 75, 80},
{60, 65, 70},
{50, 55, 60},
{40, 45, 50},
{30, 35, 40},
{20, 25, 30},
{10, 15, 20},
{0, 5, 10},
{}
};

ClassGenerator classGenerator = new ClassGenerator(students, marksOverTime, 3);
List groups = classGenerator.equalMediansGroups();

// Print groups
for (double[] group : groups) {
System.out.println("Group median: " + group[0]);
System.out.println("Group students: " + Arrays.toString(Arrays.copyOfRange(group, 1, group.length)));
System.out.println();
}
}
Результат, который я сейчас получаю, неудовлетворительный:

Код: Выделить всё

Group median: 20.0
Group students: [9.0, 8.0, 7.0]

Group median: 50.0
Group students: [6.0, 5.0, 4.0]

Group median: 80.0
Group students: [3.0, 2.0, 1.0]
Может ли кто-нибудь помочь мне понять, какие корректировки необходимы в моем методеqualMediansGroups() для достижения правильной группировки на основе равных медиан последних оценок учащихся? Если есть новые ученики без оценок, их следует распределить равномерно по группам, поскольку они не влияют на медиану какой-либо группы.
Спасибо!
[РЕШЕНО]
Я нашел следующее решение:

Код: Выделить всё

class ClassGenerator {
private ClassGenerator() {}

public static List partitionsEqually(int[] students, double[][] marksOverTime, int numGroups) {
if (students.length != marksOverTime.length)
throw new IllegalArgumentException("The number of students and marks must be equal.");
else if (Arrays.stream(marksOverTime).anyMatch(m -> Arrays.stream(m).anyMatch(mark -> mark < 0 || mark > 100)))
throw new IllegalArgumentException("Marks must be between 0 and 100.");

// Create a list of students with their marks
List studentMarksList = new ArrayList();
for (int i = 0; i < students.length; i++) {
studentMarksList.add(new StudentMarks(students[i], marksOverTime[i]));
}

// Sort students based on their last marks
studentMarksList.sort(Comparator.comparingDouble(StudentMarks::getLastMark));

// Initialize partitions
List partitions = new ArrayList();
for (int i = 0; i < numGroups; i++) partitions.add(new ArrayList());

// Distribute students into partitions
for (int i = 0; i < studentMarksList.size();  i++)
partitions.get(i % numGroups).add(studentMarksList.get(i).studentId());

return partitions;
}

private record StudentMarks(int studentId, double[] marks) {
private StudentMarks(int studentId, double[] marks) {
this.studentId = studentId;
this.marks = Arrays.copyOf(marks, marks.length);
}

private double getLastMark() {
return marks.length > 0 ? marks[marks.length - 1] : -1;
}
}


Подробнее здесь: https://stackoverflow.com/questions/786 ... ns-in-java
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»