Search in sources :

Example 1 with RequestGroup

use of org.cpsolver.studentsct.model.RequestGroup in project cpsolver by UniTime.

the class StudentSectioningXMLSaver method saveCourseRequest.

/**
     * Save course request 
     * @param requestEl request element to be populated
     * @param request course request to be saved
     */
protected void saveCourseRequest(Element requestEl, CourseRequest request) {
    requestEl.addAttribute("id", getId("request", request.getId()));
    requestEl.addAttribute("priority", String.valueOf(request.getPriority()));
    if (request.isAlternative())
        requestEl.addAttribute("alternative", "true");
    if (request.getWeight() != 1.0)
        requestEl.addAttribute("weight", sStudentWeightFormat.format(request.getWeight()));
    requestEl.addAttribute("waitlist", request.isWaitlist() ? "true" : "false");
    if (request.getTimeStamp() != null)
        requestEl.addAttribute("timeStamp", request.getTimeStamp().toString());
    boolean first = true;
    for (Course course : request.getCourses()) {
        if (first)
            requestEl.addAttribute("course", getId("course", course.getId()));
        else
            requestEl.addElement("alternative").addAttribute("course", getId("course", course.getId()));
        first = false;
    }
    for (Choice choice : request.getWaitlistedChoices()) {
        Element choiceEl = requestEl.addElement("waitlisted");
        choiceEl.addAttribute("offering", getId("offering", choice.getOffering().getId()));
        choiceEl.setText(choice.getId());
    }
    for (Choice choice : request.getSelectedChoices()) {
        Element choiceEl = requestEl.addElement("selected");
        choiceEl.addAttribute("offering", getId("offering", choice.getOffering().getId()));
        choiceEl.setText(choice.getId());
    }
    if (iSaveInitial && request.getInitialAssignment() != null) {
        saveEnrollment(requestEl.addElement("initial"), request.getInitialAssignment());
    }
    if (iSaveCurrent && getAssignment().getValue(request) != null) {
        saveEnrollment(requestEl.addElement("current"), getAssignment().getValue(request));
    }
    if (iSaveBest && request.getBestAssignment() != null) {
        saveEnrollment(requestEl.addElement("best"), request.getBestAssignment());
    }
    for (RequestGroup g : request.getRequestGroups()) {
        Element groupEl = requestEl.addElement("group").addAttribute("id", getId("group", g.getId())).addAttribute("course", getId("course", g.getCourse().getId()));
        if (iShowNames)
            groupEl.addAttribute("name", g.getName());
    }
}
Also used : Choice(org.cpsolver.studentsct.model.Choice) RequestGroup(org.cpsolver.studentsct.model.RequestGroup) Element(org.dom4j.Element) Course(org.cpsolver.studentsct.model.Course)

Example 2 with RequestGroup

use of org.cpsolver.studentsct.model.RequestGroup in project cpsolver by UniTime.

the class StudentSectioningModel method getInfo.

/**
     * Model info
     */
