Search in sources :

Example 6 with ExamModel

use of org.cpsolver.exam.model.ExamModel in project cpsolver by UniTime.

the class StudentBackToBackConflicts method getValue.

@Override
public double getValue(Assignment<Exam, ExamPlacement> assignment, ExamPlacement value, Set<ExamPlacement> conflicts) {
    Exam exam = value.variable();
    int penalty = 0;
    ExamPeriod period = value.getPeriod();
    Map<ExamStudent, Set<Exam>> prev = (period.prev() != null && (isDayBreakBackToBack() || period.prev().getDay() == period.getDay()) ? ((ExamModel) getModel()).getStudentsOfPeriod(assignment, period.prev()) : null);
    Map<ExamStudent, Set<Exam>> next = (period.next() != null && (isDayBreakBackToBack() || period.next().getDay() == period.getDay()) ? ((ExamModel) getModel()).getStudentsOfPeriod(assignment, period.next()) : null);
    for (ExamStudent s : exam.getStudents()) {
        if (prev != null) {
            Set<Exam> exams = prev.get(s);
            if (exams != null) {
                int nrExams = exams.size() + (exams.contains(exam) ? -1 : 0);
                penalty += nrExams;
            }
        }
        if (next != null) {
            Set<Exam> exams = next.get(s);
            if (exams != null) {
                int nrExams = exams.size() + (exams.contains(exam) ? -1 : 0);
                penalty += nrExams;
            }
        }
    }
    /*
        for (ExamStudent s : exam.getStudents()) {
            if (period.prev() != null) {
                if (isDayBreakBackToBack() || period.prev().getDay() == period.getDay()) {
                    Set<Exam> exams = s.getExams(assignment, period.prev());
                    int nrExams = exams.size() + (exams.contains(exam) ? -1 : 0);
                    penalty += nrExams;
                }
            }
            if (period.next() != null) {
                if (isDayBreakBackToBack() || period.next().getDay() == period.getDay()) {
                    Set<Exam> exams = s.getExams(assignment, period.next());
                    int nrExams = exams.size() + (exams.contains(exam) ? -1 : 0);
                    penalty += nrExams;
                }
            }
        }
        */
    return penalty;
}
Also used : ExamPeriod(org.cpsolver.exam.model.ExamPeriod) Set(java.util.Set) ExamModel(org.cpsolver.exam.model.ExamModel) ExamStudent(org.cpsolver.exam.model.ExamStudent) Exam(org.cpsolver.exam.model.Exam)

Example 7 with ExamModel

use of org.cpsolver.exam.model.ExamModel in project cpsolver by UniTime.

the class StudentDistanceBackToBackConflicts method getValue.

@Override
public double getValue(Assignment<Exam, ExamPlacement> assignment, ExamPlacement value, Set<ExamPlacement> conflicts) {
    Exam exam = value.variable();
    if (getBackToBackDistance() < 0)
        return 0;
    int penalty = 0;
    ExamPeriod period = value.getPeriod();
    Map<ExamStudent, Set<Exam>> prev = (period.prev() != null && period.prev().getDay() == period.getDay() ? ((ExamModel) getModel()).getStudentsOfPeriod(assignment, period.prev()) : null);
    Map<ExamStudent, Set<Exam>> next = (period.next() != null && period.next().getDay() == period.getDay() ? ((ExamModel) getModel()).getStudentsOfPeriod(assignment, period.next()) : null);
    for (ExamStudent s : exam.getStudents()) {
        if (prev != null) {
            Set<Exam> exams = prev.get(s);
            if (exams != null)
                for (Exam x : exams) {
                    if (x.equals(exam))
                        continue;
                    if (value.getDistanceInMeters(assignment.getValue(x)) > getBackToBackDistance())
                        penalty++;
                }
        }
        if (next != null) {
            Set<Exam> exams = next.get(s);
            if (exams != null)
                for (Exam x : exams) {
                    if (x.equals(exam))
                        continue;
                    if (value.getDistanceInMeters(assignment.getValue(x)) > getBackToBackDistance())
                        penalty++;
                }
        }
    }
    /*
        for (ExamStudent s : exam.getStudents()) {
            if (period.prev() != null) {
                if (period.prev().getDay() == period.getDay()) {
                    for (Exam x : s.getExams(assignment, period.prev())) {
                        if (x.equals(exam))
                            continue;
                        if (value.getDistanceInMeters(assignment.getValue(x)) > getBackToBackDistance())
                            penalty++;
                    }
                }
            }
            if (period.next() != null) {
                if (period.next().getDay() == period.getDay()) {
                    for (Exam x : s.getExams(assignment, period.next())) {
                        if (x.equals(exam))
                            continue;
                        if (value.getDistanceInMeters(assignment.getValue(x)) > getBackToBackDistance())
                            penalty++;
                    }
                }
            }
        }
        */
    return penalty;
}
Also used : ExamPeriod(org.cpsolver.exam.model.ExamPeriod) Set(java.util.Set) ExamModel(org.cpsolver.exam.model.ExamModel) ExamStudent(org.cpsolver.exam.model.ExamStudent) Exam(org.cpsolver.exam.model.Exam)

