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}