001package org.cpsolver.studentsct.weights; 002 003import java.text.DecimalFormat; 004import java.util.ArrayList; 005import java.util.BitSet; 006import java.util.HashSet; 007import java.util.Set; 008 009import org.cpsolver.coursett.model.Placement; 010import org.cpsolver.coursett.model.RoomLocation; 011import org.cpsolver.coursett.model.TimeLocation; 012import org.cpsolver.ifs.assignment.Assignment; 013import org.cpsolver.ifs.assignment.DefaultSingleAssignment; 014import org.cpsolver.ifs.solution.Solution; 015import org.cpsolver.ifs.util.DataProperties; 016import org.cpsolver.ifs.util.ToolBox; 017import org.cpsolver.studentsct.extension.DistanceConflict; 018import org.cpsolver.studentsct.extension.TimeOverlapsCounter; 019import org.cpsolver.studentsct.model.Choice; 020import org.cpsolver.studentsct.model.Config; 021import org.cpsolver.studentsct.model.Course; 022import org.cpsolver.studentsct.model.CourseRequest; 023import org.cpsolver.studentsct.model.Enrollment; 024import org.cpsolver.studentsct.model.Offering; 025import org.cpsolver.studentsct.model.Request; 026import org.cpsolver.studentsct.model.RequestGroup; 027import org.cpsolver.studentsct.model.SctAssignment; 028import org.cpsolver.studentsct.model.Section; 029import org.cpsolver.studentsct.model.Student; 030import org.cpsolver.studentsct.model.Subpart; 031 032 033/** 034 * New weighting model. It tries to obey the following principles: 035 * <ul> 036 * <li> Total student weight is between zero and one (one means student got the best schedule) 037 * <li> Weight of the given priority course is higher than sum of the remaining weights the student can get 038 * <li> First alternative is better than the following course 039 * <li> Second alternative is better than the second following course 040 * <li> Distance conflicts are considered secondary (priorities should be maximized first) 041 * <li> If alternative sections are otherwise equal, use the better balanced one 042 * </ul> 043 * 044 * @version StudentSct 1.3 (Student Sectioning)<br> 045 * Copyright (C) 2007 - 2014 Tomas Muller<br> 046 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 047 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 048 * <br> 049 * This library is free software; you can redistribute it and/or modify 050 * it under the terms of the GNU Lesser General Public License as 051 * published by the Free Software Foundation; either version 3 of the 052 * License, or (at your option) any later version. <br> 053 * <br> 054 * This library is distributed in the hope that it will be useful, but 055 * WITHOUT ANY WARRANTY; without even the implied warranty of 056 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 057 * Lesser General Public License for more details. <br> 058 * <br> 059 * You should have received a copy of the GNU Lesser General Public 060 * License along with this library; if not see 061 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 062 */ 063 064public class PriorityStudentWeights implements StudentWeights { 065 protected double iPriorityFactor = 0.5010; 066 protected double iFirstAlternativeFactor = 0.5010; 067 protected double iSecondAlternativeFactor = 0.2510; 068 protected double iDistanceConflict = 0.0100; 069 protected double iTimeOverlapFactor = 0.5000; 070 protected double iTimeOverlapMaxLimit = 0.5000; 071 protected boolean iLeftoverSpread = false; 072 protected double iBalancingFactor = 0.0050; 073 protected double iAlternativeRequestFactor = 0.1260; 074 protected double iProjectedStudentWeight = 0.0100; 075 protected boolean iMPP = false; 076 protected double iPerturbationFactor = 0.100; 077 protected double iSameChoiceWeight = 0.900; 078 protected double iSameTimeWeight = 0.700; 079 protected double iGroupFactor = 0.100; 080 081 public PriorityStudentWeights(DataProperties config) { 082 iPriorityFactor = config.getPropertyDouble("StudentWeights.Priority", iPriorityFactor); 083 iFirstAlternativeFactor = config.getPropertyDouble("StudentWeights.FirstAlternative", iFirstAlternativeFactor); 084 iSecondAlternativeFactor = config.getPropertyDouble("StudentWeights.SecondAlternative", iSecondAlternativeFactor); 085 iDistanceConflict = config.getPropertyDouble("StudentWeights.DistanceConflict", iDistanceConflict); 086 iTimeOverlapFactor = config.getPropertyDouble("StudentWeights.TimeOverlapFactor", iTimeOverlapFactor); 087 iTimeOverlapMaxLimit = config.getPropertyDouble("StudentWeights.TimeOverlapMaxLimit", iTimeOverlapMaxLimit); 088 iLeftoverSpread = config.getPropertyBoolean("StudentWeights.LeftoverSpread", iLeftoverSpread); 089 iBalancingFactor = config.getPropertyDouble("StudentWeights.BalancingFactor", iBalancingFactor); 090 iAlternativeRequestFactor = config.getPropertyDouble("StudentWeights.AlternativeRequestFactor", iAlternativeRequestFactor); 091 iProjectedStudentWeight = config.getPropertyDouble("StudentWeights.ProjectedStudentWeight", iProjectedStudentWeight); 092 iMPP = config.getPropertyBoolean("General.MPP", false); 093 iPerturbationFactor = config.getPropertyDouble("StudentWeights.Perturbation", iPerturbationFactor); 094 iSameChoiceWeight = config.getPropertyDouble("StudentWeights.SameChoice", iSameChoiceWeight); 095 iSameTimeWeight = config.getPropertyDouble("StudentWeights.SameTime", iSameTimeWeight); 096 iGroupFactor = config.getPropertyDouble("StudentWeights.SameGroup", iGroupFactor); 097 } 098 099 public double getWeight(Request request) { 100 if (request.getStudent().isDummy() && iProjectedStudentWeight >= 0.0) { 101 double weight = iProjectedStudentWeight; 102 if (request.isAlternative()) 103 weight *= iAlternativeRequestFactor; 104 return weight; 105 } 106 double total = 10000.0; 107 int nrReq = request.getStudent().nrRequests(); 108 double remain = (iLeftoverSpread ? Math.floor(10000.0 * Math.pow(iPriorityFactor, nrReq) / nrReq) : 0.0); 109 for (int idx = 0; idx < request.getStudent().getRequests().size(); idx++) { 110 Request r = request.getStudent().getRequests().get(idx); 111 boolean last = (idx + 1 == request.getStudent().getRequests().size()); 112 boolean lastNotAlt = !r.isAlternative() && (last || request.getStudent().getRequests().get(1 + idx).isAlternative()); 113 double w = Math.ceil(iPriorityFactor * total) + remain; 114 if (lastNotAlt || last) { 115 w = total; 116 } else { 117 total -= w; 118 } 119 if (r.equals(request)) { 120 return w / 10000.0; 121 } 122 } 123 return 0.0; 124 } 125 126 public double getCachedWeight(Request request) { 127 Double w = (Double)request.getExtra(); 128 if (w == null) { 129 w = getWeight(request); 130 request.setExtra(w); 131 } 132 return w; 133 } 134 135 /** 136 * Return how much the given enrollment is different from the initial enrollment 137 * @param enrollment given enrollment 138 * @return 0.0 when all the sections are the same, 1.0 when all the section are different (including different times) 139 */ 140 protected double getDifference(Enrollment enrollment) { 141 if (!enrollment.getRequest().isMPP()) return 1.0; 142 Enrollment other = enrollment.getRequest().getInitialAssignment(); 143 if (other != null) { 144 double similarSections = 0.0; 145 if (enrollment.getConfig().equals(other.getConfig())) { 146 // same configurations -- compare sections of matching subpart 147 for (Section section: enrollment.getSections()) { 148 for (Section initial: other.getSections()) { 149 if (section.getSubpart().equals(initial.getSubpart())) { 150 if (section.equals(initial)) { 151 similarSections += 1.0; 152 } else if (section.getChoice().equals(initial.getChoice())) { 153 similarSections += iSameChoiceWeight; 154 } else if (section.sameTime(initial)) { 155 similarSections += iSameTimeWeight; 156 } 157 break; 158 } 159 } 160 } 161 } else { 162 // different configurations -- compare sections of matching itype 163 for (Section section: enrollment.getSections()) { 164 for (Section initial: other.getSections()) { 165 if (section.getChoice().equals(initial.getChoice())) { 166 similarSections += iSameChoiceWeight; 167 break; 168 } else if (section.getChoice().sameTime(initial.getChoice())) { 169 similarSections += iSameTimeWeight; 170 break; 171 } 172 } 173 } 174 } 175 return 1.0 - similarSections / enrollment.getAssignments().size(); 176 } else if (enrollment.isCourseRequest()) { 177 CourseRequest cr = (CourseRequest)enrollment.getRequest(); 178 if (!cr.getSelectedChoices().isEmpty()) { 179 double similarSections = 0.0; 180 for (Section section: enrollment.getSections()) { 181 for (Choice ch: cr.getSelectedChoices()) { 182 if (ch.equals(section.getChoice())) { 183 similarSections += iSameChoiceWeight; 184 break; 185 } else if (ch.sameTime(section.getChoice())) { 186 similarSections += iSameTimeWeight; 187 break; 188 } 189 } 190 } 191 return 1.0 - similarSections / enrollment.getAssignments().size(); 192 } else { 193 return 1.0; 194 } 195 } else { 196 return 1.0; 197 } 198 } 199 200 @Override 201 public double getBound(Request request) { 202 return getCachedWeight(request); 203 } 204 205 protected double round(double value) { 206 return Math.ceil(10000.0 * value) / 10000.0; 207 } 208 209 @Override 210 public double getWeight(Assignment<Request, Enrollment> assignment, Enrollment enrollment) { 211 double weight = getCachedWeight(enrollment.getRequest()); 212 switch (enrollment.getPriority()) { 213 case 1: weight *= iFirstAlternativeFactor; break; 214 case 2: weight *= iSecondAlternativeFactor; break; 215 } 216 if (enrollment.isCourseRequest() && iBalancingFactor != 0.0) { 217 double configUsed = enrollment.getConfig().getEnrollmentWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight(); 218 double disbalanced = 0; 219 double total = 0; 220 for (Section section: enrollment.getSections()) { 221 Subpart subpart = section.getSubpart(); 222 if (subpart.getSections().size() <= 1) continue; 223 double used = section.getEnrollmentWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight(); 224 // sections have limits -> desired size is section limit x (total enrollment / total limit) 225 // unlimited sections -> desired size is total enrollment / number of sections 226 double desired = (subpart.getLimit() > 0 227 ? section.getLimit() * (configUsed / subpart.getLimit()) 228 : configUsed / subpart.getSections().size()); 229 if (used > desired) 230 disbalanced += Math.min(enrollment.getRequest().getWeight(), used - desired) / enrollment.getRequest().getWeight(); 231 else 232 disbalanced -= Math.min(enrollment.getRequest().getWeight(), desired - used) / enrollment.getRequest().getWeight(); 233 total ++; 234 } 235 if (disbalanced > 0) 236 weight *= (1.0 - disbalanced / total * iBalancingFactor); 237 } 238 if (iMPP) { 239 double difference = getDifference(enrollment); 240 if (difference > 0.0) 241 weight *= (1.0 - difference * iPerturbationFactor); 242 } 243 if (enrollment.isCourseRequest() && iGroupFactor != 0.0) { 244 double sameGroup = 0.0; int groupCount = 0; 245 for (RequestGroup g: ((CourseRequest)enrollment.getRequest()).getRequestGroups()) { 246 if (g.getCourse().equals(enrollment.getCourse())) { 247 sameGroup += g.getEnrollmentSpread(assignment, enrollment); 248 groupCount ++; 249 } 250 } 251 if (groupCount > 0) { 252 double difference = 1.0 - sameGroup / groupCount; 253 weight *= (1.0 - difference * iGroupFactor); 254 } 255 } 256 return round(weight); 257 } 258 259 @Override 260 public double getDistanceConflictWeight(Assignment<Request, Enrollment> assignment, DistanceConflict.Conflict c) { 261 if (c.getR1().getPriority() < c.getR2().getPriority()) { 262 return round(getWeight(assignment, c.getE2()) * iDistanceConflict); 263 } else { 264 return round(getWeight(assignment, c.getE1()) * iDistanceConflict); 265 } 266 } 267 268 @Override 269 public double getTimeOverlapConflictWeight(Assignment<Request, Enrollment> assignment, Enrollment e, TimeOverlapsCounter.Conflict c) { 270 double toc = Math.min(iTimeOverlapMaxLimit * c.getShare() / e.getNrSlots(), iTimeOverlapMaxLimit); 271 return round(getWeight(assignment, e) * toc); 272 } 273 274 @Override 275 public double getWeight(Assignment<Request, Enrollment> assignment, Enrollment enrollment, Set<DistanceConflict.Conflict> distanceConflicts, Set<TimeOverlapsCounter.Conflict> timeOverlappingConflicts) { 276 double base = getWeight(assignment, enrollment); 277 double dc = 0.0; 278 if (distanceConflicts != null) { 279 for (DistanceConflict.Conflict c: distanceConflicts) { 280 Enrollment other = (c.getE1().equals(enrollment) ? c.getE2() : c.getE1()); 281 if (other.getRequest().getPriority() <= enrollment.getRequest().getPriority()) 282 dc += base * iDistanceConflict; 283 else 284 dc += getWeight(assignment, other) * iDistanceConflict; 285 } 286 } 287 double toc = 0.0; 288 if (timeOverlappingConflicts != null) { 289 for (TimeOverlapsCounter.Conflict c: timeOverlappingConflicts) { 290 toc += base * Math.min(iTimeOverlapFactor * c.getShare() / enrollment.getNrSlots(), iTimeOverlapMaxLimit); 291 Enrollment other = (c.getE1().equals(enrollment) ? c.getE2() : c.getE1()); 292 toc += getWeight(assignment, other) * Math.min(iTimeOverlapFactor * c.getShare() / other.getNrSlots(), iTimeOverlapMaxLimit); 293 } 294 } 295 return round(base - dc - toc); 296 } 297 298 299 @Override 300 public boolean isBetterThanBestSolution(Solution<Request, Enrollment> currentSolution) { 301 return currentSolution.getBestInfo() == null || currentSolution.getModel().getTotalValue(currentSolution.getAssignment()) < currentSolution.getBestValue(); 302 } 303 304 @Override 305 public boolean isFreeTimeAllowOverlaps() { 306 return false; 307 } 308 309 /** 310 * Test case -- run to see the weights for a few courses 311 * @param args program arguments 312 */ 313 public static void main(String[] args) { 314 PriorityStudentWeights pw = new PriorityStudentWeights(new DataProperties()); 315 DecimalFormat df = new DecimalFormat("0.0000"); 316 Student s = new Student(0l); 317 new CourseRequest(1l, 0, false, s, ToolBox.toList( 318 new Course(1, "A", "1", new Offering(0, "A")), 319 new Course(1, "A", "2", new Offering(0, "A")), 320 new Course(1, "A", "3", new Offering(0, "A"))), false, null); 321 new CourseRequest(2l, 1, false, s, ToolBox.toList( 322 new Course(1, "B", "1", new Offering(0, "B")), 323 new Course(1, "B", "2", new Offering(0, "B")), 324 new Course(1, "B", "3", new Offering(0, "B"))), false, null); 325 new CourseRequest(3l, 2, false, s, ToolBox.toList( 326 new Course(1, "C", "1", new Offering(0, "C")), 327 new Course(1, "C", "2", new Offering(0, "C")), 328 new Course(1, "C", "3", new Offering(0, "C"))), false, null); 329 new CourseRequest(4l, 3, false, s, ToolBox.toList( 330 new Course(1, "D", "1", new Offering(0, "D")), 331 new Course(1, "D", "2", new Offering(0, "D")), 332 new Course(1, "D", "3", new Offering(0, "D"))), false, null); 333 new CourseRequest(5l, 4, false, s, ToolBox.toList( 334 new Course(1, "E", "1", new Offering(0, "E")), 335 new Course(1, "E", "2", new Offering(0, "E")), 336 new Course(1, "E", "3", new Offering(0, "E"))), false, null); 337 new CourseRequest(6l, 5, true, s, ToolBox.toList( 338 new Course(1, "F", "1", new Offering(0, "F")), 339 new Course(1, "F", "2", new Offering(0, "F")), 340 new Course(1, "F", "3", new Offering(0, "F"))), false, null); 341 new CourseRequest(7l, 6, true, s, ToolBox.toList( 342 new Course(1, "G", "1", new Offering(0, "G")), 343 new Course(1, "G", "2", new Offering(0, "G")), 344 new Course(1, "G", "3", new Offering(0, "G"))), false, null); 345 346 Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>(); 347 Placement p = new Placement(null, new TimeLocation(1, 90, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>()); 348 for (Request r: s.getRequests()) { 349 CourseRequest cr = (CourseRequest)r; 350 double[] w = new double[] {0.0, 0.0, 0.0}; 351 for (int i = 0; i < cr.getCourses().size(); i++) { 352 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 353 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 354 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 355 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 356 w[i] = pw.getWeight(assignment, e, null, null); 357 } 358 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 359 } 360 361 System.out.println("With one distance conflict:"); 362 for (Request r: s.getRequests()) { 363 CourseRequest cr = (CourseRequest)r; 364 double[] w = new double[] {0.0, 0.0, 0.0}; 365 for (int i = 0; i < cr.getCourses().size(); i++) { 366 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 367 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 368 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 369 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 370 Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>(); 371 dc.add(new DistanceConflict.Conflict(s, e, (Section)sections.iterator().next(), e, (Section)sections.iterator().next())); 372 w[i] = pw.getWeight(assignment, e, dc, null); 373 } 374 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 375 } 376 377 System.out.println("With two distance conflicts:"); 378 for (Request r: s.getRequests()) { 379 CourseRequest cr = (CourseRequest)r; 380 double[] w = new double[] {0.0, 0.0, 0.0}; 381 for (int i = 0; i < cr.getCourses().size(); i++) { 382 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 383 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 384 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 385 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 386 Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>(); 387 dc.add(new DistanceConflict.Conflict(s, e, (Section)sections.iterator().next(), e, (Section)sections.iterator().next())); 388 dc.add(new DistanceConflict.Conflict(s, e, (Section)sections.iterator().next(), e, 389 new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null))); 390 w[i] = pw.getWeight(assignment, e, dc, null); 391 } 392 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 393 } 394 395 System.out.println("With 25% time overlapping conflict:"); 396 for (Request r: s.getRequests()) { 397 CourseRequest cr = (CourseRequest)r; 398 double[] w = new double[] {0.0, 0.0, 0.0}; 399 for (int i = 0; i < cr.getCourses().size(); i++) { 400 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 401 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 402 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 403 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 404 Set<TimeOverlapsCounter.Conflict> toc = new HashSet<TimeOverlapsCounter.Conflict>(); 405 toc.add(new TimeOverlapsCounter.Conflict(s, 3, e, sections.iterator().next(), e, sections.iterator().next())); 406 w[i] = pw.getWeight(assignment, e, null, toc); 407 } 408 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 409 } 410 411 System.out.println("Disbalanced sections (by 2 / 10 students):"); 412 for (Request r: s.getRequests()) { 413 CourseRequest cr = (CourseRequest)r; 414 double[] w = new double[] {0.0, 0.0, 0.0}; 415 for (int i = 0; i < cr.getCourses().size(); i++) { 416 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 417 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 418 Subpart x = new Subpart(0, "Lec", "Lec", cfg, null); 419 Section a = new Section(0, 10, "x", x, p, null, null, null); 420 new Section(1, 10, "y", x, p, null, null, null); 421 sections.add(a); 422 a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 423 a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 424 cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 425 cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 426 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 427 w[i] = pw.getWeight(assignment, e, null, null); 428 } 429 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 430 } 431 432 System.out.println("Same choice sections:"); 433 pw.iMPP = true; 434 for (Request r: s.getRequests()) { 435 CourseRequest cr = (CourseRequest)r; 436 double[] w = new double[] {0.0, 0.0, 0.0}; 437 for (int i = 0; i < cr.getCourses().size(); i++) { 438 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 439 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 440 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 441 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 442 Set<SctAssignment> other = new HashSet<SctAssignment>(); 443 other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 444 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 445 w[i] = pw.getWeight(assignment, e, null, null); 446 } 447 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 448 } 449 450 System.out.println("Same time sections:"); 451 for (Request r: s.getRequests()) { 452 CourseRequest cr = (CourseRequest)r; 453 double[] w = new double[] {0.0, 0.0, 0.0}; 454 for (int i = 0; i < cr.getCourses().size(); i++) { 455 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 456 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 457 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 458 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 459 Set<SctAssignment> other = new HashSet<SctAssignment>(); 460 other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, "1", "Josef Novak", null)); 461 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 462 w[i] = pw.getWeight(assignment, e, null, null); 463 } 464 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 465 } 466 467 System.out.println("Different time sections:"); 468 Placement q = new Placement(null, new TimeLocation(1, 102, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>()); 469 for (Request r: s.getRequests()) { 470 CourseRequest cr = (CourseRequest)r; 471 double[] w = new double[] {0.0, 0.0, 0.0}; 472 for (int i = 0; i < cr.getCourses().size(); i++) { 473 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 474 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 475 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 476 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 477 Set<SctAssignment> other = new HashSet<SctAssignment>(); 478 other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), q, null, null, null)); 479 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 480 w[i] = pw.getWeight(assignment, e, null, null); 481 } 482 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 483 } 484 485 System.out.println("Two sections, one same choice, one same time:"); 486 for (Request r: s.getRequests()) { 487 CourseRequest cr = (CourseRequest)r; 488 double[] w = new double[] {0.0, 0.0, 0.0}; 489 for (int i = 0; i < cr.getCourses().size(); i++) { 490 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 491 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 492 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 493 sections.add(new Section(1, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null, null, null)); 494 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 495 Set<SctAssignment> other = new HashSet<SctAssignment>(); 496 other.add(new Section(2, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 497 other.add(new Section(3, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, "1", "Josef Novak", null)); 498 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 499 w[i] = pw.getWeight(assignment, e, null, null); 500 } 501 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 502 } 503 504 } 505}