Example 8 with ExamModel

use of org.cpsolver.exam.model.ExamModel in project cpsolver by UniTime.

the class ExamRoomMove method selectNeighbour.

/**
     * Select an exam randomly, select an available period randomly (if it is
     * not assigned, from {@link Exam#getPeriodPlacements()}), select rooms
     * using {@link Exam#findRoomsRandom(Assignment, ExamPeriodPlacement)}
     */
@Override
public Neighbour<Exam, ExamPlacement> selectNeighbour(Solution<Exam, ExamPlacement> solution) {
    ExamModel model = (ExamModel) solution.getModel();
    Assignment<Exam, ExamPlacement> assignment = solution.getAssignment();
    Exam exam = ToolBox.random(model.variables());
    if (exam.getMaxRooms() <= 0)
        return null;
    ExamPlacement placement = assignment.getValue(exam);
    ExamPeriodPlacement period = (placement != null ? placement.getPeriodPlacement() : (ExamPeriodPlacement) ToolBox.random(exam.getPeriodPlacements()));
    if (iCheckStudentConflicts && placement == null && exam.countStudentConflicts(assignment, period) > 0)
        return null;
    if (iCheckDistributionConstraints && placement == null && !exam.checkDistributionConstraints(assignment, period))
        return null;
    Set<ExamRoomPlacement> rooms = (placement != null ? placement.getRoomPlacements() : exam.findBestAvailableRooms(assignment, period));
    if (rooms == null || rooms.isEmpty())
        return null;
    if (placement == null)
        placement = new ExamPlacement(exam, period, rooms);
    List<ExamRoomPlacement> roomVect = new ArrayList<ExamRoomPlacement>(rooms);
    int rx = ToolBox.random(roomVect.size());
    for (int r = 0; r < roomVect.size(); r++) {
        ExamRoomPlacement current = roomVect.get((r + rx) % roomVect.size());
        int mx = ToolBox.random(exam.getRoomPlacements().size());
        for (int m = 0; m < exam.getRoomPlacements().size(); m++) {
            ExamRoomPlacement swap = exam.getRoomPlacements().get((m + mx) % exam.getRoomPlacements().size());
            ExamRoomSwapNeighbour n = new ExamRoomSwapNeighbour(assignment, placement, current, swap);
            if (n.canDo())
                return n;
        }
    }
    rooms = exam.findRoomsRandom(assignment, period);
    if (rooms == null)
        return null;
    return new ExamSimpleNeighbour(assignment, new ExamPlacement(exam, period, rooms));
}
Also used : ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) ExamModel(org.cpsolver.exam.model.ExamModel) ArrayList(java.util.ArrayList) ExamPeriodPlacement(org.cpsolver.exam.model.ExamPeriodPlacement) Exam(org.cpsolver.exam.model.Exam)

Example 9 with ExamModel

use of org.cpsolver.exam.model.ExamModel in project cpsolver by UniTime.

the class Test method addCSVLine.

