001package org.cpsolver.instructor.constraints; 002 003import java.util.ArrayList; 004import java.util.List; 005import java.util.Set; 006 007import org.cpsolver.ifs.assignment.Assignment; 008import org.cpsolver.ifs.model.GlobalConstraint; 009import org.cpsolver.ifs.util.ToolBox; 010import org.cpsolver.instructor.model.Instructor.Context; 011import org.cpsolver.instructor.model.TeachingAssignment; 012import org.cpsolver.instructor.model.TeachingRequest; 013 014/** 015 * Instructor Constraint. This is the main constraint of the problem, ensuring that an instructor gets a consistent list of 016 * assignments. It checks for instructor availability, maximal load, time conflicts, and whether the given assignments are of the same 017 * course (if desired). 018 * 019 * @version IFS 1.3 (Instructor Sectioning)<br> 020 * Copyright (C) 2016 Tomas Muller<br> 021 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 022 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 023 * <br> 024 * This library is free software; you can redistribute it and/or modify 025 * it under the terms of the GNU Lesser General Public License as 026 * published by the Free Software Foundation; either version 3 of the 027 * License, or (at your option) any later version. <br> 028 * <br> 029 * This library is distributed in the hope that it will be useful, but 030 * WITHOUT ANY WARRANTY; without even the implied warranty of 031 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 032 * Lesser General Public License for more details. <br> 033 * <br> 034 * You should have received a copy of the GNU Lesser General Public 035 * License along with this library; if not see 036 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 037 */ 038public class InstructorConstraint extends GlobalConstraint<TeachingRequest, TeachingAssignment> { 039 040 /** 041 * Constructor 042 */ 043 public InstructorConstraint() {} 044 045 @Override 046 public void computeConflicts(Assignment<TeachingRequest, TeachingAssignment> assignment, TeachingAssignment value, Set<TeachingAssignment> conflicts) { 047 Context context = value.getInstructor().getContext(assignment); 048 049 // Check availability 050 if (context.getInstructor().getTimePreference(value.variable()).isProhibited()) { 051 conflicts.add(value); 052 return; 053 } 054 055 // Check for overlaps 056 for (TeachingAssignment ta : context.getAssignments()) { 057 if (ta.variable().equals(value.variable()) || conflicts.contains(ta)) 058 continue; 059 060 if (ta.variable().overlaps(value.variable())) 061 conflicts.add(ta); 062 } 063 064 // Same course and/or common 065 if (value.variable().getCourse().isExclusive()) { 066 boolean sameCommon = value.variable().getCourse().isSameCommon(); 067 for (TeachingAssignment ta : context.getAssignments()) { 068 if (ta.variable().equals(value.variable()) || conflicts.contains(ta)) 069 continue; 070 071 if (!ta.variable().sameCourse(value.variable()) || (sameCommon && !ta.variable().sameCommon(value.variable()))) 072 conflicts.add(ta); 073 } 074 } else if (value.variable().getCourse().isSameCommon()) { 075 for (TeachingAssignment ta : context.getAssignments()) { 076 if (ta.variable().equals(value.variable()) || conflicts.contains(ta)) 077 continue; 078 if (ta.variable().sameCourse(value.variable()) && !ta.variable().sameCommon(value.variable())) 079 conflicts.add(ta); 080 } 081 } 082 083 // Check load 084 float load = value.variable().getLoad(); 085 List<TeachingAssignment> adepts = new ArrayList<TeachingAssignment>(); 086 for (TeachingAssignment ta : context.getAssignments()) { 087 if (ta.variable().equals(value.variable()) || conflicts.contains(ta)) 088 continue; 089 090 adepts.add(ta); 091 load += ta.variable().getLoad(); 092 } 093 while (load > context.getInstructor().getMaxLoad()) { 094 if (adepts.isEmpty()) { 095 conflicts.add(value); 096 break; 097 } 098 TeachingAssignment conflict = ToolBox.random(adepts); 099 load -= conflict.variable().getLoad(); 100 adepts.remove(conflict); 101 conflicts.add(conflict); 102 } 103 } 104 105 @Override 106 public String getName() { 107 return "Instructor Constraint"; 108 } 109 110 @Override 111 public String toString() { 112 return getName(); 113 } 114}