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 1: weight *= iFirstAlternativeFactor; break; 241 case 2: weight *= iSecondAlternativeFactor; break; 242 } 243 if (enrollment.isCourseRequest() && iBalancingFactor != 0.0) { 244 double configUsed = enrollment.getConfig().getEnrollmentTotalWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight(); 245 double disbalanced = 0; 246 double total = 0; 247 for (Section section: enrollment.getSections()) { 248 Subpart subpart = section.getSubpart(); 249 if (subpart.getSections().size() <= 1) continue; 250 double used = section.getEnrollmentTotalWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight(); 251 // sections have limits -> desired size is section limit x (total enrollment / total limit) 252 // unlimited sections -> desired size is total enrollment / number of sections 253 double desired = (subpart.getLimit() > 0 254 ? section.getLimit() * (configUsed / subpart.getLimit()) 255 : configUsed / subpart.getSections().size()); 256 if (used > desired) 257 disbalanced += Math.min(enrollment.getRequest().getWeight(), used - desired) / enrollment.getRequest().getWeight(); 258 else 259 disbalanced -= Math.min(enrollment.getRequest().getWeight(), desired - used) / enrollment.getRequest().getWeight(); 260 total ++; 261 } 262 if (disbalanced > 0) 263 weight *= (1.0 - disbalanced / total * iBalancingFactor); 264 } 265 if (iMPP) { 266 double difference = getDifference(enrollment); 267 if (difference > 0.0) 268 weight *= (1.0 - difference * iPerturbationFactor); 269 } 270 if (iSelectionFactor != 0.0) { 271 double selection = getSelection(enrollment); 272 if (selection > 0.0) 273 weight *= (1.0 - selection * iSelectionFactor); 274 } 275 if (enrollment.isCourseRequest() && iGroupFactor != 0.0) { 276 double sameGroup = 0.0; int groupCount = 0; 277 for (RequestGroup g: ((CourseRequest)enrollment.getRequest()).getRequestGroups()) { 278 if (g.getCourse().equals(enrollment.getCourse())) { 279 sameGroup += g.getEnrollmentSpread(assignment, enrollment, iGroupBestRatio, iGroupFillRatio); 280 groupCount ++; 281 } 282 } 283 if (groupCount > 0) { 284 double difference = 1.0 - sameGroup / groupCount; 285 weight *= (1.0 - difference * iGroupFactor); 286 } 287 } 288 return round(weight); 289 } 290 291 @Override 292 public double getDistanceConflictWeight(Assignment<Request, Enrollment> assignment, DistanceConflict.Conflict c) { 293 if (c.getR1().getPriority() < c.getR2().getPriority()) { 294 return round(getWeight(assignment, c.getE2()) * (c.getStudent().isNeedShortDistances() ? iShortDistanceConflict : iDistanceConflict)); 295 } else { 296 return round(getWeight(assignment, c.getE1()) * (c.getStudent().isNeedShortDistances() ? iShortDistanceConflict : iDistanceConflict)); 297 } 298 } 299 300 @Override 301 public double getTimeOverlapConflictWeight(Assignment<Request, Enrollment> assignment, Enrollment e, TimeOverlapsCounter.Conflict c) { 302 if (e == null || e.getRequest() == null) return 0.0; 303 double toc = Math.min(iTimeOverlapMaxLimit * c.getShare() / e.getNrSlots(), iTimeOverlapMaxLimit); 304 return round(getWeight(assignment, e) * toc); 305 } 306 307 @Override 308 public double getWeight(Assignment<Request, Enrollment> assignment, Enrollment enrollment, Set<DistanceConflict.Conflict> distanceConflicts, Set<TimeOverlapsCounter.Conflict> timeOverlappingConflicts) { 309 double base = getWeight(assignment, enrollment); 310 double dc = 0.0; 311 if (distanceConflicts != null) { 312 for (DistanceConflict.Conflict c: distanceConflicts) { 313 Enrollment other = (c.getE1().equals(enrollment) ? c.getE2() : c.getE1()); 314 if (other.getRequest().getPriority() <= enrollment.getRequest().getPriority()) 315 dc += base * (c.getStudent().isNeedShortDistances() ? iShortDistanceConflict : iDistanceConflict); 316 else 317 dc += getWeight(assignment, other) * (c.getStudent().isNeedShortDistances() ? iShortDistanceConflict : iDistanceConflict); 318 } 319 } 320 double toc = 0.0; 321 if (timeOverlappingConflicts != null) { 322 for (TimeOverlapsCounter.Conflict c: timeOverlappingConflicts) { 323 toc += base * Math.min(iTimeOverlapFactor * c.getShare() / enrollment.getNrSlots(), iTimeOverlapMaxLimit); 324 Enrollment other = (c.getE1().equals(enrollment) ? c.getE2() : c.getE1()); 325 if (other.getRequest() != null) 326 toc += getWeight(assignment, other) * Math.min(iTimeOverlapFactor * c.getShare() / other.getNrSlots(), iTimeOverlapMaxLimit); 327 } 328 } 329 return round(base - dc - toc); 330 } 331 332 333 @Override 334 public boolean isBetterThanBestSolution(Solution<Request, Enrollment> currentSolution) { 335 return currentSolution.getBestInfo() == null || currentSolution.getModel().getTotalValue(currentSolution.getAssignment()) < currentSolution.getBestValue(); 336 } 337 338 @Override 339 public boolean isFreeTimeAllowOverlaps() { 340 return false; 341 } 342 343 /** 344 * Test case -- run to see the weights for a few courses 345 * @param args program arguments 346 */ 347 public static void main(String[] args) { 348 PriorityStudentWeights pw = new PriorityStudentWeights(new DataProperties()); 349 DecimalFormat df = new DecimalFormat("0.0000"); 350 Student s = new Student(0l); 351 new CourseRequest(1l, 0, false, s, ToolBox.toList( 352 new Course(1, "A", "1", new Offering(0, "A")), 353 new Course(1, "A", "2", new Offering(0, "A")), 354 new Course(1, "A", "3", new Offering(0, "A"))), false, null); 355 new CourseRequest(2l, 1, false, s, ToolBox.toList( 356 new Course(1, "B", "1", new Offering(0, "B")), 357 new Course(1, "B", "2", new Offering(0, "B")), 358 new Course(1, "B", "3", new Offering(0, "B"))), false, null); 359 new CourseRequest(3l, 2, false, s, ToolBox.toList( 360 new Course(1, "C", "1", new Offering(0, "C")), 361 new Course(1, "C", "2", new Offering(0, "C")), 362 new Course(1, "C", "3", new Offering(0, "C"))), false, null); 363 new CourseRequest(4l, 3, false, s, ToolBox.toList( 364 new Course(1, "D", "1", new Offering(0, "D")), 365 new Course(1, "D", "2", new Offering(0, "D")), 366 new Course(1, "D", "3", new Offering(0, "D"))), false, null); 367 new CourseRequest(5l, 4, false, s, ToolBox.toList( 368 new Course(1, "E", "1", new Offering(0, "E")), 369 new Course(1, "E", "2", new Offering(0, "E")), 370 new Course(1, "E", "3", new Offering(0, "E"))), false, null); 371 new CourseRequest(6l, 5, true, s, ToolBox.toList( 372 new Course(1, "F", "1", new Offering(0, "F")), 373 new Course(1, "F", "2", new Offering(0, "F")), 374 new Course(1, "F", "3", new Offering(0, "F"))), false, null); 375 new CourseRequest(7l, 6, true, s, ToolBox.toList( 376 new Course(1, "G", "1", new Offering(0, "G")), 377 new Course(1, "G", "2", new Offering(0, "G")), 378 new Course(1, "G", "3", new Offering(0, "G"))), false, null); 379 380 Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>(); 381 Placement p = new Placement(null, new TimeLocation(1, 90, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>()); 382 for (Request r: s.getRequests()) { 383 CourseRequest cr = (CourseRequest)r; 384 double[] w = new double[] {0.0, 0.0, 0.0}; 385 for (int i = 0; i < cr.getCourses().size(); i++) { 386 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 387 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 388 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)); 389 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 390 w[i] = pw.getWeight(assignment, e, null, 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 one distance 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)); 403 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 404 Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>(); 405 dc.add(new DistanceConflict.Conflict(s, e, (Section)sections.iterator().next(), e, (Section)sections.iterator().next())); 406 w[i] = pw.getWeight(assignment, e, dc, null); 407 } 408 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 409 } 410 411 System.out.println("With two distance conflicts:"); 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 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)); 419 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 420 Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>(); 421 dc.add(new DistanceConflict.Conflict(s, e, (Section)sections.iterator().next(), e, (Section)sections.iterator().next())); 422 dc.add(new DistanceConflict.Conflict(s, e, (Section)sections.iterator().next(), e, 423 new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null))); 424 w[i] = pw.getWeight(assignment, e, dc, null); 425 } 426 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 427 } 428 429 System.out.println("With 25% time overlapping conflict:"); 430 for (Request r: s.getRequests()) { 431 CourseRequest cr = (CourseRequest)r; 432 double[] w = new double[] {0.0, 0.0, 0.0}; 433 for (int i = 0; i < cr.getCourses().size(); i++) { 434 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 435 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 436 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)); 437 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 438 Set<TimeOverlapsCounter.Conflict> toc = new HashSet<TimeOverlapsCounter.Conflict>(); 439 toc.add(new TimeOverlapsCounter.Conflict(s, 3, e, sections.iterator().next(), e, sections.iterator().next())); 440 w[i] = pw.getWeight(assignment, e, null, toc); 441 } 442 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 443 } 444 445 System.out.println("Disbalanced sections (by 2 / 10 students):"); 446 for (Request r: s.getRequests()) { 447 CourseRequest cr = (CourseRequest)r; 448 double[] w = new double[] {0.0, 0.0, 0.0}; 449 for (int i = 0; i < cr.getCourses().size(); i++) { 450 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 451 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 452 Subpart x = new Subpart(0, "Lec", "Lec", cfg, null); 453 Section a = new Section(0, 10, "x", x, p, null); 454 new Section(1, 10, "y", x, p, null); 455 sections.add(a); 456 a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 457 a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 458 cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 459 cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 460 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 461 w[i] = pw.getWeight(assignment, e, null, null); 462 } 463 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 464 } 465 466 System.out.println("Same choice sections:"); 467 pw.iMPP = true; 468 for (Request r: s.getRequests()) { 469 CourseRequest cr = (CourseRequest)r; 470 double[] w = new double[] {0.0, 0.0, 0.0}; 471 for (int i = 0; i < cr.getCourses().size(); i++) { 472 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 473 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 474 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)); 475 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 476 Set<SctAssignment> other = new HashSet<SctAssignment>(); 477 other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)); 478 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 479 w[i] = pw.getWeight(assignment, e, null, null); 480 } 481 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 482 } 483 484 System.out.println("Same time sections:"); 485 for (Request r: s.getRequests()) { 486 CourseRequest cr = (CourseRequest)r; 487 double[] w = new double[] {0.0, 0.0, 0.0}; 488 for (int i = 0; i < cr.getCourses().size(); i++) { 489 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 490 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 491 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)); 492 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 493 Set<SctAssignment> other = new HashSet<SctAssignment>(); 494 other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, new Instructor(1l, null, "Josef Novak", null))); 495 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 496 w[i] = pw.getWeight(assignment, e, null, null); 497 } 498 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 499 } 500 501 System.out.println("Different time sections:"); 502 Placement q = new Placement(null, new TimeLocation(1, 102, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>()); 503 for (Request r: s.getRequests()) { 504 CourseRequest cr = (CourseRequest)r; 505 double[] w = new double[] {0.0, 0.0, 0.0}; 506 for (int i = 0; i < cr.getCourses().size(); i++) { 507 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 508 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 509 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)); 510 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 511 Set<SctAssignment> other = new HashSet<SctAssignment>(); 512 other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), q, null)); 513 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 514 w[i] = pw.getWeight(assignment, e, null, null); 515 } 516 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 517 } 518 519 System.out.println("Two sections, one same choice, one same time:"); 520 for (Request r: s.getRequests()) { 521 CourseRequest cr = (CourseRequest)r; 522 double[] w = new double[] {0.0, 0.0, 0.0}; 523 for (int i = 0; i < cr.getCourses().size(); i++) { 524 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 525 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 526 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)); 527 sections.add(new Section(1, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null)); 528 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 529 Set<SctAssignment> other = new HashSet<SctAssignment>(); 530 other.add(new Section(2, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)); 531 other.add(new Section(3, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null, new Instructor(1l, null, "Josef Novak", null))); 532 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 533 w[i] = pw.getWeight(assignment, e, null, null); 534 } 535 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 536 } 537 538 } 539}