Skip to content

Commit

Permalink
Batch Student Sectioning Solver
Browse files Browse the repository at this point in the history
 - section / config unreserved space in limit constraints: use the same technique to overcome rounding problems as for the section / config limit
   - that is adding a little less than the biggest request weight (of the section / config) to the unreserved space

git-svn-id: http://cpsolver.googlecode.com/svn/trunk@545 e5151b7e-cabb-5534-7ab8-ba89a8838d1f
  • Loading branch information
muller@unitime.org committed May 24, 2011
1 parent b202406 commit 0eb7de7
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 21 deletions.
39 changes: 30 additions & 9 deletions src/net/sf/cpsolver/studentsct/constraint/ReservationLimit.java
Expand Up @@ -59,6 +59,7 @@
* <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
*/ */
public class ReservationLimit extends GlobalConstraint<Request, Enrollment> { public class ReservationLimit extends GlobalConstraint<Request, Enrollment> {
private static double sNominalWeight = 0.00001;
private boolean iPreferDummyStudents = false; private boolean iPreferDummyStudents = false;


/** /**
Expand All @@ -72,6 +73,26 @@ public ReservationLimit(DataProperties cfg) {
iPreferDummyStudents = cfg.getPropertyBoolean("ReservationLimit.PreferDummyStudents", false); iPreferDummyStudents = cfg.getPropertyBoolean("ReservationLimit.PreferDummyStudents", false);
} }



/**
* Remaining unreserved space in a config if the given request is assigned. In order
* to overcome rounding problems with last-like students ( e.g., 5 students
* are projected to two sections of limit 2 -- each section can have up to 3
* of these last-like students), the weight of the request with the highest
* weight in the section is changed to a small nominal weight.
*
* @param config
* a config that is of concern
* @param request
* a request of a student to be assigned containing the given
* section
* @return config's new unreserved space
*/
public static double getUnreservedSpace(Config config, Request request) {
return config.getUnreservedSpace(request) - request.getWeight()
+ Math.max(config.getMaxEnrollmentWeight(), request.getWeight()) - sNominalWeight;
}



/** /**
* A given enrollment is conflicting, if the reservation's remaning available space * A given enrollment is conflicting, if the reservation's remaning available space
Expand Down Expand Up @@ -180,9 +201,9 @@ public void computeConflicts(Enrollment enrollment, Set<Enrollment> conflicts) {
return; return;
} }


double unreserved = config.getUnreservedSpace(enrollment.getRequest()); double unreserved = getUnreservedSpace(config, enrollment.getRequest());


if (unreserved < enrollment.getRequest().getWeight()) { if (unreserved < 0.0) {
// no unreserved space available -> cannot be assigned // no unreserved space available -> cannot be assigned
// try to unassign some other enrollments that also do not have config reservation // try to unassign some other enrollments that also do not have config reservation


Expand All @@ -198,7 +219,7 @@ public void computeConflicts(Enrollment enrollment, Set<Enrollment> conflicts) {
adepts.add(e); adepts.add(e);
} }


while (unreserved < enrollment.getRequest().getWeight()) { while (unreserved < 0.0) {
if (adepts.isEmpty()) { if (adepts.isEmpty()) {
// no adepts -> enrollment cannot be assigned // no adepts -> enrollment cannot be assigned
conflicts.add(enrollment); conflicts.add(enrollment);
Expand Down Expand Up @@ -252,10 +273,10 @@ public void computeConflicts(Enrollment enrollment, Set<Enrollment> conflicts) {


// check configuration unavailable space too // check configuration unavailable space too
double unreserved = Math.min( double unreserved = Math.min(
config.getOffering().getUnreservedSpace(enrollment.getRequest()), config.getOffering().getUnreservedSpace(enrollment.getRequest()) - enrollment.getRequest().getWeight(),
config.getUnreservedSpace(enrollment.getRequest())); getUnreservedSpace(config, enrollment.getRequest()));


if (unreserved < enrollment.getRequest().getWeight()) { if (unreserved < 0.0) {
// no unreserved space available -> cannot be assigned // no unreserved space available -> cannot be assigned
// try to unassign some other enrollments that also do not have reservation // try to unassign some other enrollments that also do not have reservation


Expand All @@ -271,7 +292,7 @@ public void computeConflicts(Enrollment enrollment, Set<Enrollment> conflicts) {
adepts.add(e); adepts.add(e);
} }


while (unreserved < enrollment.getRequest().getWeight()) { while (unreserved < 0.0) {
if (adepts.isEmpty()) { if (adepts.isEmpty()) {
// no adepts -> enrollment cannot be assigned // no adepts -> enrollment cannot be assigned
conflicts.add(enrollment); conflicts.add(enrollment);
Expand Down Expand Up @@ -364,12 +385,12 @@ public boolean inConflict(Enrollment enrollment) {


// if not configuration reservation, check configuration unreserved space too // if not configuration reservation, check configuration unreserved space too
return (!hasConfigReservation(enrollment) && return (!hasConfigReservation(enrollment) &&
config.getUnreservedSpace(enrollment.getRequest()) < enrollment.getRequest().getWeight()); getUnreservedSpace(config, enrollment.getRequest()) < 0.0);
} else { } else {
// check unreserved space; // check unreserved space;
return config.getOffering().getTotalUnreservedSpace() < enrollment.getRequest().getWeight() || return config.getOffering().getTotalUnreservedSpace() < enrollment.getRequest().getWeight() ||
config.getTotalUnreservedSpace() < enrollment.getRequest().getWeight() || config.getTotalUnreservedSpace() < enrollment.getRequest().getWeight() ||
config.getUnreservedSpace(enrollment.getRequest()) < enrollment.getRequest().getWeight() || getUnreservedSpace(config, enrollment.getRequest()) < 0.0 ||
config.getOffering().getUnreservedSpace(enrollment.getRequest()) < enrollment.getRequest().getWeight(); config.getOffering().getUnreservedSpace(enrollment.getRequest()) < enrollment.getRequest().getWeight();
} }
} }
Expand Down
44 changes: 32 additions & 12 deletions src/net/sf/cpsolver/studentsct/constraint/SectionLimit.java
Expand Up @@ -100,6 +100,26 @@ public static double getEnrollmentWeight(Section section, Request request) {
- Math.max(section.getMaxEnrollmentWeight(), request.getWeight()) + sNominalWeight; - Math.max(section.getMaxEnrollmentWeight(), request.getWeight()) + sNominalWeight;
} }


/**
* Remaining unreserved space in a section if the given request is assigned. In order
* to overcome rounding problems with last-like students ( e.g., 5 students
* are projected to two sections of limit 2 -- each section can have up to 3
* of these last-like students), the weight of the request with the highest
* weight in the section is changed to a small nominal weight.
*
* @param section
* a section that is of concern
* @param request
* a request of a student to be assigned containing the given
* section
* @return section's new unreserved space
*/
public static double getUnreservedSpace(Section section, Request request) {
return section.getUnreservedSpace(request) - request.getWeight()
+ Math.max(section.getMaxEnrollmentWeight(), request.getWeight()) - sNominalWeight;
}


/** /**
* True if the enrollment has reservation for this section. * True if the enrollment has reservation for this section.
* Everything else is checked in the {@link ReservationLimit} constraint. * Everything else is checked in the {@link ReservationLimit} constraint.
Expand Down Expand Up @@ -137,18 +157,18 @@ public void computeConflicts(Enrollment enrollment, Set<Enrollment> conflicts) {


// for each section // for each section
for (Section section : enrollment.getSections()) { for (Section section : enrollment.getSections()) {

// no reservation -- check the space in the unreserved space in the section // no reservation -- check the space in the unreserved space in the section
if (!hasSectionReservation(enrollment, section)) { if (enrollment.getConfig().getOffering().hasReservations() && !hasSectionReservation(enrollment, section)) {
// section is fully reserved by section reservations // section is fully reserved by section reservations
if (section.getTotalUnreservedSpace() < enrollment.getRequest().getWeight()) { if (section.getTotalUnreservedSpace() < enrollment.getRequest().getWeight()) {
conflicts.add(enrollment); conflicts.add(enrollment);
return; return;
} }


double unreserved = section.getUnreservedSpace(enrollment.getRequest()); double unreserved = getUnreservedSpace(section, enrollment.getRequest());


if (unreserved < enrollment.getRequest().getWeight()) { if (unreserved < 0.0) {
// no unreserved space available -> cannot be assigned // no unreserved space available -> cannot be assigned
// try to unassign some other enrollments that also do not have reservation // try to unassign some other enrollments that also do not have reservation


Expand All @@ -164,7 +184,7 @@ public void computeConflicts(Enrollment enrollment, Set<Enrollment> conflicts) {
adepts.add(e); adepts.add(e);
} }


while (unreserved < enrollment.getRequest().getWeight()) { while (unreserved < 0.0) {
if (adepts.isEmpty()) { if (adepts.isEmpty()) {
// no adepts -> enrollment cannot be assigned // no adepts -> enrollment cannot be assigned
conflicts.add(enrollment); conflicts.add(enrollment);
Expand Down Expand Up @@ -206,7 +226,6 @@ public void computeConflicts(Enrollment enrollment, Set<Enrollment> conflicts) {
conflicts.add(conflict); conflicts.add(conflict);
} }
} }

} }


// unlimited section // unlimited section
Expand Down Expand Up @@ -317,16 +336,17 @@ public boolean inConflict(Enrollment enrollment) {
// for each section // for each section
for (Section section : enrollment.getSections()) { for (Section section : enrollment.getSections()) {


// unlimited section
if (section.getLimit() < 0)
continue;

// not have reservation -> check unreserved space // not have reservation -> check unreserved space
if (!hasSectionReservation(enrollment, section) && ( if (enrollment.getConfig().getOffering().hasReservations() &&
!hasSectionReservation(enrollment, section) && (
section.getTotalUnreservedSpace() < enrollment.getRequest().getWeight() || section.getTotalUnreservedSpace() < enrollment.getRequest().getWeight() ||
section.getUnreservedSpace(enrollment.getRequest()) < enrollment.getRequest().getWeight())) getUnreservedSpace(section, enrollment.getRequest()) < 0.0))
return true; return true;


// unlimited section
if (section.getLimit() < 0)
continue;

// new enrollment weight // new enrollment weight
double enrlWeight = getEnrollmentWeight(section, enrollment.getRequest()); double enrlWeight = getEnrollmentWeight(section, enrollment.getRequest());


Expand Down

0 comments on commit 0eb7de7

Please sign in to comment.