Какова правильная терминология для описания такого рода программы / алгоритма, который призывает студентов случайно, но справедливо? - PullRequest
0 голосов
/ 09 декабря 2018

Как учитель, я хотел бы разработать программу, которая поможет мне случайным образом привлекать студентов.Генератор случайных чисел не достаточно хорош, потому что несколько учеников могут быть вызваны таким образом.Я также не хочу генератора случайных очередей, потому что тогда только что вызванный студент может с уверенностью перестать обращать внимание, пока я не позову остальных ее одноклассников.

В идеале, я мог бы использовать какую-то программу, которая вызываетдля учеников 1-10 в случайной очереди, но иногда она отклоняется от этой очереди, чтобы вызвать ранее вызванных учеников.Это будет гарантировать, что все студенты будут вызываться достаточно часто, но также и то, что последний призванный студент не будет удовлетворен тем, что я не буду вызывать его снова некоторое время.Например, случайный вывод, как это было бы то, что мне нужно: 5, 7, 2, 1, 1, 9, 10, 5, 3, 6, 8, 9, 4 ...

Что такоеправильная терминология для описания такого рода программ?Я не обязательно ищу ответ о том, как написать такой код, хотя это тоже было бы неплохо.

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Вы можете выбрать учеников из группы вызовов, где каждый ученик представлен определенное количество раз.Чтобы сгладить неравномерность вызовов, количество вхождений в этом пуле выше для студентов, которые были выбраны реже, и меньше для студентов, которые были выбраны чаще, но никогда не меньше 1, чтобы дать возможность любому студенту быть вызванным снова вв любое время, независимо от его "истории звонков".Первоначально каждый ученик представлен в бассейне ровно один раз.Реализация ниже позволяет горячее включение / исключение студентов.Генератор предоставляется методом nextCall().

import java.util.*;
import java.security.SecureRandom;

public class StudentCalls {
    private final Set<String> students = new HashSet<>();
    private final List<String> callPool = new ArrayList<>();
    private static final Random rand = new SecureRandom();

    public void addStudent(String name) {
        int studentCount = students.size();
        if (!students.add(name))
            throw new IllegalArgumentException(name + " has already been added");
        int newStudentCalls = studentCount == 0 ? 1 // bootstrap
                // average of already present students', never less than 1
                : (int) Math.round((double) callPool.size() / studentCount);
        for (int i = 1; i <= newStudentCalls; i++)
            callPool.add(name);
    }

    public void addStudents(String... names) {
        for (String name : names)
            addStudent(name);
    }

    public void removeStudent(String name) {
        if (!students.remove(name))
            throw new IllegalArgumentException("Unknown student: " + name);
        callPool.removeAll(Collections.singleton(name));
    }

    public String nextCall() {
        int poolSize = callPool.size();
        if (poolSize == 0)
            throw new IllegalStateException("No students to choose from");
        int poolIndex = rand.nextInt(poolSize);
        /* Below is optimized equivalent of this code:
        String selectedStudent = callPool.remove(poolIndex);
        if (!callPool.contains(selectedStudent))
            callPool.addAll(students);
        */
        String selectedStudent = callPool.get(poolIndex);
        if (Collections.frequency(callPool, selectedStudent) > 1) {
            String lastInPool = callPool.remove(--poolSize);
            if (poolIndex < poolSize)
                callPool.set(poolIndex, lastInPool);
        } else
            for (String student : students)
                if (!student.equals(selectedStudent))
                    callPool.add(student);
        return selectedStudent;
    }

    public void conductClasses(int numberOfCalls) {
        for (int i = 0; i < numberOfCalls; i++)
            System.out.println(nextCall());
        System.out.println();
    }

    public static void main(String[] args) {
        StudentCalls sc = new StudentCalls();
        sc.addStudents("Josh", "Cooper", "Rachel", "Buckley", "Matt",
                "Lucy", "Kristin", "Kyle", "Kelly");
        sc.conductClasses(20);
        sc.removeStudent("Matt");
        sc.conductClasses(15);
        sc.addStudent("Cliff");
        sc.conductClasses(25);
    }
}
0 голосов
/ 09 декабря 2018

Вы можете пойти с Fisher-Yates Shuffle Пример:

public class Program {

    static void shuffle(int[] array) {
        int n = array.length;
        Random random = new Random();
        for (int i = 0; i < array.length; i++) {
            int randomValue = i + random.nextInt(n - i);
            int randomElement = array[randomValue];
            array[randomValue] = array[i];
            array[i] = randomElement;
        }
    }

    public static void main(String[] args) {

        int[] values = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        shuffle(values);

        // Display elements in array.
        for (int value : values) {
            System.out.println(value);
        }
    }
}
...