Search in sources :

Example 56 with Enrollment

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

the class SectionLimit method computeConflicts.

/**
     * A given enrollment is conflicting, if there is a section which limit
     * (computed by {@link SectionLimit#getEnrollmentWeight(Assignment, Section, Request)})
     * exceeds the section limit. <br>
     * For each of such sections, one or more existing enrollments are
     * (randomly) selected as conflicting until the overall weight is under the
     * limit.
     * 
     * @param enrollment
     *            {@link Enrollment} that is being considered
     * @param conflicts
     *            all computed conflicting requests are added into this set
     */
@Override
public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollment enrollment, Set<Enrollment> conflicts) {
    // check reservation can assign over the limit
    if (enrollment.getReservation() != null && enrollment.getReservation().canBatchAssignOverLimit())
        return;
    // exclude free time requests
    if (!enrollment.isCourseRequest())
        return;
    // for each section
    for (Section section : enrollment.getSections()) {
        // no reservation -- check the space in the unreserved space in the section
        if (enrollment.getConfig().getOffering().hasReservations() && !hasSectionReservation(enrollment, section)) {
            // section is fully reserved by section reservations
            if (section.getTotalUnreservedSpace() < enrollment.getRequest().getWeight()) {
                conflicts.add(enrollment);
                return;
            }
            double unreserved = getUnreservedSpace(assignment, section, enrollment.getRequest());
            if (unreserved < 0.0) {
                // no unreserved space available -> cannot be assigned
                // try to unassign some other enrollments that also do not have reservation
                List<Enrollment> adepts = new ArrayList<Enrollment>(section.getEnrollments(assignment).size());
                for (Enrollment e : section.getEnrollments(assignment)) {
                    if (e.getRequest().equals(enrollment.getRequest()))
                        continue;
                    if (e.getReservation() != null && e.getReservation().canBatchAssignOverLimit())
                        continue;
                    if (hasSectionReservation(e, section))
                        continue;
                    if (conflicts.contains(e))
                        unreserved += e.getRequest().getWeight();
                    else
                        adepts.add(e);
                }
                while (unreserved < 0.0) {
                    if (adepts.isEmpty()) {
                        // no adepts -> enrollment cannot be assigned
                        conflicts.add(enrollment);
                        return;
                    }
                    // pick adept (prefer dummy students), decrease unreserved space,
                    // make conflict
                    List<Enrollment> best = new ArrayList<Enrollment>();
                    boolean bestDummy = false;
                    double bestValue = 0;
                    for (Enrollment adept : adepts) {
                        boolean dummy = adept.getStudent().isDummy();
                        double value = adept.toDouble(assignment, false);
                        if (iPreferDummyStudents && dummy != bestDummy) {
                            if (dummy) {
                                best.clear();
                                best.add(adept);
                                bestDummy = dummy;
                                bestValue = value;
                            }
                            continue;
                        }
                        if (best.isEmpty() || value > bestValue) {
                            if (best.isEmpty())
                                best.clear();
                            best.add(adept);
                            bestDummy = dummy;
                            bestValue = value;
                        } else if (bestValue == value) {
                            best.add(adept);
                        }
                    }
                    Enrollment conflict = ToolBox.random(best);
                    adepts.remove(conflict);
                    unreserved += conflict.getRequest().getWeight();
                    conflicts.add(conflict);
                }
            }
        }
        // unlimited section
        if (section.getLimit() < 0)
            continue;
        // new enrollment weight
        double enrlWeight = getEnrollmentWeight(assignment, section, enrollment.getRequest());
        // below limit -> ok
        if (enrlWeight <= section.getLimit())
            continue;
        // above limit -> compute adepts (current assignments that are not
        // yet conflicting) exclude all conflicts as well
        List<Enrollment> adepts = new ArrayList<Enrollment>(section.getEnrollments(assignment).size());
        for (Enrollment e : section.getEnrollments(assignment)) {
            if (e.getRequest().equals(enrollment.getRequest()))
                continue;
            if (conflicts.contains(e))
                enrlWeight -= e.getRequest().getWeight();
            else
                adepts.add(e);
        }
        // while above limit -> pick an adept and make it conflicting
        while (enrlWeight > section.getLimit()) {
            if (adepts.isEmpty()) {
                // no adepts -> enrollment cannot be assigned
                conflicts.add(enrollment);
                return;
            }
            // pick adept (prefer dummy students & students w/o reservation), decrease enrollment
            // weight, make conflict
            List<Enrollment> best = new ArrayList<Enrollment>();
            boolean bestDummy = false;
            double bestValue = 0;
            boolean bestRes = true;
            for (Enrollment adept : adepts) {
                boolean dummy = adept.getStudent().isDummy();
                double value = adept.toDouble(assignment, false);
                boolean res = hasSectionReservation(adept, section);
                if (iPreferDummyStudents && dummy != bestDummy) {
                    if (dummy) {
                        best.clear();
                        best.add(adept);
                        bestDummy = dummy;
                        bestValue = value;
                        bestRes = res;
                    }
                    continue;
                }
                if (bestRes != res) {
                    if (!res) {
                        best.clear();
                        best.add(adept);
                        bestDummy = dummy;
                        bestValue = value;
                        bestRes = res;
                    }
                    continue;
                }
                if (best.isEmpty() || value > bestValue) {
                    if (best.isEmpty())
                        best.clear();
                    best.add(adept);
                    bestDummy = dummy;
                    bestValue = value;
                    bestRes = res;
                } else if (bestValue == value) {
                    best.add(adept);
                }
            }
            Enrollment conflict = ToolBox.random(best);
            adepts.remove(conflict);
            enrlWeight -= conflict.getRequest().getWeight();
            conflicts.add(conflict);
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Enrollment(org.cpsolver.studentsct.model.Enrollment) Section(org.cpsolver.studentsct.model.Section)

Example 57 with Enrollment

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

the class EnrollmentSelection method isAllowed.

/** true, if it is allowed to assign given value 
     * @param assignment current assignment
     * @param value given value
     * @param conflicts conflicting assignments
     * @return true if it is allowed
     **/
public boolean isAllowed(Assignment<Request, Enrollment> assignment, Enrollment value, Set<Enrollment> conflicts) {
    if (value == null)
        return true;
    StudentSectioningModel model = (StudentSectioningModel) value.variable().getModel();
    if (model.getNrLastLikeRequests(false) == 0 || model.getNrRealRequests(false) == 0)
        return true;
    Request request = value.variable();
    if (request.getStudent().isDummy()) {
        if (conflicts == null)
            conflicts = value.variable().getModel().conflictValues(assignment, value);
        for (Enrollment conflict : conflicts) {
            if (!conflict.getRequest().getStudent().isDummy())
                return false;
        }
    } else {
        if (conflicts == null)
            conflicts = value.variable().getModel().conflictValues(assignment, value);
        if (conflicts.size() > (assignment.getValue(request) == null ? 1 : 0))
            return false;
    }
    return true;
}
Also used : Request(org.cpsolver.studentsct.model.Request) Enrollment(org.cpsolver.studentsct.model.Enrollment) StudentSectioningModel(org.cpsolver.studentsct.StudentSectioningModel)

Example 58 with Enrollment

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

the class OnlineSelection method updateSpace.

/** Update online sectioning info after the given student is sectioned 
     * @param assignment current assignment
     * @param student student in question
     **/
public void updateSpace(Assignment<Request, Enrollment> assignment, Student student) {
    for (Request request : student.getRequests()) {
        if (!(request instanceof CourseRequest))
            continue;
        CourseRequest courseRequest = (CourseRequest) request;
        Enrollment enrollment = assignment.getValue(courseRequest);
        if (enrollment == null)
            // not enrolled --> no update
            return;
        for (Section section : enrollment.getSections()) {
            section.setSpaceHeld(section.getSpaceHeld() - courseRequest.getWeight());
        // sLog.debug("  -- space held for "+section+" decreased by 1 (to "+section.getSpaceHeld()+")");
        }
        List<Enrollment> feasibleEnrollments = new ArrayList<Enrollment>();
        for (Enrollment enrl : courseRequest.values(assignment)) {
            boolean overlaps = false;
            for (Request otherRequest : courseRequest.getStudent().getRequests()) {
                if (otherRequest.equals(courseRequest) || !(otherRequest instanceof CourseRequest))
                    continue;
                Enrollment otherErollment = assignment.getValue(otherRequest);
                if (otherErollment == null)
                    continue;
                if (enrl.isOverlapping(otherErollment)) {
                    overlaps = true;
                    break;
                }
            }
            if (!overlaps)
                feasibleEnrollments.add(enrl);
        }
        double decrement = courseRequest.getWeight() / feasibleEnrollments.size();
        for (Enrollment feasibleEnrollment : feasibleEnrollments) {
            for (Section section : feasibleEnrollment.getSections()) {
                section.setSpaceExpected(section.getSpaceExpected() - decrement);
            // sLog.debug("  -- space expected for "+section+" decreased by "+decrement+" (to "+section.getSpaceExpected()+")");
            }
        }
    }
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request) ArrayList(java.util.ArrayList) Enrollment(org.cpsolver.studentsct.model.Enrollment) Section(org.cpsolver.studentsct.model.Section)

Example 59 with Enrollment

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

the class PriorityConstructionSelection method branchAndBound.

/**
     * Find best solution for the next student using {@link BranchBoundSelection}.
     * @param solution current selection
     * @return generated neighbour
     */
public Neighbour<Request, Enrollment> branchAndBound(Solution<Request, Enrollment> solution) {
    while (iStudentsEnumeration.hasNext()) {
        Student student = iStudentsEnumeration.next();
        Progress.getInstance(solution.getModel()).incProgress();
        /*
            if (student.nrRequests() < iCycle) {
                // not enough requests -> nothing to improve -> skip
                continue;
            }
            if (student.nrAssignedRequests() + 1 < iCycle) {
                // previous step cycle already did not improve the assignment -> skip
                continue;
            }
            */
        Neighbour<Request, Enrollment> neighbour = iBranchBoundSelection.getSelection(solution.getAssignment(), student).select();
        if (neighbour != null)
            return neighbour;
    }
    return null;
}
Also used : Request(org.cpsolver.studentsct.model.Request) Enrollment(org.cpsolver.studentsct.model.Enrollment) Student(org.cpsolver.studentsct.model.Student)

Aggregations

Enrollment (org.cpsolver.studentsct.model.Enrollment)59 Request (org.cpsolver.studentsct.model.Request)47 CourseRequest (org.cpsolver.studentsct.model.CourseRequest)36 ArrayList (java.util.ArrayList)19 Section (org.cpsolver.studentsct.model.Section)19 HashSet (java.util.HashSet)17 Student (org.cpsolver.studentsct.model.Student)16 FreeTimeRequest (org.cpsolver.studentsct.model.FreeTimeRequest)15 Course (org.cpsolver.studentsct.model.Course)14 HashMap (java.util.HashMap)11 DataProperties (org.cpsolver.ifs.util.DataProperties)9 Config (org.cpsolver.studentsct.model.Config)9 Set (java.util.Set)8 TreeSet (java.util.TreeSet)8 Subpart (org.cpsolver.studentsct.model.Subpart)8 Map (java.util.Map)7 DefaultSingleAssignment (org.cpsolver.ifs.assignment.DefaultSingleAssignment)7 DistanceConflict (org.cpsolver.studentsct.extension.DistanceConflict)7 Offering (org.cpsolver.studentsct.model.Offering)7 File (java.io.File)6