001    package net.sf.cpsolver.studentsct.heuristics;
002    
003    import java.text.DecimalFormat;
004    
005    import net.sf.cpsolver.ifs.heuristics.RoundRobinNeighbourSelection;
006    import net.sf.cpsolver.ifs.solution.Solution;
007    import net.sf.cpsolver.ifs.solver.Solver;
008    import net.sf.cpsolver.ifs.util.DataProperties;
009    import net.sf.cpsolver.studentsct.StudentSectioningModel;
010    import net.sf.cpsolver.studentsct.heuristics.selection.BacktrackSelection;
011    import net.sf.cpsolver.studentsct.heuristics.selection.BranchBoundSelection;
012    import net.sf.cpsolver.studentsct.heuristics.selection.RandomUnassignmentSelection;
013    import net.sf.cpsolver.studentsct.heuristics.selection.ResectionIncompleteStudentsSelection;
014    import net.sf.cpsolver.studentsct.heuristics.selection.ResectionUnassignedStudentsSelection;
015    import net.sf.cpsolver.studentsct.heuristics.selection.RndUnProblStudSelection;
016    import net.sf.cpsolver.studentsct.heuristics.selection.StandardSelection;
017    import net.sf.cpsolver.studentsct.heuristics.selection.SwapStudentSelection;
018    
019    /**
020     * (Batch) student sectioning neighbour selection.
021     * It is based on {@link RoundRobinNeighbourSelection}, the following steps are involved:
022     * <ul>
023     * <li>Phase 1: section all students using incremental branch & bound (no unassignments) ({@link BranchBoundSelection} is used)
024     * <li>Phase 2: pick a student (one by one) with an incomplete schedule, try to find an improvement ({@link SwapStudentSelection} is used)
025     * <li>Phase 3: use standard value selection for some time ({@link StandardSelection} is used)
026     * <li>Phase 4: use backtrack neighbour selection ({@link BacktrackSelection} is used)
027     * <li>Phase 5: pick a student (one by one) with an incomplete schedule, try to find an improvement, identify problematic students
028     * ({@link SwapStudentSelection} is used)
029     * <li>Phase 6: random unassignment of some problematic students ({@link RndUnProblStudSelection} is used)
030     * <li>Phase 7: resection incomplete students ({@link ResectionIncompleteStudentsSelection} is used)
031     * <li>Phase 8: resection of students that were unassigned in step 6 ({@link ResectionUnassignedStudentsSelection} is used)
032     * <li>Phase 9: pick a student (one by one) with an incomplete schedule, try to find an improvement ({@link SwapStudentSelection} is used)
033     * <li>Phase 10: use standard value selection for some time ({@link StandardSelection} with {@link RouletteWheelRequestSelection} is used)
034     * <li>Phase 11: pick a student (one by one) with an incomplete schedule, try to find an improvement ({@link SwapStudentSelection} is used)
035     * <li>Phase 12: use backtrack neighbour selection ({@link BacktrackSelection} is used)
036     * <li>Phase 13: random unassignment of some students ({@link RandomUnassignmentSelection} is used)
037     * </ul>
038     * 
039     * <br><br>
040     * 
041     * @version
042     * StudentSct 1.1 (Student Sectioning)<br>
043     * Copyright (C) 2007 Tomáš Müller<br>
044     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
045     * Lazenska 391, 76314 Zlin, Czech Republic<br>
046     * <br>
047     * This library is free software; you can redistribute it and/or
048     * modify it under the terms of the GNU Lesser General Public
049     * License as published by the Free Software Foundation; either
050     * version 2.1 of the License, or (at your option) any later version.
051     * <br><br>
052     * This library is distributed in the hope that it will be useful,
053     * but WITHOUT ANY WARRANTY; without even the implied warranty of
054     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
055     * Lesser General Public License for more details.
056     * <br><br>
057     * You should have received a copy of the GNU Lesser General Public
058     * License along with this library; if not, write to the Free Software
059     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
060     */
061    
062    public class StudentSctNeighbourSelection extends RoundRobinNeighbourSelection {
063        private static org.apache.log4j.Logger sLog = org.apache.log4j.Logger.getLogger(StudentSctNeighbourSelection.class);
064        private static DecimalFormat sDF = new DecimalFormat("0.000");
065        
066        public StudentSctNeighbourSelection(DataProperties properties) throws Exception {
067            super(properties);
068        }
069        
070        public void init(Solver solver) {
071            super.init(solver);
072            setup(solver);
073        }
074    
075        public void setup(Solver solver) {
076            //Phase 1: section all students using incremental branch & bound (no unassignments)
077            registerSelection(new BranchBoundSelection(solver.getProperties()));
078    
079            //Phase 2: pick a student (one by one) with an incomplete schedule, try to find an improvement
080            registerSelection(new SwapStudentSelection(solver.getProperties()));
081    
082            //Phase 3: use standard value selection for some time
083            registerSelection(new StandardSelection(solver.getProperties(), getVariableSelection(), getValueSelection())); 
084    
085            //Phase 4: use backtrack neighbour selection
086            registerSelection(new BacktrackSelection(solver.getProperties()));
087            
088            //Phase 5: pick a student (one by one) with an incomplete schedule, try to find an improvement, identify problematic students
089            SwapStudentSelection swapStudentSelection = new SwapStudentSelection(solver.getProperties());
090            registerSelection(swapStudentSelection);
091                
092            //Phase 6: random unassignment of some problematic students
093            registerSelection(new RndUnProblStudSelection(solver.getProperties(), swapStudentSelection));
094            
095            //Phase 7: resection incomplete students 
096            registerSelection(new ResectionIncompleteStudentsSelection(solver.getProperties()));
097            
098            //Phase 8: resection of students that were unassigned in step 6
099            registerSelection(new ResectionUnassignedStudentsSelection(solver.getProperties()));
100               
101            //Phase 9: pick a student (one by one) with an incomplete schedule, try to find an improvement
102            registerSelection(new SwapStudentSelection(solver.getProperties()));
103    
104            //Phase 10: use standard value selection for some time
105            registerSelection(new StandardSelection(solver.getProperties(), new RouletteWheelRequestSelection(solver.getProperties()), getValueSelection()));
106            
107            //Phase 11: pick a student (one by one) with an incomplete schedule, try to find an improvement
108            registerSelection(new SwapStudentSelection(solver.getProperties()));
109            
110            //Phase 12: use backtrack neighbour selection
111            registerSelection(new BacktrackSelection(solver.getProperties()));
112    
113            //Phase 13: random unassignment of some students
114            registerSelection(new RandomUnassignmentSelection(solver.getProperties()));
115        }
116        
117        public void changeSelection(Solution solution) {
118            super.changeSelection(solution);
119            StudentSectioningModel m = (StudentSectioningModel)solution.getModel();
120            sLog.debug("**CURR** "+
121                    (m.getNrRealStudents(false)>0?"RRq:"+m.getNrAssignedRealRequests(false)+"/"+m.getNrRealRequests(false)+", ":"")+
122                    (m.getNrLastLikeStudents(false)>0?"DRq:"+m.getNrAssignedLastLikeRequests(false)+"/"+m.getNrLastLikeRequests(false)+", ":"")+
123                    (m.getNrRealStudents(false)>0?"RS:"+m.getNrCompleteRealStudents(false)+"/"+m.getNrRealStudents(false)+", ":"")+
124                    (m.getNrLastLikeStudents(false)>0?"DS:"+m.getNrCompleteLastLikeStudents(false)+"/"+m.getNrLastLikeStudents(false)+", ":"")+
125                    "V:"+sDF.format(m.getTotalValue())+
126                    (m.getDistanceConflict()==null?"":", DC:"+sDF.format(m.getDistanceConflict().getTotalNrConflicts())));
127        }
128        
129    }