001package net.sf.cpsolver.coursett.criteria.additional; 002 003import java.util.Collection; 004import java.util.Set; 005 006import net.sf.cpsolver.coursett.criteria.StudentConflict; 007import net.sf.cpsolver.coursett.model.Lecture; 008import net.sf.cpsolver.coursett.model.Placement; 009import net.sf.cpsolver.coursett.model.Student; 010import net.sf.cpsolver.ifs.util.DataProperties; 011 012/** 013 * Ignored committed student conflicts. This criterion counts committed student conflicts (both overlapping and distance) between classes 014 * which are connected by a {@link IgnoredStudentConflict} constraint. This criterion was created mostly for debugging 015 * as these student conflicts are to be ignored. 016 * <br> 017 * 018 * @version CourseTT 1.2 (University Course Timetabling)<br> 019 * Copyright (C) 2013 Tomáš Müller<br> 020 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 021 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 022 * <br> 023 * This library is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU Lesser General Public License as 025 * published by the Free Software Foundation; either version 3 of the 026 * License, or (at your option) any later version. <br> 027 * <br> 028 * This library is distributed in the hope that it will be useful, but 029 * WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 031 * Lesser General Public License for more details. <br> 032 * <br> 033 * You should have received a copy of the GNU Lesser General Public 034 * License along with this library; if not see 035 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 036 */ 037public class IgnoredCommittedStudentConflict extends StudentConflict { 038 039 @Override 040 public double getWeightDefault(DataProperties config) { 041 return config.getPropertyDouble("Comparator.IgnoredCommitedStudentConflictWeight", 0.0); 042 } 043 044 @Override 045 public String getPlacementSelectionWeightName() { 046 return "Placement.NrIgnoredCommitedStudConfsWeight"; 047 } 048 049 @Override 050 public boolean isApplicable(Lecture l1, Lecture l2) { 051 return ignore(l1, l2) && committed(l1, l2); // only committed student conflicts 052 } 053 054 055 @Override 056 public boolean inConflict(Placement p1, Placement p2) { 057 return ignore(p1, p2) && committed(p1, p2) && super.inConflict(p1, p2); 058 } 059 060 public int countCommittedConflicts(Student student, Placement placement) { 061 if (student.getCommitedPlacements() == null) return 0; 062 int conflicts = 0; 063 Lecture lecture = placement.variable(); 064 for (Placement commitedPlacement : student.getCommitedPlacements()) { 065 Lecture commitedLecture = commitedPlacement.variable(); 066 if (lecture.getSchedulingSubpartId() != null && lecture.getSchedulingSubpartId().equals(commitedLecture.getSchedulingSubpartId())) continue; 067 if (ignore(placement, commitedPlacement) && (overlaps(placement, commitedPlacement) || distance(getMetrics(), placement, commitedPlacement))) 068 conflicts ++; 069 } 070 if (conflicts == 0) return 0; 071 double w = student.getOfferingWeight((placement.variable()).getConfiguration()); 072 return (int) Math.round(student.avg(w, 1.0) * conflicts); 073 } 074 075 public double countCommittedConflicts(Placement placement) { 076 double ret = 0; 077 Lecture lecture = placement.variable(); 078 for (Student student : lecture.students()) { 079 ret += countCommittedConflicts(student, placement); 080 } 081 return ret; 082 } 083 084 @Override 085 public double[] getBounds(Collection<Lecture> variables) { 086 double[] bounds = super.getBounds(variables); 087 for (Lecture lecture: variables) { 088 Double max = null; 089 for (Placement placement: lecture.values()) { 090 if (max == null) { max = new Double(countCommittedConflicts(placement)); continue; } 091 max = Math.max(max, countCommittedConflicts(placement)); 092 } 093 if (max != null) bounds[0] += max; 094 } 095 return bounds; 096 } 097 098 @Override 099 public double getValue(Placement value, Set<Placement> conflicts) { 100 double ret = super.getValue(value, conflicts); 101 ret += countCommittedConflicts(value); 102 if (iIncludeConflicts && conflicts != null) 103 for (Placement conflict: conflicts) 104 ret -= countCommittedConflicts(conflict); 105 return ret; 106 } 107 108 @Override 109 public double getValue(Collection<Lecture> variables) { 110 double ret = super.getValue(variables); 111 for (Lecture lect: variables) 112 if (lect.getAssignment() != null) 113 ret += countCommittedConflicts(lect.getAssignment()); 114 return Math.round(ret); 115 } 116}