@Override
public Map<String, String> getInfo(Assignment<Request, Enrollment> assignment) {
    Map<String, String> info = super.getInfo(assignment);
    StudentSectioningModelContext context = getContext(assignment);
    if (!getStudents().isEmpty())
        info.put("Students with complete schedule", sDoubleFormat.format(100.0 * context.nrComplete() / getStudents().size()) + "% (" + context.nrComplete() + "/" + getStudents().size() + ")");
    if (getDistanceConflict() != null && getDistanceConflict().getTotalNrConflicts(assignment) != 0)
        info.put("Student distance conflicts", String.valueOf(getDistanceConflict().getTotalNrConflicts(assignment)));
    if (getTimeOverlaps() != null && getTimeOverlaps().getTotalNrConflicts(assignment) != 0)
        info.put("Time overlapping conflicts", String.valueOf(getTimeOverlaps().getTotalNrConflicts(assignment)));
    int nrLastLikeStudents = getNrLastLikeStudents(false);
    if (nrLastLikeStudents != 0 && nrLastLikeStudents != getStudents().size()) {
        int nrRealStudents = getStudents().size() - nrLastLikeStudents;
        int nrLastLikeCompleteStudents = getNrCompleteLastLikeStudents(assignment, false);
        int nrRealCompleteStudents = context.nrComplete() - nrLastLikeCompleteStudents;
        if (nrLastLikeStudents > 0)
            info.put("Projected students with complete schedule", sDecimalFormat.format(100.0 * nrLastLikeCompleteStudents / nrLastLikeStudents) + "% (" + nrLastLikeCompleteStudents + "/" + nrLastLikeStudents + ")");
        if (nrRealStudents > 0)
            info.put("Real students with complete schedule", sDecimalFormat.format(100.0 * nrRealCompleteStudents / nrRealStudents) + "% (" + nrRealCompleteStudents + "/" + nrRealStudents + ")");
        int nrLastLikeRequests = getNrLastLikeRequests(false);
        int nrRealRequests = variables().size() - nrLastLikeRequests;
        int nrLastLikeAssignedRequests = context.getNrAssignedLastLikeRequests();
        int nrRealAssignedRequests = assignment.nrAssignedVariables() - nrLastLikeAssignedRequests;
        if (nrLastLikeRequests > 0)
            info.put("Projected assigned requests", sDecimalFormat.format(100.0 * nrLastLikeAssignedRequests / nrLastLikeRequests) + "% (" + nrLastLikeAssignedRequests + "/" + nrLastLikeRequests + ")");
        if (nrRealRequests > 0)
            info.put("Real assigned requests", sDecimalFormat.format(100.0 * nrRealAssignedRequests / nrRealRequests) + "% (" + nrRealAssignedRequests + "/" + nrRealRequests + ")");
        if (getDistanceConflict() != null && getDistanceConflict().getTotalNrConflicts(assignment) > 0)
            info.put("Student distance conflicts", String.valueOf(getDistanceConflict().getTotalNrConflicts(assignment)));
        if (getTimeOverlaps() != null && getTimeOverlaps().getTotalNrConflicts(assignment) > 0)
            info.put("Time overlapping conflicts", String.valueOf(getTimeOverlaps().getTotalNrConflicts(assignment)));
    }
    context.getInfo(assignment, info);
    double groupSpread = 0.0;
    double groupCount = 0;
    for (Offering offering : iOfferings) {
        for (Course course : offering.getCourses()) {
            for (RequestGroup group : course.getRequestGroups()) {
                groupSpread += group.getAverageSpread(assignment) * group.getEnrollmentWeight(assignment, null);
                groupCount += group.getEnrollmentWeight(assignment, null);
            }
        }
    }
    if (groupCount > 0)
        info.put("Same group", sDecimalFormat.format(100.0 * groupSpread / groupCount) + "%");
    return info;
}
Also used : RequestGroup(org.cpsolver.studentsct.model.RequestGroup) Course(org.cpsolver.studentsct.model.Course) Offering(org.cpsolver.studentsct.model.Offering) Constraint(org.cpsolver.ifs.model.Constraint)

Example 3 with RequestGroup

use of org.cpsolver.studentsct.model.RequestGroup in project cpsolver by UniTime.

the class StudentSectioningModel method toString.

@Override
public String toString(Assignment<Request, Enrollment> assignment) {
    double groupSpread = 0.0;
    double groupCount = 0;
    for (Offering offering : iOfferings) {
        for (Course course : offering.getCourses()) {
            for (RequestGroup group : course.getRequestGroups()) {
                groupSpread += group.getAverageSpread(assignment) * group.getEnrollmentWeight(assignment, null);
                groupCount += group.getEnrollmentWeight(assignment, null);
            }
        }
    }
    return (getNrRealStudents(false) > 0 ? "RRq:" + getNrAssignedRealRequests(assignment, false) + "/" + getNrRealRequests(false) + ", " : "") + (getNrLastLikeStudents(false) > 0 ? "DRq:" + getNrAssignedLastLikeRequests(assignment, false) + "/" + getNrLastLikeRequests(false) + ", " : "") + (getNrRealStudents(false) > 0 ? "RS:" + getNrCompleteRealStudents(assignment, false) + "/" + getNrRealStudents(false) + ", " : "") + (getNrLastLikeStudents(false) > 0 ? "DS:" + getNrCompleteLastLikeStudents(assignment, false) + "/" + getNrLastLikeStudents(false) + ", " : "") + "V:" + sDecimalFormat.format(-getTotalValue(assignment)) + (getDistanceConflict() == null ? "" : ", DC:" + getDistanceConflict().getTotalNrConflicts(assignment)) + (getTimeOverlaps() == null ? "" : ", TOC:" + getTimeOverlaps().getTotalNrConflicts(assignment)) + (iMPP ? ", IS:" + sDecimalFormat.format(100.0 * getContext(assignment).iAssignedSameSectionWeight / iTotalMPPCRWeight) + "%" : "") + (iMPP ? ", IT:" + sDecimalFormat.format(100.0 * getContext(assignment).iAssignedSameTimeWeight / iTotalMPPCRWeight) + "%" : "") + ", %:" + sDecimalFormat.format(-100.0 * getTotalValue(assignment) / (getStudents().size() - iNrDummyStudents + (iProjectedStudentWeight < 0.0 ? iNrDummyStudents * (iTotalDummyWeight / iNrDummyRequests) : iProjectedStudentWeight * iTotalDummyWeight))) + (groupCount > 0 ? ", SG:" + sDecimalFormat.format(100.0 * groupSpread / groupCount) + "%" : "");
}
Also used : RequestGroup(org.cpsolver.studentsct.model.RequestGroup) Course(org.cpsolver.studentsct.model.Course) Offering(org.cpsolver.studentsct.model.Offering)

