Skip to content

Commit

Permalink
Student Scheduling Solver: Priority Students
Browse files Browse the repository at this point in the history
- use the setting of Sectioning.PriorityStudentsFirstSelection.AllIn when comparting two requests for student and request priority

- when Sectioning.PriorityStudentsFirstSelection.AllIn is set to true
  - request of a priority student is always considered more important
    e.g., do not assign a critical request of non-priority student when it conflicts with a non-critical request of a priority student
    (priority student takes precedence over non-priority)

- when Sectioning.PriorityStudentsFirstSelection.AllIn is set to false
  - more critical request is always connsidered more important (using request priority)
    e.g., do not assign a non-critical request of a priority student when it conflicts with a critical request of a non-priority students
    (critical request takes precedence over non-critical)
  • Loading branch information
tomas-muller committed Jun 25, 2020
1 parent ed79895 commit afea8ee
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 28 deletions.
57 changes: 40 additions & 17 deletions src/org/cpsolver/studentsct/constraint/ConfigLimit.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class ConfigLimit extends GlobalConstraint<Request, Enrollment> {

private static double sNominalWeight = 0.00001;
private boolean iPreferDummyStudents = false;
private boolean iPreferPriorityStudents = true;

/**
* Constructor
Expand All @@ -77,6 +78,7 @@ public class ConfigLimit extends GlobalConstraint<Request, Enrollment> {
public ConfigLimit(DataProperties cfg) {
super();
iPreferDummyStudents = cfg.getPropertyBoolean("ConfigLimit.PreferDummyStudents", false);
iPreferPriorityStudents = cfg.getPropertyBoolean("Sectioning.PriorityStudentsFirstSelection.AllIn", true);
}


Expand Down Expand Up @@ -165,7 +167,7 @@ public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollm

// pick adept (prefer dummy students & students w/o reservation), decrease enrollment
// weight, make conflict
Enrollment conflict = new Adepts(iPreferDummyStudents, adepts, assignment).get();
Enrollment conflict = new Adepts(iPreferDummyStudents, iPreferPriorityStudents, adepts, assignment).get();
adepts.remove(conflict);
enrlWeight -= conflict.getRequest().getWeight();
conflicts.add(conflict);
Expand Down Expand Up @@ -225,19 +227,23 @@ static class Adepts {
private RequestPriority iRequestPriority;
private boolean iReservation;
private boolean iConsiderDummy;
private boolean iPriorityFirst;

public Adepts(boolean preferDummy) {
public Adepts(boolean preferDummy, boolean priorityFirst) {
iConsiderDummy = preferDummy;
iPriorityFirst = priorityFirst;
iEnrollments = new ArrayList<Enrollment>();
}

public Adepts(boolean preferDummy, int size) {
public Adepts(boolean preferDummy, boolean priorityFirst, int size) {
iConsiderDummy = preferDummy;
iPriorityFirst = priorityFirst;
iEnrollments = new ArrayList<Enrollment>(size);
}

public Adepts(boolean preferDummy, Collection<Enrollment> adepts, Assignment<Request, Enrollment> assignment) {
public Adepts(boolean preferDummy, boolean priorityFirst, Collection<Enrollment> adepts, Assignment<Request, Enrollment> assignment) {
iConsiderDummy = preferDummy;
iPriorityFirst = priorityFirst;
iEnrollments = new ArrayList<Enrollment>(adepts.size());
for (Enrollment adept: adepts)
add(adept, assignment);
Expand All @@ -261,19 +267,36 @@ public void add(Enrollment enrollment, Assignment<Request, Enrollment> assignmen
iEnrollments.add(enrollment);
return;
}
if (iPriority != priority) { // different priority
if (priority) return; // ignore priority students
iEnrollments.clear();
iValue = value; iDummy = dummy; iPriority = priority; iRequestPriority = rp; iReservation = reservation;
iEnrollments.add(enrollment);
return;
}
if (iRequestPriority != rp) { // different request priority
if (rp.ordinal() < iRequestPriority.ordinal()) return; // ignore more critical courses
iEnrollments.clear();
iValue = value; iDummy = dummy; iPriority = priority; iRequestPriority = rp; iReservation = reservation;
iEnrollments.add(enrollment);
return;
if (iPriorityFirst) {
if (iPriority != priority) { // different priority
if (priority) return; // ignore priority students
iEnrollments.clear();
iValue = value; iDummy = dummy; iPriority = priority; iRequestPriority = rp; iReservation = reservation;
iEnrollments.add(enrollment);
return;
}
if (iRequestPriority != rp) { // different request priority
if (rp.ordinal() < iRequestPriority.ordinal()) return; // ignore more critical courses
iEnrollments.clear();
iValue = value; iDummy = dummy; iPriority = priority; iRequestPriority = rp; iReservation = reservation;
iEnrollments.add(enrollment);
return;
}
} else {
if (iRequestPriority != rp) { // different request priority
if (rp.ordinal() < iRequestPriority.ordinal()) return; // ignore more critical courses
iEnrollments.clear();
iValue = value; iDummy = dummy; iPriority = priority; iRequestPriority = rp; iReservation = reservation;
iEnrollments.add(enrollment);
return;
}
if (iPriority != priority) { // different priority
if (priority) return; // ignore priority students
iEnrollments.clear();
iValue = value; iDummy = dummy; iPriority = priority; iRequestPriority = rp; iReservation = reservation;
iEnrollments.add(enrollment);
return;
}
}
if (iReservation != reservation) { // different reservation
if (reservation) return; // ignore students with reservation
Expand Down
4 changes: 3 additions & 1 deletion src/org/cpsolver/studentsct/constraint/CourseLimit.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
public class CourseLimit extends GlobalConstraint<Request, Enrollment> {
private static double sNominalWeight = 0.00001;
private boolean iPreferDummyStudents = false;
private boolean iPreferPriorityStudents = true;

/**
* Constructor
Expand All @@ -75,6 +76,7 @@ public class CourseLimit extends GlobalConstraint<Request, Enrollment> {
public CourseLimit(DataProperties cfg) {
super();
iPreferDummyStudents = cfg.getPropertyBoolean("CourseLimit.PreferDummyStudents", false);
iPreferPriorityStudents = cfg.getPropertyBoolean("Sectioning.PriorityStudentsFirstSelection.AllIn", true);
}


Expand Down Expand Up @@ -163,7 +165,7 @@ public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollm

// pick adept (prefer dummy students), decrease unreserved space,
// make conflict
Enrollment conflict = new Adepts(iPreferDummyStudents, adepts, assignment).get();
Enrollment conflict = new Adepts(iPreferDummyStudents, iPreferPriorityStudents, adepts, assignment).get();
adepts.remove(conflict);
enrlWeight -= conflict.getRequest().getWeight();
conflicts.add(conflict);
Expand Down
9 changes: 5 additions & 4 deletions src/org/cpsolver/studentsct/constraint/ReservationLimit.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.cpsolver.ifs.assignment.Assignment;
import org.cpsolver.ifs.model.GlobalConstraint;
import org.cpsolver.ifs.util.DataProperties;
import org.cpsolver.ifs.util.ToolBox;
import org.cpsolver.studentsct.constraint.ConfigLimit.Adepts;
import org.cpsolver.studentsct.model.Config;
import org.cpsolver.studentsct.model.Enrollment;
Expand Down Expand Up @@ -63,6 +62,7 @@
public class ReservationLimit extends GlobalConstraint<Request, Enrollment> {
private static double sNominalWeight = 0.00001;
private boolean iPreferDummyStudents = false;
private boolean iPreferPriorityStudents = true;

/**
* Constructor
Expand All @@ -73,6 +73,7 @@ public class ReservationLimit extends GlobalConstraint<Request, Enrollment> {
public ReservationLimit(DataProperties cfg) {
super();
iPreferDummyStudents = cfg.getPropertyBoolean("ReservationLimit.PreferDummyStudents", false);
iPreferPriorityStudents = cfg.getPropertyBoolean("Sectioning.PriorityStudentsFirstSelection.AllIn", true);
}


Expand Down Expand Up @@ -166,7 +167,7 @@ public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollm

// pick adept (prefer dummy students), decrease unreserved space,
// make conflict
Enrollment conflict = new Adepts(iPreferDummyStudents, adepts, assignment).get();
Enrollment conflict = new Adepts(iPreferDummyStudents, iPreferPriorityStudents, adepts, assignment).get();
adepts.remove(conflict);
reserved += conflict.getRequest().getWeight();
conflicts.add(conflict);
Expand Down Expand Up @@ -213,7 +214,7 @@ public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollm

// pick adept (prefer dummy students), decrease unreserved space,
// make conflict
Enrollment conflict = new Adepts(iPreferDummyStudents, adepts, assignment).get();
Enrollment conflict = new Adepts(iPreferDummyStudents, iPreferPriorityStudents, adepts, assignment).get();
adepts.remove(conflict);
unreserved += conflict.getRequest().getWeight();
conflicts.add(conflict);
Expand Down Expand Up @@ -257,7 +258,7 @@ public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollm

// pick adept (prefer dummy students), decrease unreserved space,
// make conflict
Enrollment conflict = new Adepts(iPreferDummyStudents, adepts, assignment).get();
Enrollment conflict = new Adepts(iPreferDummyStudents, iPreferPriorityStudents, adepts, assignment).get();
adepts.remove(conflict);
unreserved += conflict.getRequest().getWeight();
conflicts.add(conflict);
Expand Down
7 changes: 4 additions & 3 deletions src/org/cpsolver/studentsct/constraint/SectionLimit.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.cpsolver.ifs.assignment.Assignment;
import org.cpsolver.ifs.model.GlobalConstraint;
import org.cpsolver.ifs.util.DataProperties;
import org.cpsolver.ifs.util.ToolBox;
import org.cpsolver.studentsct.constraint.ConfigLimit.Adepts;
import org.cpsolver.studentsct.model.Enrollment;
import org.cpsolver.studentsct.model.Request;
Expand Down Expand Up @@ -71,6 +70,7 @@
public class SectionLimit extends GlobalConstraint<Request, Enrollment> {
private static double sNominalWeight = 0.00001;
private boolean iPreferDummyStudents = false;
private boolean iPreferPriorityStudents = true;

/**
* Constructor
Expand All @@ -81,6 +81,7 @@ public class SectionLimit extends GlobalConstraint<Request, Enrollment> {
public SectionLimit(DataProperties cfg) {
super();
iPreferDummyStudents = cfg.getPropertyBoolean("SectionLimit.PreferDummyStudents", false);
iPreferPriorityStudents = cfg.getPropertyBoolean("Sectioning.PriorityStudentsFirstSelection.AllIn", true);
}

/**
Expand Down Expand Up @@ -196,7 +197,7 @@ public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollm

// pick adept (prefer dummy students), decrease unreserved space,
// make conflict
Enrollment conflict = new Adepts(iPreferDummyStudents, adepts, assignment).get();
Enrollment conflict = new Adepts(iPreferDummyStudents, iPreferPriorityStudents, adepts, assignment).get();
adepts.remove(conflict);
unreserved += conflict.getRequest().getWeight();
conflicts.add(conflict);
Expand Down Expand Up @@ -237,7 +238,7 @@ public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollm

// pick adept (prefer dummy students & students w/o reservation), decrease enrollment
// weight, make conflict
Enrollment conflict = new Adepts(iPreferDummyStudents, adepts, assignment).get();
Enrollment conflict = new Adepts(iPreferDummyStudents, iPreferPriorityStudents, adepts, assignment).get();
adepts.remove(conflict);
enrlWeight -= conflict.getRequest().getWeight();
conflicts.add(conflict);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
*/
public class RandomizedBacktrackNeighbourSelection extends BacktrackNeighbourSelection<Request, Enrollment> {
private int iMaxValues = 100;
private boolean iPreferPriorityStudents = true;

/**
* Constructor
Expand All @@ -74,6 +75,7 @@ public class RandomizedBacktrackNeighbourSelection extends BacktrackNeighbourSel
public RandomizedBacktrackNeighbourSelection(DataProperties properties) throws Exception {
super(properties);
iMaxValues = properties.getPropertyInt("Neighbour.MaxValues", iMaxValues);
iPreferPriorityStudents = properties.getPropertyBoolean("Sectioning.PriorityStudentsFirstSelection.AllIn", true);
}

/**
Expand Down Expand Up @@ -130,8 +132,10 @@ public boolean canUnassign(Enrollment enrollment, Enrollment conflict, Assignmen
float credit = conflict.getRequest().getStudent().getAssignedCredit(assignment) - conflict.getCredit();
if (credit < conflict.getRequest().getStudent().getMinCredit()) return false;
}
if (!enrollment.getStudent().isPriority() && conflict.getStudent().isPriority()) return false;
if (!conflict.getRequest().isAlternative() && conflict.getRequest().getRequestPriority().isHigher(enrollment.getRequest())) return false;
if (iPreferPriorityStudents || conflict.getRequest().getRequestPriority().isSame(enrollment.getRequest())) {
if (!enrollment.getStudent().isPriority() && conflict.getStudent().isPriority()) return false;
}
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public class StandardSelection implements NeighbourSelection<Request, Enrollment
private ValueSelection<Request, Enrollment> iValueSelection = null;
private VariableSelection<Request, Enrollment> iVariableSelection = null;
protected long iNrIterations = -1;
private boolean iPreferPriorityStudents = true;

/**
* Constructor (variable and value selection are expected to be already
Expand All @@ -81,6 +82,7 @@ public StandardSelection(DataProperties properties, VariableSelection<Request, E
ValueSelection<Request, Enrollment> valueSelection) {
iVariableSelection = variableSelection;
iValueSelection = valueSelection;
iPreferPriorityStudents = properties.getPropertyBoolean("Sectioning.PriorityStudentsFirstSelection.AllIn", true);
}

/** Initialization */
Expand Down Expand Up @@ -110,8 +112,10 @@ public boolean canUnassign(Enrollment enrollment, Enrollment conflict, Assignmen
float credit = conflict.getRequest().getStudent().getAssignedCredit(assignment) - conflict.getCredit();
if (credit < conflict.getRequest().getStudent().getMinCredit()) return false;
}
if (!enrollment.getStudent().isPriority() && conflict.getStudent().isPriority()) return false;
if (!conflict.getRequest().isAlternative() && conflict.getRequest().getRequestPriority().isHigher(enrollment.getRequest())) return false;
if (iPreferPriorityStudents || conflict.getRequest().getRequestPriority().isSame(enrollment.getRequest())) {
if (!enrollment.getStudent().isPriority() && conflict.getStudent().isPriority()) return false;
}
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public class SwapStudentSelection implements NeighbourSelection<Request, Enrollm
private int iMaxValues = 100;
public static boolean sDebug = false;
protected StudentOrder iOrder = new StudentChoiceRealFirstOrder();
private boolean iPreferPriorityStudents = true;

protected long iNbrIterations = 0;
protected long iTotalTime = 0;
Expand All @@ -124,6 +125,7 @@ public SwapStudentSelection(DataProperties properties) {
sLog.error("Unable to set student order, reason:" + e.getMessage(), e);
}
}
iPreferPriorityStudents = properties.getPropertyBoolean("Sectioning.PriorityStudentsFirstSelection.AllIn", true);
}

/** Initialization */
Expand Down Expand Up @@ -222,8 +224,10 @@ public boolean canUnassign(Enrollment enrollment, Enrollment conflict, Assignmen
float credit = conflict.getRequest().getStudent().getAssignedCredit(assignment) - conflict.getCredit();
if (credit < conflict.getRequest().getStudent().getMinCredit()) return false;
}
if (!enrollment.getStudent().isPriority() && conflict.getStudent().isPriority()) return false;
if (!conflict.getRequest().isAlternative() && conflict.getRequest().getRequestPriority().isHigher(enrollment.getRequest())) return false;
if (iPreferPriorityStudents || conflict.getRequest().getRequestPriority().isSame(enrollment.getRequest())) {
if (!enrollment.getStudent().isPriority() && conflict.getStudent().isPriority()) return false;
}
return true;
}

Expand Down
3 changes: 3 additions & 0 deletions src/org/cpsolver/studentsct/model/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -298,5 +298,8 @@ public boolean isCritical(Request r) {
public boolean isHigher(Request r) {
return ordinal() < r.getRequestPriority().ordinal();
}
public boolean isSame(Request r) {
return ordinal() == r.getRequestPriority().ordinal();
}
}
}

0 comments on commit afea8ee

Please sign in to comment.