use of org.cpsolver.studentsct.model.Subpart in project cpsolver by UniTime.
the class PriorityStudentWeights method main.
/**
* Test case -- run to see the weights for a few courses
* @param args program arguments
*/
public static void main(String[] args) {
PriorityStudentWeights pw = new PriorityStudentWeights(new DataProperties());
DecimalFormat df = new DecimalFormat("0.000000");
Student s = new Student(0l);
new CourseRequest(1l, 0, false, s, ToolBox.toList(new Course(1, "A", "1", new Offering(0, "A")), new Course(1, "A", "2", new Offering(0, "A")), new Course(1, "A", "3", new Offering(0, "A"))), false, null);
new CourseRequest(2l, 1, false, s, ToolBox.toList(new Course(1, "B", "1", new Offering(0, "B")), new Course(1, "B", "2", new Offering(0, "B")), new Course(1, "B", "3", new Offering(0, "B"))), false, null);
new CourseRequest(3l, 2, false, s, ToolBox.toList(new Course(1, "C", "1", new Offering(0, "C")), new Course(1, "C", "2", new Offering(0, "C")), new Course(1, "C", "3", new Offering(0, "C"))), false, null);
new CourseRequest(4l, 3, false, s, ToolBox.toList(new Course(1, "D", "1", new Offering(0, "D")), new Course(1, "D", "2", new Offering(0, "D")), new Course(1, "D", "3", new Offering(0, "D"))), false, null);
new CourseRequest(5l, 4, false, s, ToolBox.toList(new Course(1, "E", "1", new Offering(0, "E")), new Course(1, "E", "2", new Offering(0, "E")), new Course(1, "E", "3", new Offering(0, "E"))), false, null);
new CourseRequest(6l, 5, true, s, ToolBox.toList(new Course(1, "F", "1", new Offering(0, "F")), new Course(1, "F", "2", new Offering(0, "F")), new Course(1, "F", "3", new Offering(0, "F"))), false, null);
new CourseRequest(7l, 6, true, s, ToolBox.toList(new Course(1, "G", "1", new Offering(0, "G")), new Course(1, "G", "2", new Offering(0, "G")), new Course(1, "G", "3", new Offering(0, "G"))), false, null);
Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
Placement p = new Placement(null, new TimeLocation(1, 90, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>());
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With one distance conflict:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>();
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, (Section) sections.iterator().next()));
w[i] = pw.getWeight(assignment, e, dc, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With two distance conflicts:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>();
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, (Section) sections.iterator().next()));
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)));
w[i] = pw.getWeight(assignment, e, dc, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With 25% time overlapping conflict:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<TimeOverlapsCounter.Conflict> toc = new HashSet<TimeOverlapsCounter.Conflict>();
toc.add(new TimeOverlapsCounter.Conflict(s, 3, e, sections.iterator().next(), e, sections.iterator().next()));
w[i] = pw.getWeight(assignment, e, null, toc);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("Disbalanced sections (by 2 / 10 students):");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
Subpart x = new Subpart(0, "Lec", "Lec", cfg, null);
Section a = new Section(0, 10, "x", x, p, null);
new Section(1, 10, "y", x, p, null);
sections.add(a);
a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("Same choice sections:");
pw.iMPP = true;
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("Same time sections:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, new Instructor(1l, null, "Josef Novak", null)));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("Different time sections:");
Placement q = new Placement(null, new TimeLocation(1, 102, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>());
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), q, null));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("Two sections, one same choice, one same time:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
sections.add(new Section(1, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(2, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
other.add(new Section(3, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null, new Instructor(1l, null, "Josef Novak", null)));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
}
use of org.cpsolver.studentsct.model.Subpart in project cpsolver by UniTime.
the class SuggestionSelection method setRequiredSections.
@Override
public void setRequiredSections(Hashtable<CourseRequest, Set<Section>> requiredSections) {
iRequiredConfig = new Hashtable<CourseRequest, Config>();
iRequiredSection = new Hashtable<CourseRequest, Hashtable<Subpart, Section>>();
if (requiredSections != null) {
for (Map.Entry<CourseRequest, Set<Section>> entry : requiredSections.entrySet()) {
Hashtable<Subpart, Section> subSection = new Hashtable<Subpart, Section>();
iRequiredSection.put(entry.getKey(), subSection);
for (Section section : entry.getValue()) {
if (subSection.isEmpty())
iRequiredConfig.put(entry.getKey(), section.getSubpart().getConfig());
subSection.put(section.getSubpart(), section);
}
}
}
}
use of org.cpsolver.studentsct.model.Subpart in project cpsolver by UniTime.
the class FractionallyUnbalancedWhenNoExpectations method getOverExpected.
@Override
public double getOverExpected(Assignment<Request, Enrollment> assignment, Section section, Request request) {
Subpart subpart = section.getSubpart();
if (hasExpectations(subpart) && section.getLimit() > 0)
return super.getOverExpected(assignment, section, request);
if (getDisbalance() == null || getDisbalance() < 0.0)
return 0.0;
double enrlConfig = request.getWeight() + getEnrollment(assignment, subpart.getConfig(), request);
int subparts = section.getSubpart().getConfig().getSubparts().size();
int limit = getLimit(section);
double enrl = request.getWeight() + getEnrollment(assignment, section, request);
if (limit > 0) {
// sections have limits -> desired size is section limit x (total
// enrollment / total limit)
double desired = (enrlConfig / getLimit(subpart)) * limit;
if (enrl - desired >= Math.max(1.0, getDisbalance() * limit)) {
double max = getMaximum(section, limit);
return Math.min(max, enrl - desired) / (max * subparts);
}
} else if (isBalanceUnlimited()) {
// unlimited sections -> desired size is total enrollment / number
// of sections
double desired = enrlConfig / subpart.getSections().size();
if (enrl - desired >= Math.max(1.0, getDisbalance() * desired)) {
double max = getMaximum(section, desired);
return Math.min(max, enrl - desired) / (max * subparts);
}
}
return 0.0;
}
use of org.cpsolver.studentsct.model.Subpart in project cpsolver by UniTime.
the class EqualWeightCriterion method compare.
@Override
public int compare(Assignment<Request, Enrollment> assignment, Enrollment[] current, Enrollment[] best) {
if (best == null)
return -1;
// 0. best number of assigned course requests (including alternativity &
// priority)
int currentAssignedCourseReq = 0, bestAssignedCourseReq = 0;
int currentAssignedRequests = 0, bestAssignedRequests = 0;
int currentAssignedPriority = 0, bestAssignedPriority = 0;
int currentAssignedAlternativity = 0, bestAssignedAlternativity = 0;
int currentNotFollowedReservations = 0, bestNotFollowedReservations = 0;
for (int idx = 0; idx < current.length; idx++) {
if (current[idx] != null && current[idx].getAssignments() != null) {
currentAssignedRequests++;
if (current[idx].isCourseRequest())
currentAssignedCourseReq++;
currentAssignedPriority += current[idx].getTruePriority() * current[idx].getTruePriority();
currentAssignedAlternativity += (current[idx].getRequest().isAlternative() ? 1 : 0);
if (current[idx].getTruePriority() < current[idx].getPriority())
currentNotFollowedReservations++;
}
if (best[idx] != null && best[idx].getAssignments() != null) {
bestAssignedRequests++;
if (best[idx].isCourseRequest())
bestAssignedCourseReq++;
bestAssignedPriority += best[idx].getTruePriority() * best[idx].getTruePriority();
bestAssignedAlternativity += (best[idx].getRequest().isAlternative() ? 1 : 0);
if (best[idx].getTruePriority() < best[idx].getPriority())
bestNotFollowedReservations++;
}
}
if (currentAssignedCourseReq > bestAssignedCourseReq)
return -1;
if (bestAssignedCourseReq > currentAssignedCourseReq)
return 1;
if (currentAssignedPriority < bestAssignedPriority)
return -1;
if (bestAssignedPriority < currentAssignedPriority)
return 1;
if (currentAssignedAlternativity < bestAssignedAlternativity)
return -1;
if (bestAssignedAlternativity < currentAssignedAlternativity)
return 1;
// 0.1. allowed, but not available sections
int bestNotAvailable = 0, currentNotAvailable = 0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null && best[idx].getRequest() instanceof CourseRequest && best[idx].getReservation() != null && best[idx].getReservation().canAssignOverLimit()) {
for (Section section : best[idx].getSections()) {
if (section.getLimit() == 0)
bestNotAvailable++;
}
}
if (current[idx] != null && current[idx].getAssignments() != null && current[idx].getRequest() instanceof CourseRequest && current[idx].getReservation() != null && current[idx].getReservation().canAssignOverLimit()) {
for (Section section : current[idx].getSections()) {
if (section.getLimit() == 0)
currentNotAvailable++;
}
}
}
if (bestNotAvailable > currentNotAvailable)
return -1;
if (bestNotAvailable < currentNotAvailable)
return 1;
// 0.5. avoid course overlaps & unavailabilities
if (getModel().getStudentQuality() != null) {
int bestTimeOverlaps = 0, currentTimeOverlaps = 0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null && best[idx].getRequest() instanceof CourseRequest) {
for (int x = 0; x < idx; x++) {
if (best[x] != null && best[x].getAssignments() != null && best[x].getRequest() instanceof CourseRequest)
bestTimeOverlaps += getModel().getStudentQuality().penalty(StudentQuality.Type.CourseTimeOverlap, best[x], best[idx]);
}
}
if (current[idx] != null && current[idx].getAssignments() != null && current[idx].getRequest() instanceof CourseRequest) {
for (int x = 0; x < idx; x++) {
if (current[x] != null && current[x].getAssignments() != null && current[x].getRequest() instanceof CourseRequest)
currentTimeOverlaps += getModel().getStudentQuality().penalty(StudentQuality.Type.CourseTimeOverlap, current[x], current[idx]);
}
}
}
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
bestTimeOverlaps += getModel().getStudentQuality().penalty(StudentQuality.Type.Unavailability, best[idx]);
}
if (current[idx] != null && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
currentTimeOverlaps += getModel().getStudentQuality().penalty(StudentQuality.Type.Unavailability, current[idx]);
}
}
if (currentTimeOverlaps < bestTimeOverlaps)
return -1;
if (bestTimeOverlaps < currentTimeOverlaps)
return 1;
} else if (getModel().getTimeOverlaps() != null) {
int bestTimeOverlaps = 0, currentTimeOverlaps = 0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null && best[idx].getRequest() instanceof CourseRequest) {
for (int x = 0; x < idx; x++) {
if (best[x] != null && best[x].getAssignments() != null && best[x].getRequest() instanceof CourseRequest)
bestTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(best[x], best[idx]);
}
}
if (current[idx] != null && current[idx].getAssignments() != null && current[idx].getRequest() instanceof CourseRequest) {
for (int x = 0; x < idx; x++) {
if (current[x] != null && current[x].getAssignments() != null && current[x].getRequest() instanceof CourseRequest)
currentTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(current[x], current[idx]);
}
}
}
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
bestTimeOverlaps += getModel().getTimeOverlaps().nrNotAvailableTimeConflicts(best[idx]);
}
if (current[idx] != null && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
currentTimeOverlaps += getModel().getTimeOverlaps().nrNotAvailableTimeConflicts(current[idx]);
}
}
if (currentTimeOverlaps < bestTimeOverlaps)
return -1;
if (bestTimeOverlaps < currentTimeOverlaps)
return 1;
}
// 1. minimize number of penalties
double bestPenalties = 0, currentPenalties = 0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
for (Section section : best[idx].getSections()) bestPenalties += getModel().getOverExpected(assignment, best, idx, section, best[idx].getRequest());
}
if (current[idx] != null && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
for (Section section : current[idx].getSections()) currentPenalties += getModel().getOverExpected(assignment, current, idx, section, current[idx].getRequest());
}
}
if (currentPenalties < bestPenalties)
return -1;
if (bestPenalties < currentPenalties)
return 1;
// 2. best number of assigned requests (including free time requests)
if (currentAssignedRequests > bestAssignedRequests)
return -1;
if (bestAssignedRequests > currentAssignedRequests)
return 1;
// 3. maximize selection
int bestSelected = 0, currentSelected = 0;
for (int idx = 0; idx < current.length; idx++) {
Set<Section> preferred = getPreferredSections(getRequest(idx));
if (preferred != null && !preferred.isEmpty()) {
if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
for (Section section : best[idx].getSections()) if (preferred.contains(section))
bestSelected++;
}
if (current[idx] != null && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
for (Section section : current[idx].getSections()) if (preferred.contains(section))
currentSelected++;
}
}
}
if (currentSelected > bestSelected)
return -1;
if (bestSelected > currentSelected)
return 1;
// 3.5 maximize preferences
double bestSelectedConfigs = 0, currentSelectedConfigs = 0;
double bestSelectedSections = 0, currentSelectedSections = 0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
bestSelectedSections += best[idx].percentSelectedSameSection();
bestSelectedConfigs += best[idx].percentSelectedSameConfig();
}
if (current[idx] != null && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
currentSelectedSections += current[idx].percentSelectedSameSection();
currentSelectedConfigs += current[idx].percentSelectedSameConfig();
}
}
if (0.3 * currentSelectedConfigs + 0.7 * currentSelectedSections > 0.3 * bestSelectedConfigs + 0.7 * bestSelectedSections)
return -1;
if (0.3 * bestSelectedConfigs + 0.7 * bestSelectedSections > 0.3 * currentSelectedConfigs + 0.7 * currentSelectedSections)
return 1;
// 3.9 minimize enrollments where the reservation is not followed
if (currentNotFollowedReservations < bestNotFollowedReservations)
return -1;
if (bestNotFollowedReservations < currentNotFollowedReservations)
return 1;
// 3.95 avoid past sections
int bestPast = 0, currentPast = 0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null) {
for (Section section : best[idx].getSections()) {
if (section.isPast())
bestPast++;
}
}
if (current[idx] != null && current[idx].getAssignments() != null) {
for (Section section : current[idx].getSections()) {
if (section.isPast())
currentPast++;
}
}
}
if (currentPast < bestPast)
return -1;
if (bestPast < currentPast)
return 1;
// 4-5. student quality
if (getModel().getStudentQuality() != null) {
double bestQuality = 0, currentQuality = 0;
for (StudentQuality.Type type : StudentQuality.Type.values()) {
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null) {
bestQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, best[idx]);
for (int x = 0; x < idx; x++) {
if (best[x] != null && best[x].getAssignments() != null)
bestQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, best[x], best[idx]);
}
}
if (current[idx] != null && current[idx].getAssignments() != null) {
currentQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, current[idx]);
for (int x = 0; x < idx; x++) {
if (current[x] != null && current[x].getAssignments() != null)
currentQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, current[x], current[idx]);
}
}
}
}
if (currentQuality < bestQuality)
return -1;
if (bestQuality < currentQuality)
return 1;
} else {
// 4. avoid time overlaps
if (getModel().getTimeOverlaps() != null) {
int bestTimeOverlaps = 0, currentTimeOverlaps = 0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null) {
for (int x = 0; x < idx; x++) {
if (best[x] != null && best[x].getAssignments() != null)
bestTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(best[x], best[idx]);
else if (getStudent().getRequests().get(x) instanceof FreeTimeRequest)
bestTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(((FreeTimeRequest) getStudent().getRequests().get(x)).createEnrollment(), best[idx]);
}
}
if (current[idx] != null && current[idx].getAssignments() != null) {
for (int x = 0; x < idx; x++) {
if (current[x] != null && current[x].getAssignments() != null)
currentTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(current[x], current[idx]);
else if (getStudent().getRequests().get(x) instanceof FreeTimeRequest)
currentTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(((FreeTimeRequest) getStudent().getRequests().get(x)).createEnrollment(), current[idx]);
}
}
}
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
bestTimeOverlaps += getModel().getTimeOverlaps().nrNotAvailableTimeConflicts(best[idx]);
}
if (current[idx] != null && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
currentTimeOverlaps += getModel().getTimeOverlaps().nrNotAvailableTimeConflicts(current[idx]);
}
}
if (currentTimeOverlaps < bestTimeOverlaps)
return -1;
if (bestTimeOverlaps < currentTimeOverlaps)
return 1;
}
// 5. avoid distance conflicts
if (getModel().getDistanceConflict() != null) {
int bestDistanceConf = 0, currentDistanceConf = 0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null) {
bestDistanceConf += getModel().getDistanceConflict().nrConflicts(best[idx]);
for (int x = 0; x < idx; x++) {
if (best[x] != null && best[x].getAssignments() != null)
bestDistanceConf += getModel().getDistanceConflict().nrConflicts(best[x], best[idx]);
}
}
if (current[idx] != null && current[idx].getAssignments() != null) {
currentDistanceConf += getModel().getDistanceConflict().nrConflicts(current[idx]);
for (int x = 0; x < idx; x++) {
if (current[x] != null && current[x].getAssignments() != null)
currentDistanceConf += getModel().getDistanceConflict().nrConflicts(current[x], current[idx]);
}
}
}
if (currentDistanceConf < bestDistanceConf)
return -1;
if (bestDistanceConf < currentDistanceConf)
return 1;
}
}
// 6. avoid no-time and online sections (no-time first, online second)
int bestNoTime = 0, currentNoTime = 0;
int bestOnline = 0, currentOnline = 0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null) {
for (Section section : best[idx].getSections()) {
if (!section.hasTime())
bestNoTime++;
if (section.isOnline())
bestOnline++;
}
}
if (current[idx] != null && current[idx].getAssignments() != null) {
for (Section section : current[idx].getSections()) {
if (!section.hasTime())
currentNoTime++;
if (section.isOnline())
currentOnline++;
}
}
}
if (currentNoTime < bestNoTime)
return -1;
if (bestNoTime < currentNoTime)
return 1;
if (currentOnline < bestOnline)
return -1;
if (bestOnline < currentOnline)
return 1;
// 7. balance sections
double bestUnavailableSize = 0.0, currentUnavailableSize = 0.0;
int bestAltSectionsWithLimit = 0, currentAltSectionsWithLimit = 0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null) {
for (Section section : best[idx].getSections()) {
Subpart subpart = section.getSubpart();
// skip unlimited and single section subparts
if (subpart.getSections().size() <= 1 || subpart.getLimit() <= 0)
continue;
// average size
double averageSize = ((double) subpart.getLimit()) / subpart.getSections().size();
// section is below average
if (section.getLimit() < averageSize)
bestUnavailableSize += (averageSize - section.getLimit()) / averageSize;
bestAltSectionsWithLimit++;
}
}
if (current[idx] != null && current[idx].getAssignments() != null) {
for (Section section : current[idx].getSections()) {
Subpart subpart = section.getSubpart();
// skip unlimited and single section subparts
if (subpart.getSections().size() <= 1 || subpart.getLimit() <= 0)
continue;
// average size
double averageSize = ((double) subpart.getLimit()) / subpart.getSections().size();
// section is below average
if (section.getLimit() < averageSize)
currentUnavailableSize += (averageSize - section.getLimit()) / averageSize;
currentAltSectionsWithLimit++;
}
}
}
double bestUnavailableSizeFraction = (bestUnavailableSize > 0 ? bestUnavailableSize / bestAltSectionsWithLimit : 0.0);
double currentUnavailableSizeFraction = (currentUnavailableSize > 0 ? currentUnavailableSize / currentAltSectionsWithLimit : 0.0);
if (currentUnavailableSizeFraction < bestUnavailableSizeFraction)
return -1;
if (bestUnavailableSizeFraction < currentUnavailableSizeFraction)
return 1;
// 8. average penalty sections
double bestPenalty = 0.0, currentPenalty = 0.0;
for (int idx = 0; idx < current.length; idx++) {
if (best[idx] != null && best[idx].getAssignments() != null) {
for (Section section : best[idx].getSections()) bestPenalty += section.getPenalty() / best[idx].getSections().size();
}
if (current[idx] != null && current[idx].getAssignments() != null) {
for (Section section : current[idx].getSections()) currentPenalty += section.getPenalty() / current[idx].getSections().size();
}
}
if (currentPenalty < bestPenalty)
return -1;
if (bestPenalty < currentPenalty)
return 1;
return 0;
}
use of org.cpsolver.studentsct.model.Subpart in project cpsolver by UniTime.
the class MultiCriteriaBranchAndBoundSelection method setRequiredSections.
@Override
public void setRequiredSections(Hashtable<CourseRequest, Set<Section>> requiredSections) {
if (requiredSections != null) {
for (Map.Entry<CourseRequest, Set<Section>> entry : requiredSections.entrySet()) {
Hashtable<Subpart, Section> subSection = new Hashtable<Subpart, Section>();
iRequiredSection.put(entry.getKey(), subSection);
for (Section section : entry.getValue()) {
if (subSection.isEmpty())
iRequiredConfig.put(entry.getKey(), section.getSubpart().getConfig());
subSection.put(section.getSubpart(), section);
}
}
}
}
Aggregations