Example 4 with RequestGroup

use of org.cpsolver.studentsct.model.RequestGroup in project cpsolver by UniTime.

the class RequestGroupTable method create.

@Override
public CSVFile create(Assignment<Request, Enrollment> assignment, DataProperties properties) {
    boolean useAmPm = properties.getPropertyBoolean("useAmPm", true);
    CSVFile csv = new CSVFile();
    csv.setHeader(new CSVFile.CSVField[] { new CSVFile.CSVField("Group"), new CSVFile.CSVField("Course"), new CSVFile.CSVField("Total\nSpread"), new CSVFile.CSVField("Group\nEnrollment"), new CSVFile.CSVField("Class"), new CSVFile.CSVField("Meeting Time"), new CSVFile.CSVField("Class\nSpread"), new CSVFile.CSVField("Class\nEnrollment"), new CSVFile.CSVField("Class\nLimit") });
    TreeSet<RequestGroup> groups = new TreeSet<RequestGroup>(new Comparator<RequestGroup>() {

        @Override
        public int compare(RequestGroup g1, RequestGroup g2) {
            int cmp = g1.getName().compareTo(g2.getName());
            if (cmp != 0)
                return cmp;
            cmp = g1.getCourse().getName().compareTo(g2.getCourse().getName());
            if (cmp != 0)
                return cmp;
            if (g1.getId() < g2.getId())
                return -1;
            if (g1.getId() > g2.getId())
                return 1;
            return (g1.getCourse().getId() < g2.getCourse().getId() ? -1 : g1.getCourse().getId() > g2.getCourse().getId() ? 1 : 0);
        }
    });
    for (Offering offering : iModel.getOfferings()) for (Course course : offering.getCourses()) groups.addAll(course.getRequestGroups());
    for (RequestGroup group : groups) {
        double groupEnrollment = group.getEnrollmentWeight(assignment, null);
        double groupSpread = group.getAverageSpread(assignment);
        for (Config config : group.getCourse().getOffering().getConfigs()) for (Subpart subpart : config.getSubparts()) for (Section section : subpart.getSections()) {
            double s = group.getSectionWeight(assignment, section, null);
            if (s > 0.00001) {
                csv.addLine(new CSVFile.CSVField[] { new CSVFile.CSVField(group.getName()), new CSVFile.CSVField(group.getCourse().getName()), new CSVFile.CSVField(sDF.format(100.0 * groupSpread)), new CSVFile.CSVField(Math.round(groupEnrollment)), new CSVFile.CSVField(section.getSubpart().getName() + " " + section.getName(group.getCourse().getId())), new CSVFile.CSVField(section.getTime() == null ? "" : section.getTime().getDayHeader() + " " + section.getTime().getStartTimeHeader(useAmPm) + " - " + section.getTime().getEndTimeHeader(useAmPm)), new CSVFile.CSVField(sDF.format(100.0 * group.getSectionSpread(assignment, section))), new CSVFile.CSVField(Math.round(group.getSectionWeight(assignment, section, null))), new CSVFile.CSVField(section.getLimit()) });
            }
        }
    }
    return csv;
}
Also used : CSVFile(org.cpsolver.ifs.util.CSVFile) Config(org.cpsolver.studentsct.model.Config) Offering(org.cpsolver.studentsct.model.Offering) Section(org.cpsolver.studentsct.model.Section) TreeSet(java.util.TreeSet) RequestGroup(org.cpsolver.studentsct.model.RequestGroup) Subpart(org.cpsolver.studentsct.model.Subpart) Course(org.cpsolver.studentsct.model.Course)

Example 5 with RequestGroup

use of org.cpsolver.studentsct.model.RequestGroup in project cpsolver by UniTime.

the class ShuffleStudentsSelection method init.

