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 protected double iGroupBestRatio = 0.95; 081 protected double iGroupFillRatio = 0.05; 082 083 public PriorityStudentWeights(DataProperties config) { 084 iPriorityFactor = config.getPropertyDouble("StudentWeights.Priority", iPriorityFactor); 085 iFirstAlternativeFactor = config.getPropertyDouble("StudentWeights.FirstAlternative", iFirstAlternativeFactor); 086 iSecondAlternativeFactor = config.getPropertyDouble("StudentWeights.SecondAlternative", iSecondAlternativeFactor); 087 iDistanceConflict = config.getPropertyDouble("StudentWeights.DistanceConflict", iDistanceConflict); 088 iTimeOverlapFactor = config.getPropertyDouble("StudentWeights.TimeOverlapFactor", iTimeOverlapFactor); 089 iTimeOverlapMaxLimit = config.getPropertyDouble("StudentWeights.TimeOverlapMaxLimit", iTimeOverlapMaxLimit); 090 iLeftoverSpread = config.getPropertyBoolean("StudentWeights.LeftoverSpread", iLeftoverSpread); 091 iBalancingFactor = config.getPropertyDouble("StudentWeights.BalancingFactor", iBalancingFactor); 092 iAlternativeRequestFactor = config.getPropertyDouble("StudentWeights.AlternativeRequestFactor", iAlternativeRequestFactor); 093 iProjectedStudentWeight = config.getPropertyDouble("StudentWeights.ProjectedStudentWeight", iProjectedStudentWeight); 094 iMPP = config.getPropertyBoolean("General.MPP", false); 095 iPerturbationFactor = config.getPropertyDouble("StudentWeights.Perturbation", iPerturbationFactor); 096 iSameChoiceWeight = config.getPropertyDouble("StudentWeights.SameChoice", iSameChoiceWeight); 097 iSameTimeWeight = config.getPropertyDouble("StudentWeights.SameTime", iSameTimeWeight); 098 iGroupFactor = config.getPropertyDouble("StudentWeights.SameGroup", iGroupFactor); 099 iGroupBestRatio = config.getPropertyDouble("StudentWeights.GroupBestRatio", iGroupBestRatio); 100 iGroupFillRatio = config.getPropertyDouble("StudentWeights.GroupFillRatio", iGroupFillRatio); 101 } 102 103 public double getWeight(Request request) { 104 if (request.getStudent().isDummy() && iProjectedStudentWeight >= 0.0) { 105 double weight = iProjectedStudentWeight; 106 if (request.isAlternative()) 107 weight *= iAlternativeRequestFactor; 108 return weight; 109 } 110 double total = 10000.0; 111 int nrReq = request.getStudent().nrRequests(); 112 double remain = (iLeftoverSpread ? Math.floor(10000.0 * Math.pow(iPriorityFactor, nrReq) / nrReq) : 0.0); 113 for (int idx = 0; idx < request.getStudent().getRequests().size(); idx++) { 114 Request r = request.getStudent().getRequests().get(idx); 115 boolean last = (idx + 1 == request.getStudent().getRequests().size()); 116 boolean lastNotAlt = !r.isAlternative() && (last || request.getStudent().getRequests().get(1 + idx).isAlternative()); 117 double w = Math.ceil(iPriorityFactor * total) + remain; 118 if (lastNotAlt || last) { 119 w = total; 120 } else { 121 total -= w; 122 } 123 if (r.equals(request)) { 124 return w / 10000.0; 125 } 126 } 127 return 0.0; 128 } 129 130 public double getCachedWeight(Request request) { 131 Double w = (Double)request.getExtra(); 132 if (w == null) { 133 w = getWeight(request); 134 request.setExtra(w); 135 } 136 return w; 137 } 138 139 /** 140 * Return how much the given enrollment is different from the initial enrollment 141 * @param enrollment given enrollment 142 * @return 0.0 when all the sections are the same, 1.0 when all the section are different (including different times) 143 */ 144 protected double getDifference(Enrollment enrollment) { 145 if (!enrollment.getRequest().isMPP()) return 1.0; 146 Enrollment other = enrollment.getRequest().getInitialAssignment(); 147 if (other != null) { 148 double similarSections = 0.0; 149 if (enrollment.getConfig().equals(other.getConfig())) { 150 // same configurations -- compare sections of matching subpart 151 for (Section section: enrollment.getSections()) { 152 for (Section initial: other.getSections()) { 153 if (section.getSubpart().equals(initial.getSubpart())) { 154 if (section.equals(initial)) { 155 similarSections += 1.0; 156 } else if (section.getChoice().equals(initial.getChoice())) { 157 similarSections += iSameChoiceWeight; 158 } else if (section.sameTime(initial)) { 159 similarSections += iSameTimeWeight; 160 } 161 break; 162 } 163 } 164 } 165 } else { 166 // different configurations -- compare sections of matching itype 167 for (Section section: enrollment.getSections()) { 168 for (Section initial: other.getSections()) { 169 if (section.getChoice().equals(initial.getChoice())) { 170 similarSections += iSameChoiceWeight; 171 break; 172 } else if (section.getChoice().sameTime(initial.getChoice())) { 173 similarSections += iSameTimeWeight; 174 break; 175 } 176 } 177 } 178 } 179 return 1.0 - similarSections / enrollment.getAssignments().size(); 180 } else if (enrollment.isCourseRequest()) { 181 CourseRequest cr = (CourseRequest)enrollment.getRequest(); 182 if (!cr.getSelectedChoices().isEmpty()) { 183 double similarSections = 0.0; 184 for (Section section: enrollment.getSections()) { 185 for (Choice ch: cr.getSelectedChoices()) { 186 if (ch.equals(section.getChoice())) { 187 similarSections += iSameChoiceWeight; 188 break; 189 } else if (ch.sameTime(section.getChoice())) { 190 similarSections += iSameTimeWeight; 191 break; 192 } 193 } 194 } 195 return 1.0 - similarSections / enrollment.getAssignments().size(); 196 } else { 197 return 1.0; 198 } 199 } else { 200 return 1.0; 201 } 202 } 203 204 @Override 205 public double getBound(Request request) { 206 return getCachedWeight(request); 207 } 208 209 protected double round(double value) { 210 return Math.ceil(10000.0 * value) / 10000.0; 211 } 212 213 @Override 214 public double getWeight(Assignment<Request, Enrollment> assignment, Enrollment enrollment) { 215 double weight = getCachedWeight(enrollment.getRequest()); 216 switch (enrollment.getPriority()) { 217 case 1: weight *= iFirstAlternativeFactor; break; 218 case 2: weight *= iSecondAlternativeFactor; break; 219 } 220 if (enrollment.isCourseRequest() && iBalancingFactor != 0.0) { 221 double configUsed = enrollment.getConfig().getEnrollmentWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight(); 222 double disbalanced = 0; 223 double total = 0; 224 for (Section section: enrollment.getSections()) { 225 Subpart subpart = section.getSubpart(); 226 if (subpart.getSections().size() <= 1) continue; 227 double used = section.getEnrollmentWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight(); 228 // sections have limits -> desired size is section limit x (total enrollment / total limit) 229 // unlimited sections -> desired size is total enrollment / number of sections 230 double desired = (subpart.getLimit() > 0 231 ? section.getLimit() * (configUsed / subpart.getLimit()) 232 : configUsed / subpart.getSections().size()); 233 if (used > desired) 234 disbalanced += Math.min(enrollment.getRequest().getWeight(), used - desired) / enrollment.getRequest().getWeight(); 235 else 236 disbalanced -= Math.min(enrollment.getRequest().getWeight(), desired - used) / enrollment.getRequest().getWeight(); 237 total ++; 238 } 239 if (disbalanced > 0) 240 weight *= (1.0 - disbalanced / total * iBalancingFactor); 241 } 242 if (iMPP) { 243 double difference = getDifference(enrollment); 244 if (difference > 0.0) 245 weight *= (1.0 - difference * iPerturbationFactor); 246 } 247 if (enrollment.isCourseRequest() && iGroupFactor != 0.0) { 248 double sameGroup = 0.0; int groupCount = 0; 249 for (RequestGroup g: ((CourseRequest)enrollment.getRequest()).getRequestGroups()) { 250 if (g.getCourse().equals(enrollment.getCourse())) { 251 sameGroup += g.getEnrollmentSpread(assignment, enrollment, iGroupBestRatio, iGroupFillRatio); 252 groupCount ++; 253 } 254 } 255 if (groupCount > 0) { 256 double difference = 1.0 - sameGroup / groupCount; 257 weight *= (1.0 - difference * iGroupFactor); 258 } 259 } 260 return round(weight); 261 } 262 263 @Override 264 public double getDistanceConflictWeight(Assignment<Request, Enrollment> assignment, DistanceConflict.Conflict c) { 265 if (c.getR1().getPriority() < c.getR2().getPriority()) { 266 return round(getWeight(assignment, c.getE2()) * iDistanceConflict); 267 } else { 268 return round(getWeight(assignment, c.getE1()) * iDistanceConflict); 269 } 270 } 271 272 @Override 273 public double getTimeOverlapConflictWeight(Assignment<Request, Enrollment> assignment, Enrollment e, TimeOverlapsCounter.Conflict c) { 274 double toc = Math.min(iTimeOverlapMaxLimit * c.getShare() / e.getNrSlots(), iTimeOverlapMaxLimit); 275 return round(getWeight(assignment, e) * toc); 276 } 277 278 @Override 279 public double getWeight(Assignment<Request, Enrollment> assignment, Enrollment enrollment, Set<DistanceConflict.Conflict> distanceConflicts, Set<TimeOverlapsCounter.Conflict> timeOverlappingConflicts) { 280 double base = getWeight(assignment, enrollment); 281 double dc = 0.0; 282 if (distanceConflicts != null) { 283 for (DistanceConflict.Conflict c: distanceConflicts) { 284 Enrollment other = (c.getE1().equals(enrollment) ? c.getE2() : c.getE1()); 285 if (other.getRequest().getPriority() <= enrollment.getRequest().getPriority()) 286 dc += base * iDistanceConflict; 287 else 288 dc += getWeight(assignment, other) * iDistanceConflict; 289 } 290 } 291 double toc = 0.0; 292 if (timeOverlappingConflicts != null) { 293 for (TimeOverlapsCounter.Conflict c: timeOverlappingConflicts) { 294 toc += base * Math.min(iTimeOverlapFactor * c.getShare() / enrollment.getNrSlots(), iTimeOverlapMaxLimit); 295 Enrollment other = (c.getE1().equals(enrollment) ? c.getE2() : c.getE1()); 296 toc += getWeight(assignment, other) * Math.min(iTimeOverlapFactor * c.getShare() / other.getNrSlots(), iTimeOverlapMaxLimit); 297 } 298 } 299 return round(base - dc - toc); 300 } 301 302 303 @Override 304 public boolean isBetterThanBestSolution(Solution<Request, Enrollment> currentSolution) { 305 return currentSolution.getBestInfo() == null || currentSolution.getModel().getTotalValue(currentSolution.getAssignment()) < currentSolution.getBestValue(); 306 } 307 308 @Override 309 public boolean isFreeTimeAllowOverlaps() { 310 return false; 311 } 312 313 /** 314 * Test case -- run to see the weights for a few courses 315 * @param args program arguments 316 */ 317 public static void main(String[] args) { 318 PriorityStudentWeights pw = new PriorityStudentWeights(new DataProperties()); 319 DecimalFormat df = new DecimalFormat("0.0000"); 320 Student s = new Student(0l); 321 new CourseRequest(1l, 0, false, s, ToolBox.toList( 322 new Course(1, "A", "1", new Offering(0, "A")), 323 new Course(1, "A", "2", new Offering(0, "A")), 324 new Course(1, "A", "3", new Offering(0, "A"))), false, null); 325 new CourseRequest(2l, 1, false, s, ToolBox.toList( 326 new Course(1, "B", "1", new Offering(0, "B")), 327 new Course(1, "B", "2", new Offering(0, "B")), 328 new Course(1, "B", "3", new Offering(0, "B"))), false, null); 329 new CourseRequest(3l, 2, false, s, ToolBox.toList( 330 new Course(1, "C", "1", new Offering(0, "C")), 331 new Course(1, "C", "2", new Offering(0, "C")), 332 new Course(1, "C", "3", new Offering(0, "C"))), false, null); 333 new CourseRequest(4l, 3, false, s, ToolBox.toList( 334 new Course(1, "D", "1", new Offering(0, "D")), 335 new Course(1, "D", "2", new Offering(0, "D")), 336 new Course(1, "D", "3", new Offering(0, "D"))), false, null); 337 new CourseRequest(5l, 4, false, s, ToolBox.toList( 338 new Course(1, "E", "1", new Offering(0, "E")), 339 new Course(1, "E", "2", new Offering(0, "E")), 340 new Course(1, "E", "3", new Offering(0, "E"))), false, null); 341 new CourseRequest(6l, 5, true, s, ToolBox.toList( 342 new Course(1, "F", "1", new Offering(0, "F")), 343 new Course(1, "F", "2", new Offering(0, "F")), 344 new Course(1, "F", "3", new Offering(0, "F"))), false, null); 345 new CourseRequest(7l, 6, true, s, ToolBox.toList( 346 new Course(1, "G", "1", new Offering(0, "G")), 347 new Course(1, "G", "2", new Offering(0, "G")), 348 new Course(1, "G", "3", new Offering(0, "G"))), false, null); 349 350 Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>(); 351 Placement p = new Placement(null, new TimeLocation(1, 90, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>()); 352 for (Request r: s.getRequests()) { 353 CourseRequest cr = (CourseRequest)r; 354 double[] w = new double[] {0.0, 0.0, 0.0}; 355 for (int i = 0; i < cr.getCourses().size(); i++) { 356 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 357 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 358 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 359 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 360 w[i] = pw.getWeight(assignment, e, null, null); 361 } 362 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 363 } 364 365 System.out.println("With one distance conflict:"); 366 for (Request r: s.getRequests()) { 367 CourseRequest cr = (CourseRequest)r; 368 double[] w = new double[] {0.0, 0.0, 0.0}; 369 for (int i = 0; i < cr.getCourses().size(); i++) { 370 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 371 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 372 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 373 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 374 Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>(); 375 dc.add(new DistanceConflict.Conflict(s, e, (Section)sections.iterator().next(), e, (Section)sections.iterator().next())); 376 w[i] = pw.getWeight(assignment, e, dc, null); 377 } 378 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 379 } 380 381 System.out.println("With two distance conflicts:"); 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, null, null)); 389 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 390 Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>(); 391 dc.add(new DistanceConflict.Conflict(s, e, (Section)sections.iterator().next(), e, (Section)sections.iterator().next())); 392 dc.add(new DistanceConflict.Conflict(s, e, (Section)sections.iterator().next(), e, 393 new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null))); 394 w[i] = pw.getWeight(assignment, e, dc, null); 395 } 396 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 397 } 398 399 System.out.println("With 25% time overlapping conflict:"); 400 for (Request r: s.getRequests()) { 401 CourseRequest cr = (CourseRequest)r; 402 double[] w = new double[] {0.0, 0.0, 0.0}; 403 for (int i = 0; i < cr.getCourses().size(); i++) { 404 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 405 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 406 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 407 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 408 Set<TimeOverlapsCounter.Conflict> toc = new HashSet<TimeOverlapsCounter.Conflict>(); 409 toc.add(new TimeOverlapsCounter.Conflict(s, 3, e, sections.iterator().next(), e, sections.iterator().next())); 410 w[i] = pw.getWeight(assignment, e, null, toc); 411 } 412 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 413 } 414 415 System.out.println("Disbalanced sections (by 2 / 10 students):"); 416 for (Request r: s.getRequests()) { 417 CourseRequest cr = (CourseRequest)r; 418 double[] w = new double[] {0.0, 0.0, 0.0}; 419 for (int i = 0; i < cr.getCourses().size(); i++) { 420 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 421 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 422 Subpart x = new Subpart(0, "Lec", "Lec", cfg, null); 423 Section a = new Section(0, 10, "x", x, p, null, null, null); 424 new Section(1, 10, "y", x, p, null, null, null); 425 sections.add(a); 426 a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 427 a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 428 cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 429 cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment)); 430 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 431 w[i] = pw.getWeight(assignment, e, null, null); 432 } 433 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 434 } 435 436 System.out.println("Same choice sections:"); 437 pw.iMPP = true; 438 for (Request r: s.getRequests()) { 439 CourseRequest cr = (CourseRequest)r; 440 double[] w = new double[] {0.0, 0.0, 0.0}; 441 for (int i = 0; i < cr.getCourses().size(); i++) { 442 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 443 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 444 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 445 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 446 Set<SctAssignment> other = new HashSet<SctAssignment>(); 447 other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 448 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 449 w[i] = pw.getWeight(assignment, e, null, null); 450 } 451 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 452 } 453 454 System.out.println("Same time sections:"); 455 for (Request r: s.getRequests()) { 456 CourseRequest cr = (CourseRequest)r; 457 double[] w = new double[] {0.0, 0.0, 0.0}; 458 for (int i = 0; i < cr.getCourses().size(); i++) { 459 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 460 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 461 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 462 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 463 Set<SctAssignment> other = new HashSet<SctAssignment>(); 464 other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, "1", "Josef Novak", null)); 465 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 466 w[i] = pw.getWeight(assignment, e, null, null); 467 } 468 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 469 } 470 471 System.out.println("Different time sections:"); 472 Placement q = new Placement(null, new TimeLocation(1, 102, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>()); 473 for (Request r: s.getRequests()) { 474 CourseRequest cr = (CourseRequest)r; 475 double[] w = new double[] {0.0, 0.0, 0.0}; 476 for (int i = 0; i < cr.getCourses().size(); i++) { 477 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 478 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 479 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 480 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 481 Set<SctAssignment> other = new HashSet<SctAssignment>(); 482 other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), q, null, null, null)); 483 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 484 w[i] = pw.getWeight(assignment, e, null, null); 485 } 486 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 487 } 488 489 System.out.println("Two sections, one same choice, one same time:"); 490 for (Request r: s.getRequests()) { 491 CourseRequest cr = (CourseRequest)r; 492 double[] w = new double[] {0.0, 0.0, 0.0}; 493 for (int i = 0; i < cr.getCourses().size(); i++) { 494 Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering()); 495 Set<SctAssignment> sections = new HashSet<SctAssignment>(); 496 sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 497 sections.add(new Section(1, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null, null, null)); 498 Enrollment e = new Enrollment(cr, i, cfg, sections, assignment); 499 Set<SctAssignment> other = new HashSet<SctAssignment>(); 500 other.add(new Section(2, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, null, null)); 501 other.add(new Section(3, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, "1", "Josef Novak", null)); 502 cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment)); 503 w[i] = pw.getWeight(assignment, e, null, null); 504 } 505 System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2])); 506 } 507 508 } 509}