use of org.cpsolver.studentsct.model.Subpart in project cpsolver by UniTime.
the class PriorityStudentWeights method getWeightMultiplicative.
public double getWeightMultiplicative(Assignment<Request, Enrollment> assignment, Enrollment enrollment) {
double weight = getBaseWeight(assignment, enrollment);
if (enrollment.isCourseRequest() && iNoTimeFactor != 0.0) {
int noTimeSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (!section.hasTime())
noTimeSections++;
total++;
}
if (noTimeSections > 0)
weight *= (1.0 - iNoTimeFactor * noTimeSections / total);
}
if (enrollment.isCourseRequest() && iOnlineFactor != 0.0) {
int onlineSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (section.isOnline())
onlineSections++;
total++;
}
if (onlineSections > 0)
weight *= (1.0 - iOnlineFactor * onlineSections / total);
}
if (enrollment.isCourseRequest() && iPastFactor != 0.0) {
int pastSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (section.isPast())
pastSections++;
total++;
}
if (pastSections > 0)
weight *= (1.0 - iPastFactor * pastSections / total);
}
if (enrollment.getTruePriority() < enrollment.getPriority()) {
weight *= (1.0 - iReservationNotFollowedFactor);
}
if (enrollment.isCourseRequest() && iBalancingFactor != 0.0) {
double configUsed = enrollment.getConfig().getEnrollmentTotalWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight();
double disbalanced = 0;
double total = 0;
for (Section section : enrollment.getSections()) {
Subpart subpart = section.getSubpart();
if (subpart.getSections().size() <= 1)
continue;
double used = section.getEnrollmentTotalWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight();
// sections have limits -> desired size is section limit x (total enrollment / total limit)
// unlimited sections -> desired size is total enrollment / number of sections
double desired = (subpart.getLimit() > 0 ? section.getLimit() * (configUsed / subpart.getLimit()) : configUsed / subpart.getSections().size());
if (used > desired)
disbalanced += Math.min(enrollment.getRequest().getWeight(), used - desired) / enrollment.getRequest().getWeight();
else
disbalanced -= Math.min(enrollment.getRequest().getWeight(), desired - used) / enrollment.getRequest().getWeight();
total++;
}
if (disbalanced > 0)
weight *= (1.0 - disbalanced / total * iBalancingFactor);
}
if (iMPP) {
double difference = getDifference(enrollment);
if (difference > 0.0)
weight *= (1.0 - difference * iPerturbationFactor);
}
if (iSelectionFactor != 0.0) {
double selection = getSelection(enrollment);
if (selection > 0.0)
weight *= (1.0 - selection * iSelectionFactor);
}
if (enrollment.isCourseRequest() && iGroupFactor != 0.0) {
double sameGroup = 0.0;
int groupCount = 0;
for (RequestGroup g : ((CourseRequest) enrollment.getRequest()).getRequestGroups()) {
if (g.getCourse().equals(enrollment.getCourse())) {
sameGroup += g.getEnrollmentSpread(assignment, enrollment, iGroupBestRatio, iGroupFillRatio);
groupCount++;
}
}
if (groupCount > 0) {
double difference = 1.0 - sameGroup / groupCount;
weight *= (1.0 - difference * iGroupFactor);
}
}
return round(weight);
}
use of org.cpsolver.studentsct.model.Subpart in project cpsolver by UniTime.
the class PriorityStudentWeights method getWeightAdditive.
public double getWeightAdditive(Assignment<Request, Enrollment> assignment, Enrollment enrollment) {
double base = getBaseWeight(assignment, enrollment);
double weight = 0.0;
if (enrollment.isCourseRequest() && iNoTimeFactor != 0.0) {
int noTimeSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (!section.hasTime())
noTimeSections++;
total++;
}
if (noTimeSections > 0)
weight += iNoTimeFactor * noTimeSections / total;
}
if (enrollment.isCourseRequest() && iOnlineFactor != 0.0) {
int onlineSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (section.isOnline())
onlineSections++;
total++;
}
if (onlineSections > 0)
weight += iOnlineFactor * onlineSections / total;
}
if (enrollment.isCourseRequest() && iPastFactor != 0.0) {
int pastSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (section.isPast())
pastSections++;
total++;
}
if (pastSections > 0)
weight += iPastFactor * pastSections / total;
}
if (enrollment.getTruePriority() < enrollment.getPriority()) {
weight += iReservationNotFollowedFactor;
}
if (enrollment.isCourseRequest() && iBalancingFactor != 0.0) {
double configUsed = enrollment.getConfig().getEnrollmentTotalWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight();
double disbalanced = 0;
double total = 0;
for (Section section : enrollment.getSections()) {
Subpart subpart = section.getSubpart();
if (subpart.getSections().size() <= 1)
continue;
double used = section.getEnrollmentTotalWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight();
// sections have limits -> desired size is section limit x (total enrollment / total limit)
// unlimited sections -> desired size is total enrollment / number of sections
double desired = (subpart.getLimit() > 0 ? section.getLimit() * (configUsed / subpart.getLimit()) : configUsed / subpart.getSections().size());
if (used > desired)
disbalanced += Math.min(enrollment.getRequest().getWeight(), used - desired) / enrollment.getRequest().getWeight();
else
disbalanced -= Math.min(enrollment.getRequest().getWeight(), desired - used) / enrollment.getRequest().getWeight();
total++;
}
if (disbalanced > 0)
weight += disbalanced / total * iBalancingFactor;
}
if (iMPP) {
double difference = getDifference(enrollment);
if (difference > 0.0)
weight += difference * iPerturbationFactor;
}
if (iSelectionFactor != 0.0) {
double selection = getSelection(enrollment);
if (selection > 0.0)
weight += selection * iSelectionFactor;
}
if (enrollment.isCourseRequest() && iGroupFactor != 0.0) {
double sameGroup = 0.0;
int groupCount = 0;
for (RequestGroup g : ((CourseRequest) enrollment.getRequest()).getRequestGroups()) {
if (g.getCourse().equals(enrollment.getCourse())) {
sameGroup += g.getEnrollmentSpread(assignment, enrollment, iGroupBestRatio, iGroupFillRatio);
groupCount++;
}
}
if (groupCount > 0) {
double difference = 1.0 - sameGroup / groupCount;
weight += difference * iGroupFactor;
}
}
return round(base * (1.0 - weight));
}
use of org.cpsolver.studentsct.model.Subpart in project cpsolver by UniTime.
the class RequestGroupTable method create.
@Override
public CSVFile create(Assignment<Request, Enrollment> assignment, DataProperties properties) {
boolean useAmPm = properties.getPropertyBoolean("useAmPm", true);
CSVFile csv = new CSVFile();
csv.setHeader(new CSVFile.CSVField[] { new CSVFile.CSVField("Group"), new CSVFile.CSVField("Course"), new CSVFile.CSVField("Total\nSpread"), new CSVFile.CSVField("Group\nEnrollment"), new CSVFile.CSVField("Class"), new CSVFile.CSVField("Meeting Time"), new CSVFile.CSVField("Class\nSpread"), new CSVFile.CSVField("Class\nEnrollment"), new CSVFile.CSVField("Class\nLimit") });
TreeSet<RequestGroup> groups = new TreeSet<RequestGroup>(new Comparator<RequestGroup>() {
@Override
public int compare(RequestGroup g1, RequestGroup g2) {
int cmp = g1.getName().compareTo(g2.getName());
if (cmp != 0)
return cmp;
cmp = g1.getCourse().getName().compareTo(g2.getCourse().getName());
if (cmp != 0)
return cmp;
if (g1.getId() < g2.getId())
return -1;
if (g1.getId() > g2.getId())
return 1;
return (g1.getCourse().getId() < g2.getCourse().getId() ? -1 : g1.getCourse().getId() > g2.getCourse().getId() ? 1 : 0);
}
});
for (Offering offering : iModel.getOfferings()) for (Course course : offering.getCourses()) groups.addAll(course.getRequestGroups());
for (RequestGroup group : groups) {
double groupEnrollment = group.getEnrollmentWeight(assignment, null);
double groupSpread = group.getAverageSpread(assignment);
for (Config config : group.getCourse().getOffering().getConfigs()) for (Subpart subpart : config.getSubparts()) for (Section section : subpart.getSections()) {
double s = group.getSectionWeight(assignment, section, null);
if (s > 0.00001) {
csv.addLine(new CSVFile.CSVField[] { new CSVFile.CSVField(group.getName()), new CSVFile.CSVField(group.getCourse().getName()), new CSVFile.CSVField(sDF.format(100.0 * groupSpread)), new CSVFile.CSVField(Math.round(groupEnrollment)), new CSVFile.CSVField(section.getSubpart().getName() + " " + section.getName(group.getCourse().getId())), new CSVFile.CSVField(section.getTime() == null ? "" : section.getTime().getDayHeader() + " " + section.getTime().getStartTimeHeader(useAmPm) + " - " + section.getTime().getEndTimeHeader(useAmPm)), new CSVFile.CSVField(sDF.format(100.0 * group.getSectionSpread(assignment, section))), new CSVFile.CSVField(Math.round(group.getSectionWeight(assignment, section, null))), new CSVFile.CSVField(section.getLimit()) });
}
}
}
return csv;
}
use of org.cpsolver.studentsct.model.Subpart in project cpsolver by UniTime.
the class Reservation method getLimitCapNoCache.
/**
* Compute limit cap (maximum number of students that can get into the offering using this reservation)
*/
private double getLimitCapNoCache() {
// no config -> can be unlimited
if (getConfigs().isEmpty())
return -1;
// can assign over limit -> no cap
if (canAssignOverLimit())
return -1;
double cap = 0;
if (areRestrictionsInclusive()) {
// for each config
for (Config config : getConfigs()) {
// config cap
double configCap = config.getLimit();
for (Map.Entry<Subpart, Set<Section>> entry : getSections().entrySet()) {
if (!config.equals(entry.getKey().getConfig()))
continue;
Set<Section> sections = entry.getValue();
// subpart cap
double subpartCap = 0;
for (Section section : sections) subpartCap = add(subpartCap, section.getLimit());
// minimize
configCap = min(configCap, subpartCap);
}
// add config cap
cap = add(cap, configCap);
}
} else {
// for each config
for (Config config : getConfigs()) cap = add(cap, config.getLimit());
// for each subpart
for (Map.Entry<Subpart, Set<Section>> entry : getSections().entrySet()) {
Set<Section> sections = entry.getValue();
// subpart cap
double subpartCap = 0;
for (Section section : sections) subpartCap = add(subpartCap, section.getLimit());
cap = add(cap, subpartCap);
}
}
return cap;
}
use of org.cpsolver.studentsct.model.Subpart in project cpsolver by UniTime.
the class OriginalStudentWeights method main.
/**
* Test case -- run to see the weights for a few courses
* @param args program arguments
*/
public static void main(String[] args) {
OriginalStudentWeights pw = new OriginalStudentWeights(new DataProperties());
DecimalFormat df = new DecimalFormat("0.000");
Student s = new Student(0l);
new CourseRequest(1l, 0, false, s, ToolBox.toList(new Course(1, "A", "1", new Offering(0, "A")), new Course(1, "A", "2", new Offering(0, "A")), new Course(1, "A", "3", new Offering(0, "A"))), false, null);
new CourseRequest(2l, 1, false, s, ToolBox.toList(new Course(1, "B", "1", new Offering(0, "B")), new Course(1, "B", "2", new Offering(0, "B")), new Course(1, "B", "3", new Offering(0, "B"))), false, null);
new CourseRequest(3l, 2, false, s, ToolBox.toList(new Course(1, "C", "1", new Offering(0, "C")), new Course(1, "C", "2", new Offering(0, "C")), new Course(1, "C", "3", new Offering(0, "C"))), false, null);
new CourseRequest(4l, 3, false, s, ToolBox.toList(new Course(1, "D", "1", new Offering(0, "D")), new Course(1, "D", "2", new Offering(0, "D")), new Course(1, "D", "3", new Offering(0, "D"))), false, null);
new CourseRequest(5l, 4, false, s, ToolBox.toList(new Course(1, "E", "1", new Offering(0, "E")), new Course(1, "E", "2", new Offering(0, "E")), new Course(1, "E", "3", new Offering(0, "E"))), false, null);
new CourseRequest(6l, 5, true, s, ToolBox.toList(new Course(1, "F", "1", new Offering(0, "F")), new Course(1, "F", "2", new Offering(0, "F")), new Course(1, "F", "3", new Offering(0, "F"))), false, null);
new CourseRequest(7l, 6, true, s, ToolBox.toList(new Course(1, "G", "1", new Offering(0, "G")), new Course(1, "G", "2", new Offering(0, "G")), new Course(1, "G", "3", new Offering(0, "G"))), false, null);
Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
Placement p = new Placement(null, new TimeLocation(1, 90, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>());
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With one distance conflict:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>();
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, (Section) sections.iterator().next()));
w[i] = pw.getWeight(assignment, e, dc, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With two distance conflicts:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>();
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, (Section) sections.iterator().next()));
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)));
w[i] = pw.getWeight(assignment, e, dc, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With 25% time overlapping conflicts:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<TimeOverlapsCounter.Conflict> toc = new HashSet<TimeOverlapsCounter.Conflict>();
toc.add(new TimeOverlapsCounter.Conflict(s, 3, e, sections.iterator().next(), e, sections.iterator().next()));
w[i] = pw.getWeight(assignment, e, null, toc);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
}
Aggregations