    001package org.cpsolver.studentsct.heuristics.selection;
    002
    003import java.util.ArrayList;
    004import java.util.Collections;
    005import java.util.LinkedList;
    006import java.util.List;
    007import java.util.Queue;
    008
    009import org.cpsolver.ifs.heuristics.VariableSelection;
    010import org.cpsolver.ifs.solution.Solution;
    011import org.cpsolver.ifs.solver.Solver;
    012import org.cpsolver.studentsct.filter.StudentFilter;
    013import org.cpsolver.studentsct.model.Enrollment;
    014import org.cpsolver.studentsct.model.FreeTimeRequest;
    015import org.cpsolver.studentsct.model.Request;
    016
    017public class UnassignedRequestSelection implements VariableSelection<Request, Enrollment>{
    018    protected int iNrRounds = 0;
    019    protected Queue<Request> iRequests = null;
    020    protected StudentFilter iFilter = null;
    021
    022    @Override
    023    public void init(Solver<Request, Enrollment> solver) {
    024        iRequests = new LinkedList<Request>();
    025        iNrRounds = solver.getProperties().getPropertyInt("UnassignedRequestSelection.NrRounds", 1);
    026    }
    027
    028    @Override
    029    public Request selectVariable(Solution<Request, Enrollment> solution) {
    030        return nextRequest(solution);
    031    }
    032
    033    protected synchronized Request nextRequest(Solution<Request, Enrollment> solution) {
    034        if (iRequests.isEmpty() && iNrRounds > 0) {
    035            iNrRounds --;
    036            List<Request> variables = new ArrayList<Request>();
    037            for (Request r: solution.getModel().unassignedVariables(solution.getAssignment())) {
    038                if (r instanceof FreeTimeRequest) continue;
    039                if (iFilter == null || iFilter.accept(r.getStudent()))
    040                    variables.add(r);
    041            }
    042            Collections.shuffle(variables);
    043            iRequests.addAll(variables);
    044        }
    045        return iRequests.poll();
    046    }
    047
    048    /**
    049     * Only consider students meeting the given filter.
    050     */
    051    public StudentFilter getFilter() { return iFilter; }
    052
    053    /**
    054     * Only consider students meeting the given filter.
    055     */
    056    public UnassignedRequestSelection withFilter(StudentFilter filter) { iFilter = filter; return this; }
    057}