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