siqiangong 2024-07-08 16:38 采纳率: 0%
浏览 69
已结题

阅卷双评的任务分配方式

双评概念:比如高考,同一份答题卡上的作文题目,需要两个评卷人(lao shi)进行阅卷,当两个评卷人(lao shi)打分不一致时,需要仲裁以保证公平。

问题诉求:在阅卷过程中,会有一些特殊情况出现,比如:两个评卷人阅卷时,为了加快进度,又加入了一个评卷人或两个评卷人;或者本来有四个评卷人删除了一个评卷人;再或者某位评卷人不想阅卷了把剩下的转给另一个评卷人去阅。因为一份试卷要被阅两次,而且不能是同一个评卷人阅两次,所以会出现任务分配比麻烦的情况,有没有比较好的算法来解决。要不然只能机械式的一个个比对某位评卷人有没有阅过同一题块。

样例参考:当1000份答题卡,实际要阅2000次,3个评卷人阅。
初始平均分配 评卷人A:667份,评卷人B:667份,评卷人C:666份。
1、评卷人C阅了400份后把剩下的转给评卷人B,有可能会出现剩下的部分评卷人B已经阅过了不能转的情况,最终评卷人A分配多少,评卷人B分配多少?;
2、后面又增加了一个评卷人D,那该如何从评卷人A、B、C拿出部分配给D,特别是能不能做到四人平均分配,不能的情况下提示需要手动修改各评卷人的任务数量;
3、阅卷过程中又增加了500份要阅的试卷,或者删除了某个评卷人把他的所有任务回收了,那这些新增加的任务又如何重新分配给评卷人;

三种情况有可能出现一种,也有可能三种同时出现

有没有比较好的算法,首先通过点击某个按钮自动平均分配,不能平均分配则提示需要手动修改各评卷人的任务数量,至于各评卷人可以获取多少任务量在输入过程中会自动提示一个上限值?

求大咖给个全面的java的算法,最好验证过的。

  • 写回答

35条回答 默认 最新

  • CSDN专家-sinJack 2024-07-11 10:39
    关注
    获得3.00元问题酬金

    参考如下代码:

    import java.util.*;
    
    class Grader {
        private final String id;
        private final Set<Integer> gradedPapers = new HashSet<>();
        private int tasksRemaining;
    
        public Grader(String id, int initialTasks) {
            this.id = id;
            this.tasksRemaining = initialTasks;
        }
    
        public boolean canGradePaper(int paperId) {
            return !gradedPapers.contains(paperId);
        }
    
        public void gradePaper(int paperId) {
            gradedPapers.add(paperId);
            tasksRemaining--;
        }
    
        public int getTasksRemaining() {
            return tasksRemaining;
        }
    }
    
    class GradingSystem {
        private final List<Grader> graders = new ArrayList<>();
        private final Queue<Integer> papersQueue = new LinkedList<>();
        private final Map<Integer, Integer> paperGradersCount = new HashMap<>();
    
        public void addGrader(String graderId, int initialTasks) {
            Grader grader = new Grader(graderId, initialTasks);
            graders.add(grader);
            redistributeTasks();
        }
    
        public void removeGrader(String graderId) {
            Grader graderToRemove = graders.stream()
                                           .filter(grader -> grader.getId().equals(graderId))
                                           .findFirst()
                                           .orElse(null);
            if (graderToRemove != null) {
                graders.remove(graderToRemove);
                redistributeTasks();
            }
        }
    
        public void redistributeTasks() {
            int totalTasks = papersQueue.size() * 2;
            int tasksPerGrader = totalTasks / graders.size();
            int remainder = totalTasks % graders.size();
    
            for (Grader grader : graders) {
                grader.tasksRemaining = tasksPerGrader + (remainder-- > 0 ? 1 : 0);
            }
    
            while (!papersQueue.isEmpty()) {
                int paperId = papersQueue.poll();
                assignPaperToGraders(paperId);
            }
        }
    
        private void assignPaperToGraders(int paperId) {
            int requiredGraders = paperGradersCount.getOrDefault(paperId, 0) + 1;
            if (requiredGraders > 2) return; 
    
            List<Grader> availableGraders = graders.stream()
                                                   .filter(grader -> grader.canGradePaper(paperId))
                                                   .sorted(Comparator.comparingInt(Grader::getTasksRemaining))
                                                   .limit(2 - requiredGraders)
                                                   .collect(Collectors.toList());
    
            if (!availableGraders.isEmpty()) {
                Grader grader = availableGraders.get(0);
                grader.gradePaper(paperId);
                paperGradersCount.merge(paperId, 1, Integer::sum);
            }
        }
    }
    
    
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 7月17日
  • 修改了问题 7月10日
  • 修改了问题 7月10日
  • 修改了问题 7月10日
  • 展开全部