Search in sources :

Example 1 with RouletteWheelSelection

use of org.cpsolver.ifs.heuristics.RouletteWheelSelection 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)

Example 2 with RouletteWheelSelection

use of org.cpsolver.ifs.heuristics.RouletteWheelSelection in project cpsolver by UniTime.

the class MaxOverExpectedConstraint method computeConflicts.

@Override
public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollment value, Set<Enrollment> conflicts) {
    if (!value.isCourseRequest())
        return;
    CourseRequest cr = (CourseRequest) value.variable();
    OnlineSectioningModel model = (OnlineSectioningModel) getModel();
    double basePenalty = model.getOverExpected(assignment, value, value, conflicts);
    if (basePenalty > iMaxOverExpected) {
        conflicts.add(value);
        return;
    }
    RouletteWheelSelection<Enrollment> selection = new RouletteWheelSelection<Enrollment>();
    for (Request r : cr.getStudent().getRequests()) {
        Enrollment e = assignment.getValue(r);
        if (e != null && !r.equals(value.variable()) && !conflicts.contains(e) && e.isCourseRequest()) {
            double penalty = model.getOverExpected(assignment, e, value, conflicts);
            if (penalty > 0.0)
                selection.add(e, penalty);
        }
    }
    while (selection.getRemainingPoints() + basePenalty > iMaxOverExpected && selection.hasMoreElements()) {
        conflicts.add(selection.nextElement());
    }
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) RouletteWheelSelection(org.cpsolver.ifs.heuristics.RouletteWheelSelection) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request) Enrollment(org.cpsolver.studentsct.model.Enrollment)

Aggregations

RouletteWheelSelection (org.cpsolver.ifs.heuristics.RouletteWheelSelection)2 CourseRequest (org.cpsolver.studentsct.model.CourseRequest)2 Enrollment (org.cpsolver.studentsct.model.Enrollment)2 Request (org.cpsolver.studentsct.model.Request)2 HashSet (java.util.HashSet)1 StudentSectioningModel (org.cpsolver.studentsct.StudentSectioningModel)1 Course (org.cpsolver.studentsct.model.Course)1 Offering (org.cpsolver.studentsct.model.Offering)1 RequestGroup (org.cpsolver.studentsct.model.RequestGroup)1 Section (org.cpsolver.studentsct.model.Section)1 Subpart (org.cpsolver.studentsct.model.Subpart)1