private static void addCSVLine(File file, String instance, String config, Solution<Exam, ExamPlacement> solution) {
    try {
        ExamModel model = (ExamModel) solution.getModel();
        Assignment<Exam, ExamPlacement> assignment = solution.getAssignment();
        boolean ex = file.exists();
        PrintWriter pw = new PrintWriter(new FileWriter(file, true));
        boolean mpp = ((PerturbationPenalty) model.getCriterion(PerturbationPenalty.class)).isMPP();
        int largeSize = ((LargeExamsPenalty) model.getCriterion(LargeExamsPenalty.class)).getLargeSize();
        RoomSplitDistancePenalty splitDistance = (RoomSplitDistancePenalty) model.getCriterion(RoomSplitDistancePenalty.class);
        ExamSplitter splitter = (ExamSplitter) model.getCriterion(ExamSplitter.class);
        PeriodViolation violPer = (PeriodViolation) model.getCriterion(PeriodViolation.class);
        RoomViolation violRoom = (RoomViolation) model.getCriterion(RoomViolation.class);
        DistributionViolation violDist = (DistributionViolation) model.getCriterion(DistributionViolation.class);
        DistanceToStronglyPreferredRoom distStrPref = (DistanceToStronglyPreferredRoom) model.getCriterion(DistanceToStronglyPreferredRoom.class);
        ExamRotationPenalty rotation = (ExamRotationPenalty) model.getCriterion(ExamRotationPenalty.class);
        DecimalFormat df = new DecimalFormat("0.00");
        if (!ex) {
            pw.println("SEED" + ",NA,DC,M2D,BTB" + (model.getBackToBackDistance() < 0 ? "" : ",dBTB") + ",iNA,iDC,iM2D,iBTB" + (model.getBackToBackDistance() < 0 ? "" : ",diBTB") + ",PP,RP,DP" + // Period Index, Rotation Penalty, Period Size
            ",PI,@P,PS" + // Room Size, Room Split, Room Split Distance
            ",RSz,RSp,RD" + (largeSize >= 0 ? ",LP" : "") + (mpp ? ",IP,IRP" : "") + (distStrPref == null ? "" : ",@D") + (splitter == null ? "" : ",XX") + (violPer == null ? "" : ",!P") + (violRoom == null ? "" : ",!R") + (violDist == null ? "" : ",!D") + ",INSTANCE,CONFIG");
            int nrStudentExams = 0;
            for (ExamStudent student : model.getStudents()) {
                nrStudentExams += student.variables().size();
            }
            int nrInstructorExams = 0;
            for (ExamInstructor instructor : model.getInstructors()) {
                nrInstructorExams += instructor.variables().size();
            }
            pw.println("MIN" + ",#EX,#RM,#PER," + (model.getBackToBackDistance() < 0 ? "" : ",") + ",#STD,#STDX,#INS,#INSX" + (model.getBackToBackDistance() < 0 ? "" : ",") + "," + model.getCriterion(PeriodPenalty.class).getBounds(assignment)[0] + "," + model.getCriterion(RoomPenalty.class).getBounds(assignment)[0] + "," + model.getCriterion(DistributionPenalty.class).getBounds(assignment)[0] + ",," + df.format(rotation.averagePeriod(assignment)) + "," + ",,," + (largeSize >= 0 ? ",0" : "") + (mpp ? ",," : "") + (distStrPref == null ? "" : ",") + (splitter == null ? "" : ",") + (violPer == null ? "" : ",") + (violRoom == null ? "" : ",") + (violDist == null ? "" : ",") + ",,");
            pw.println("MAX" + "," + model.variables().size() + "," + model.getRooms().size() + "," + model.getPeriods().size() + "," + (model.getBackToBackDistance() < 0 ? "" : ",") + "," + model.getStudents().size() + "," + nrStudentExams + "," + model.getInstructors().size() + "," + nrInstructorExams + (model.getBackToBackDistance() < 0 ? "" : ",") + "," + model.getCriterion(PeriodPenalty.class).getBounds(assignment)[1] + "," + model.getCriterion(RoomPenalty.class).getBounds(assignment)[1] + "," + model.getCriterion(DistributionPenalty.class).getBounds(assignment)[1] + ",," + rotation.nrAssignedExamsWithAvgPeriod(assignment) + "," + ",,," + (largeSize >= 0 ? "," + model.getCriterion(LargeExamsPenalty.class).getBounds(assignment)[1] : "") + (mpp ? ",," : "") + (distStrPref == null ? "" : ",") + (splitter == null ? "" : ",") + (violPer == null ? "" : "," + model.getCriterion(PeriodViolation.class).getBounds(assignment)[1]) + (violRoom == null ? "" : "," + model.getCriterion(RoomViolation.class).getBounds(assignment)[1]) + (violDist == null ? "" : "," + model.getCriterion(DistributionViolation.class).getBounds(assignment)[1]) + ",,");
        }
        pw.println(ToolBox.getSeed() + "," + model.getCriterion(StudentNotAvailableConflicts.class).getValue(assignment) + "," + model.getCriterion(StudentDirectConflicts.class).getValue(assignment) + "," + model.getCriterion(StudentMoreThan2ADayConflicts.class).getValue(assignment) + "," + model.getCriterion(StudentBackToBackConflicts.class).getValue(assignment) + (model.getBackToBackDistance() < 0 ? "" : "," + model.getCriterion(StudentDistanceBackToBackConflicts.class).getValue(assignment)) + "," + model.getCriterion(InstructorNotAvailableConflicts.class).getValue(assignment) + "," + model.getCriterion(InstructorDirectConflicts.class).getValue(assignment) + "," + model.getCriterion(InstructorMoreThan2ADayConflicts.class).getValue(assignment) + "," + model.getCriterion(InstructorBackToBackConflicts.class).getValue(assignment) + (model.getBackToBackDistance() < 0 ? "" : "," + model.getCriterion(InstructorDistanceBackToBackConflicts.class).getValue(assignment)) + "," + model.getCriterion(PeriodPenalty.class).getValue(assignment) + "," + model.getCriterion(RoomPenalty.class).getValue(assignment) + "," + model.getCriterion(DistributionPenalty.class).getValue(assignment) + "," + df.format(model.getCriterion(PeriodIndexPenalty.class).getValue(assignment) / assignment.nrAssignedVariables()) + "," + df.format(Math.sqrt(rotation.getValue(assignment) / rotation.nrAssignedExamsWithAvgPeriod(assignment)) - 1) + "," + df.format(model.getCriterion(PeriodSizePenalty.class).getValue(assignment) / assignment.nrAssignedVariables()) + "," + df.format(model.getCriterion(RoomSizePenalty.class).getValue(assignment) / assignment.nrAssignedVariables()) + "," + model.getCriterion(RoomSplitPenalty.class).getValue(assignment) + "," + df.format(splitDistance.nrRoomSplits(assignment) <= 0 ? 0.0 : splitDistance.getValue(assignment) / splitDistance.nrRoomSplits(assignment)) + (largeSize >= 0 ? "," + model.getCriterion(LargeExamsPenalty.class).getValue(assignment) : "") + (mpp ? "," + df.format(model.getCriterion(PerturbationPenalty.class).getValue(assignment) / assignment.nrAssignedVariables()) + "," + df.format(model.getCriterion(RoomPerturbationPenalty.class).getValue(assignment) / assignment.nrAssignedVariables()) : "") + (distStrPref == null ? "" : "," + df.format(distStrPref.getValue(assignment) / assignment.nrAssignedVariables())) + (splitter == null ? "" : "," + df.format(splitter.getValue(assignment))) + (violPer == null ? "" : "," + df.format(violPer.getValue(assignment))) + (violRoom == null ? "" : "," + df.format(violRoom.getValue(assignment))) + (violDist == null ? "" : "," + df.format(violDist.getValue(assignment))) + "," + instance + "," + config);
        pw.flush();
        pw.close();
    } catch (Exception e) {
        sLog.error("Unable to add CSV line to " + file, e);
    }
}
Also used : RoomPerturbationPenalty(org.cpsolver.exam.criteria.RoomPerturbationPenalty) PerturbationPenalty(org.cpsolver.exam.criteria.PerturbationPenalty) InstructorDistanceBackToBackConflicts(org.cpsolver.exam.criteria.InstructorDistanceBackToBackConflicts) ExamModel(org.cpsolver.exam.model.ExamModel) FileWriter(java.io.FileWriter) DecimalFormat(java.text.DecimalFormat) DistanceToStronglyPreferredRoom(org.cpsolver.exam.criteria.additional.DistanceToStronglyPreferredRoom) InstructorBackToBackConflicts(org.cpsolver.exam.criteria.InstructorBackToBackConflicts) DistributionViolation(org.cpsolver.exam.criteria.additional.DistributionViolation) RoomViolation(org.cpsolver.exam.criteria.additional.RoomViolation) ExamStudentConflictsPerExam(org.cpsolver.exam.reports.ExamStudentConflictsPerExam) Exam(org.cpsolver.exam.model.Exam) PrintWriter(java.io.PrintWriter) LargeExamsPenalty(org.cpsolver.exam.criteria.LargeExamsPenalty) ExamInstructor(org.cpsolver.exam.model.ExamInstructor) RoomSplitDistancePenalty(org.cpsolver.exam.criteria.RoomSplitDistancePenalty) PeriodViolation(org.cpsolver.exam.criteria.additional.PeriodViolation) InstructorDirectConflicts(org.cpsolver.exam.criteria.InstructorDirectConflicts) ExamStudent(org.cpsolver.exam.model.ExamStudent) IOException(java.io.IOException) ExamRotationPenalty(org.cpsolver.exam.criteria.ExamRotationPenalty) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) InstructorNotAvailableConflicts(org.cpsolver.exam.criteria.InstructorNotAvailableConflicts) InstructorMoreThan2ADayConflicts(org.cpsolver.exam.criteria.InstructorMoreThan2ADayConflicts) ExamSplitter(org.cpsolver.exam.split.ExamSplitter) RoomPerturbationPenalty(org.cpsolver.exam.criteria.RoomPerturbationPenalty)