@Override
public void init(Solver<Request, Enrollment> solver) {
    StudentSectioningModel model = (StudentSectioningModel) solver.currentSolution().getModel();
    iQueue = new LinkedList<Shuffle>();
    Assignment<Request, Enrollment> assignment = solver.currentSolution().getAssignment();
    // Check all request groups that have a spread < 1.0 
    RouletteWheelSelection<RequestGroup> groups = new RouletteWheelSelection<RequestGroup>();
    for (Offering offering : model.getOfferings()) {
        for (Course course : offering.getCourses()) {
            for (RequestGroup group : course.getRequestGroups()) {
                double spread = group.getAverageSpread(solver.currentSolution().getAssignment());
                if (spread >= 1.0)
                    continue;
                groups.add(group, 1.0 - spread);
            }
        }
    }
    // If there are some, pick one randomly (using roulette wheel selection)
    if (groups.hasMoreElements()) {
        RequestGroup group = groups.nextElement();
        RouletteWheelSelection<Subpart> subparts = new RouletteWheelSelection<Subpart>();
        for (CourseRequest cr : group.getRequests()) {
            Enrollment e = assignment.getValue(cr);
            if (e != null)
                for (Section section : e.getSections()) if (group.getSectionSpread(assignment, section) < 1.0)
                    subparts.addExisting(section.getSubpart(), 1.0);
        }
        if (subparts.hasMoreElements()) {
            // Pick a subpart that has sections with a section spread < 1.0
            Subpart subpart = subparts.nextElement();
            RouletteWheelSelection<Section> sections = new RouletteWheelSelection<Section>();
            section: for (Section section : subpart.getSections()) {
                // Only take sections that all requests can use
                for (CourseRequest cr : group.getRequests()) {
                    boolean match = false;
                    for (Enrollment e : cr.values(assignment)) if (e.getSections().contains(section)) {
                        match = true;
                        break;
                    }
                    if (!match)
                        continue section;
                }
                // Take sections with conflicts with lower probability
                int nrConflicts = 0;
                if (!section.isAllowOverlap())
                    requests: for (CourseRequest cr : group.getRequests()) {
                        for (Request r : cr.getStudent().getRequests()) {
                            if (r.equals(cr))
                                continue;
                            Enrollment e = assignment.getValue(r);
                            if (e != null && !e.isAllowOverlap() && section.isOverlapping(e.getSections())) {
                                nrConflicts++;
                                continue requests;
                            }
                        }
                    }
                sections.add(section, 1 + group.getRequests().size() - nrConflicts);
            }
            Set<Section> filter = new HashSet<Section>();
            double space = 0.0;
            // Pick enough sections
            while (sections.hasMoreElements()) {
                Section section = sections.nextElement();
                if (filter.add(section)) {
                    if (section.getLimit() < 0)
                        break;
                    space += section.getLimit();
                }
                if (space >= group.getTotalWeight())
                    break;
            }
            // Add all requests that should be moved into the queue
            for (CourseRequest cr : group.getRequests()) {
                Shuffle shuffle = new Shuffle(group, cr, filter);
                Enrollment e = assignment.getValue(cr);
                if (e != null && shuffle.matchFilter(e))
                    continue;
                iQueue.add(shuffle);
            }
        } else {
            // No subpart -> no section filter
            for (CourseRequest cr : group.getRequests()) iQueue.add(new Shuffle(group, cr, null));
        }
    }
    // Shuffle the queue
    Collections.shuffle((LinkedList<Shuffle>) iQueue);
    // Initialize the backtrack selection, if needed
    if (iBacktrack == null) {
        try {
            iBacktrack = new ShuffleBacktrackNeighbourSelection(solver.getProperties());
            iBacktrack.init(solver);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    // Change progress
    Progress.getInstance(solver.currentSolution().getModel()).setPhase("Shuffling students along request groups...", iQueue.size());
}
Also used : RouletteWheelSelection(org.cpsolver.ifs.heuristics.RouletteWheelSelection) Request(org.cpsolver.studentsct.model.Request) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Offering(org.cpsolver.studentsct.model.Offering) Section(org.cpsolver.studentsct.model.Section) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) RequestGroup(org.cpsolver.studentsct.model.RequestGroup) Subpart(org.cpsolver.studentsct.model.Subpart) Enrollment(org.cpsolver.studentsct.model.Enrollment) Course(org.cpsolver.studentsct.model.Course) StudentSectioningModel(org.cpsolver.studentsct.StudentSectioningModel) HashSet(java.util.HashSet)

Aggregations

RequestGroup (org.cpsolver.studentsct.model.RequestGroup)7 Course (org.cpsolver.studentsct.model.Course)6 Offering (org.cpsolver.studentsct.model.Offering)4 CourseRequest (org.cpsolver.studentsct.model.CourseRequest)3 Section (org.cpsolver.studentsct.model.Section)3 Subpart (org.cpsolver.studentsct.model.Subpart)3 Choice (org.cpsolver.studentsct.model.Choice)2 Element (org.dom4j.Element)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 TreeSet (java.util.TreeSet)1 RouletteWheelSelection (org.cpsolver.ifs.heuristics.RouletteWheelSelection)1 Constraint (org.cpsolver.ifs.model.Constraint)1 CSVFile (org.cpsolver.ifs.util.CSVFile)1 StudentSectioningModel (org.cpsolver.studentsct.StudentSectioningModel)1 Config (org.cpsolver.studentsct.model.Config)1 Enrollment (org.cpsolver.studentsct.model.Enrollment)1 Request (org.cpsolver.studentsct.model.Request)1