Example 10 with ExamModel

use of org.cpsolver.exam.model.ExamModel in project cpsolver by UniTime.

the class Test method main.

/**
     * Main program
     * 
     * @param args
     *            problem property file, input file (optional, may be set by
     *            General.Input property), output file (optional, may be set by
     *            General.OutputFile property)
     */
public static void main(String[] args) {
    try {
        DataProperties cfg = new DataProperties();
        cfg.setProperty("Termination.StopWhenComplete", "false");
        cfg.setProperty("Termination.TimeOut", "1800");
        cfg.setProperty("General.SaveBestUnassigned", "-1");
        cfg.setProperty("Neighbour.Class", "org.cpsolver.exam.heuristics.ExamNeighbourSelection");
        if (args.length >= 1) {
            cfg.load(new FileInputStream(args[0]));
            cfg.setProperty("General.Config", new File(args[0]).getName());
        }
        cfg.putAll(System.getProperties());
        File inputFile = new File("c:\\test\\exam\\exam1070.xml");
        if (args.length >= 2) {
            inputFile = new File(args[1]);
        }
        ToolBox.setSeed(cfg.getPropertyLong("General.Seed", Math.round(Long.MAX_VALUE * Math.random())));
        cfg.setProperty("General.Input", inputFile.toString());
        String outName = inputFile.getName();
        if (outName.indexOf('.') >= 0)
            outName = outName.substring(0, outName.lastIndexOf('.')) + "s.xml";
        File outFile = new File(inputFile.getParentFile(), outName);
        if (args.length >= 3) {
            outFile = new File(args[2]);
            if (outFile.exists() && outFile.isDirectory())
                outFile = new File(outFile, outName);
            if (!outFile.exists() && !outFile.getName().endsWith(".xml"))
                outFile = new File(outFile, outName);
        }
        if (outFile.getParentFile() != null)
            outFile.getParentFile().mkdirs();
        cfg.setProperty("General.OutputFile", outFile.toString());
        cfg.setProperty("General.Output", outFile.getParent());
        String logName = outFile.getName();
        if (logName.indexOf('.') >= 0)
            logName = logName.substring(0, logName.lastIndexOf('.')) + ".log";
        setupLogging(new File(outFile.getParent(), logName), "true".equals(System.getProperty("debug", "false")));
        ExamModel model = new ExamModel(cfg);
        Document document = (new SAXReader()).read(new File(cfg.getProperty("General.Input")));
        int nrSolvers = cfg.getPropertyInt("Parallel.NrSolvers", 1);
        Assignment<Exam, ExamPlacement> assignment = (nrSolvers <= 1 ? new DefaultSingleAssignment<Exam, ExamPlacement>() : new DefaultParallelAssignment<Exam, ExamPlacement>());
        model.load(document, assignment);
        Solver<Exam, ExamPlacement> solver = (nrSolvers == 1 ? new Solver<Exam, ExamPlacement>(cfg) : new ParallelSolver<Exam, ExamPlacement>(cfg));
        solver.setInitalSolution(new Solution<Exam, ExamPlacement>(model, assignment));
        solver.currentSolution().addSolutionListener(new SolutionListener<Exam, ExamPlacement>() {

            @Override
            public void solutionUpdated(Solution<Exam, ExamPlacement> solution) {
            }

            @Override
            public void getInfo(Solution<Exam, ExamPlacement> solution, Map<String, String> info) {
            }

            @Override
            public void getInfo(Solution<Exam, ExamPlacement> solution, Map<String, String> info, Collection<Exam> variables) {
            }

            @Override
            public void bestCleared(Solution<Exam, ExamPlacement> solution) {
            }

            @Override
            public void bestSaved(Solution<Exam, ExamPlacement> solution) {
                ExamModel m = (ExamModel) solution.getModel();
                Assignment<Exam, ExamPlacement> a = solution.getAssignment();
                if (sLog.isInfoEnabled()) {
                    sLog.info("**BEST[" + solution.getIteration() + "]** " + (m.variables().size() > a.nrAssignedVariables() ? "V:" + a.nrAssignedVariables() + "/" + m.variables().size() + " - " : "") + "T:" + new DecimalFormat("0.00").format(m.getTotalValue(a)) + " " + m.toString(a) + (solution.getFailedIterations() > 0 ? ", F:" + sDoubleFormat.format(100.0 * solution.getFailedIterations() / solution.getIteration()) + "%" : ""));
                }
            }

            @Override
            public void bestRestored(Solution<Exam, ExamPlacement> solution) {
            }
        });
        Runtime.getRuntime().addShutdownHook(new ShutdownHook(solver));
        solver.start();
        try {
            solver.getSolverThread().join();
        } catch (InterruptedException e) {
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : Solver(org.cpsolver.ifs.solver.Solver) ParallelSolver(org.cpsolver.ifs.solver.ParallelSolver) DefaultParallelAssignment(org.cpsolver.ifs.assignment.DefaultParallelAssignment) ExamModel(org.cpsolver.exam.model.ExamModel) SAXReader(org.dom4j.io.SAXReader) DecimalFormat(java.text.DecimalFormat) DataProperties(org.cpsolver.ifs.util.DataProperties) Document(org.dom4j.Document) DefaultParallelAssignment(org.cpsolver.ifs.assignment.DefaultParallelAssignment) DefaultSingleAssignment(org.cpsolver.ifs.assignment.DefaultSingleAssignment) Assignment(org.cpsolver.ifs.assignment.Assignment) ExamStudentConflictsPerExam(org.cpsolver.exam.reports.ExamStudentConflictsPerExam) Exam(org.cpsolver.exam.model.Exam) ParallelSolver(org.cpsolver.ifs.solver.ParallelSolver) FileInputStream(java.io.FileInputStream) IOException(java.io.IOException) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) DefaultSingleAssignment(org.cpsolver.ifs.assignment.DefaultSingleAssignment) File(java.io.File)

Aggregations

ExamModel (org.cpsolver.exam.model.ExamModel)21 Exam (org.cpsolver.exam.model.Exam)20 ExamPlacement (org.cpsolver.exam.model.ExamPlacement)13 Set (java.util.Set)9 ExamRoomPlacement (org.cpsolver.exam.model.ExamRoomPlacement)9 ExamPeriodPlacement (org.cpsolver.exam.model.ExamPeriodPlacement)8 ExamInstructor (org.cpsolver.exam.model.ExamInstructor)6 ExamPeriod (org.cpsolver.exam.model.ExamPeriod)6 ExamStudent (org.cpsolver.exam.model.ExamStudent)6 ArrayList (java.util.ArrayList)4 IOException (java.io.IOException)3 HashSet (java.util.HashSet)3 File (java.io.File)2 DecimalFormat (java.text.DecimalFormat)2 HashMap (java.util.HashMap)2 ExamRoomSharing (org.cpsolver.exam.model.ExamRoomSharing)2 ExamStudentConflictsPerExam (org.cpsolver.exam.reports.ExamStudentConflictsPerExam)2 Assignment (org.cpsolver.ifs.assignment.Assignment)2 FileInputStream (java.io.FileInputStream)1 FileWriter (java.io.FileWriter)1