use of org.cpsolver.ifs.model.Constraint in project cpsolver by UniTime.
the class CSPModel method buildBinaryConstraintGraph.
private void buildBinaryConstraintGraph(Random rnd) {
int numberOfAllPairs = variables().size() * (variables().size() - 1) / 2;
CSPVariable[][] allPairs = new CSPVariable[numberOfAllPairs][];
int idx = 0;
for (CSPVariable v1 : variables()) {
for (CSPVariable v2 : variables()) {
if (v1.getId() >= v2.getId())
continue;
allPairs[idx++] = new CSPVariable[] { v1, v2 };
}
}
idx = 0;
for (Iterator<Constraint<CSPVariable, CSPValue>> i = constraints().iterator(); i.hasNext(); ) {
CSPBinaryConstraint c = (CSPBinaryConstraint) i.next();
swap(allPairs, idx, idx + (int) (rnd.nextDouble() * (numberOfAllPairs - idx)));
c.addVariable(allPairs[idx][0]);
c.addVariable(allPairs[idx][1]);
c.init(rnd);
idx++;
}
}
use of org.cpsolver.ifs.model.Constraint in project cpsolver by UniTime.
the class GroupConstraint method forwardCheck.
public boolean forwardCheck(Assignment<Lecture, Placement> assignment, Placement value, Set<GroupConstraint> ignore, int depth) {
try {
if (depth < 0)
return true;
ignore.add(this);
int neededSize = value.variable().maxRoomUse();
for (Lecture lecture : variables()) {
// Skip this lecture
if (lecture.equals(value.variable()))
continue;
Placement current = assignment.getValue(lecture);
if (current != null) {
// Has assignment, check whether it is conflicting
if (isSatisfiedPair(assignment, value, current)) {
// Increase needed size if the assignment is of the same room and overlapping in time
if (canShareRoom() && sameRoomAndOverlaps(value, current)) {
neededSize += lecture.maxRoomUse();
}
continue;
}
return false;
}
// Look for supporting assignments assignment
boolean shareRoomAndOverlaps = canShareRoom();
Placement support = null;
int nrSupports = 0;
if (lecture.nrValues() >= iForwardCheckMaxDomainSize) {
// ignore variables with large domains
return true;
}
List<Placement> values = lecture.values(assignment);
if (values.isEmpty()) {
// ignore variables with empty domain
return true;
}
for (Placement other : lecture.values(assignment)) {
if (nrSupports < 2) {
if (isSatisfiedPair(assignment, value, other)) {
if (support == null)
support = other;
nrSupports++;
if (shareRoomAndOverlaps && !sameRoomAndOverlaps(value, other))
shareRoomAndOverlaps = false;
}
} else if (shareRoomAndOverlaps && !sameRoomAndOverlaps(value, other) && isSatisfiedPair(assignment, value, other)) {
shareRoomAndOverlaps = false;
}
if (nrSupports > 1 && !shareRoomAndOverlaps)
break;
}
// No supporting assignment -> fail
if (nrSupports == 0) {
// other class cannot be assigned with this value
return false;
}
// Increase needed size if all supporters are of the same room and in overlapping times
if (shareRoomAndOverlaps) {
neededSize += lecture.maxRoomUse();
}
// Only one supporter -> propagate the new assignment over other hard constraints of the lecture
if (nrSupports == 1) {
for (Constraint<Lecture, Placement> other : lecture.hardConstraints()) {
if (other instanceof WeakeningConstraint)
continue;
if (other instanceof GroupConstraint) {
GroupConstraint gc = (GroupConstraint) other;
if (depth > 0 && !ignore.contains(gc) && !gc.forwardCheck(assignment, support, ignore, depth - 1))
return false;
} else {
if (other.inConflict(assignment, support))
return false;
}
}
for (GlobalConstraint<Lecture, Placement> other : getModel().globalConstraints()) {
if (other instanceof WeakeningConstraint)
continue;
if (other.inConflict(assignment, support))
return false;
}
}
}
if (canShareRoom() && neededSize > value.getRoomSize()) {
// room is too small to fit all meet with classes
return false;
}
return true;
} finally {
ignore.remove(this);
}
}
use of org.cpsolver.ifs.model.Constraint in project cpsolver by UniTime.
the class GroupConstraint method forwardCheck.
public void forwardCheck(Assignment<Lecture, Placement> assignment, Placement value, Set<Placement> conflicts, Set<GroupConstraint> ignore, int depth) {
try {
if (depth < 0)
return;
ignore.add(this);
List<Placement> neededSize = null;
for (Lecture lecture : variables()) {
// already conflicting
if (conflicts.contains(value))
break;
// Skip this lecture
if (lecture.equals(value.variable()))
continue;
Placement current = assignment.getValue(lecture);
if (current != null) {
// Has assignment, check whether it is conflicting
if (isSatisfiedPair(assignment, value, current)) {
// Increase needed size if the assignment is of the same room and overlapping in time
if (canShareRoom() && sameRoomAndOverlaps(value, current)) {
if (neededSize == null)
neededSize = new ArrayList<Placement>();
neededSize.add(current);
}
continue;
}
conflicts.add(current);
}
// Look for supporting assignments assignment
boolean shareRoomAndOverlaps = canShareRoom();
Placement support = null;
int nrSupports = 0;
if (lecture.nrValues() >= iForwardCheckMaxDomainSize) {
// ignore variables with large domains
return;
}
List<Placement> values = lecture.values(assignment);
if (values.isEmpty()) {
// ignore variables with empty domain
return;
}
for (Placement other : values) {
if (nrSupports < 2) {
if (isSatisfiedPair(assignment, value, other)) {
if (support == null)
support = other;
nrSupports++;
if (shareRoomAndOverlaps && !sameRoomAndOverlaps(value, other))
shareRoomAndOverlaps = false;
}
} else if (shareRoomAndOverlaps && !sameRoomAndOverlaps(value, other) && isSatisfiedPair(assignment, value, other)) {
shareRoomAndOverlaps = false;
}
if (nrSupports > 1 && !shareRoomAndOverlaps)
break;
}
// No supporting assignment -> fail
if (nrSupports == 0) {
// other class cannot be assigned with this value
conflicts.add(value);
return;
}
// Increase needed size if all supporters are of the same room and in overlapping times
if (shareRoomAndOverlaps && support != null) {
if (neededSize == null)
neededSize = new ArrayList<Placement>();
neededSize.add(support);
}
// Only one supporter -> propagate the new assignment over other hard constraints of the lecture
if (nrSupports == 1) {
for (Constraint<Lecture, Placement> other : lecture.hardConstraints()) {
if (other instanceof WeakeningConstraint)
continue;
if (other instanceof GroupConstraint) {
GroupConstraint gc = (GroupConstraint) other;
if (depth > 0 && !ignore.contains(gc))
gc.forwardCheck(assignment, support, conflicts, ignore, depth - 1);
} else {
other.computeConflicts(assignment, support, conflicts);
}
}
for (GlobalConstraint<Lecture, Placement> other : getModel().globalConstraints()) {
if (other instanceof WeakeningConstraint)
continue;
other.computeConflicts(assignment, support, conflicts);
}
if (conflicts.contains(support))
conflicts.add(value);
}
}
if (canShareRoom() && neededSize != null) {
if (value.getRoomLocations() != null) {
for (RoomLocation room : value.getRoomLocations()) if (room.getRoomConstraint() != null && !room.getRoomConstraint().checkRoomSize(value, neededSize)) {
// room is too small to fit all meet with classes
conflicts.add(value);
}
} else if (value.getRoomLocation() != null) {
RoomLocation room = value.getRoomLocation();
if (room.getRoomConstraint() != null && !room.getRoomConstraint().checkRoomSize(value, neededSize)) {
// room is too small to fit all meet with classes
conflicts.add(value);
}
}
}
} finally {
ignore.remove(this);
}
}
use of org.cpsolver.ifs.model.Constraint in project cpsolver by UniTime.
the class TimetableModel method saveAsXML.
public void saveAsXML(DataProperties cfg, boolean gen, Solution<Activity, Location> solution, Assignment<Activity, Location> assignment, File outFile) throws IOException {
outFile.getParentFile().mkdirs();
sLogger.debug("Writting XML data to:" + outFile);
Document document = DocumentHelper.createDocument();
document.addComment("Interactive Timetabling - University Timetable Generator (version 2.0)");
if (assignment == null && solution != null)
assignment = solution.getAssignment();
if (assignment == null)
assignment = new DefaultSingleAssignment<Activity, Location>();
if (!assignedVariables(assignment).isEmpty()) {
StringBuffer comments = new StringBuffer("Solution Info:\n");
Map<String, String> solutionInfo = (solution == null ? getInfo(assignment) : solution.getInfo());
for (String key : new TreeSet<String>(solutionInfo.keySet())) {
String value = solutionInfo.get(key);
comments.append(" " + key + ": " + value + "\n");
}
document.addComment(comments.toString());
}
Element root = document.addElement("Timetable");
if (gen) {
Element generator = root.addElement("Generator");
generator.addAttribute("version", "2.0");
generator.addElement("DaysPerWeek").setText(String.valueOf(iNrDays));
generator.addElement("SlotsPerDay").setText(String.valueOf(iNrHours));
generator.addElement("NrRooms").setText(cfg.getProperty("Generator.NrRooms", "20"));
generator.addElement("NrInstructors").setText(cfg.getProperty("Generator.NrInstructors", "20"));
generator.addElement("NrClasses").setText(cfg.getProperty("Generator.NrClasses", "20"));
generator.addElement("FillFactor").setText(cfg.getProperty("Generator.FillFactor", "0.8"));
generator.addElement("ActivityLengthMax").setText(cfg.getProperty("Generator.ActivityLengthMax", "5"));
generator.addElement("NrGroupsOfRooms").setText(cfg.getProperty("Generator.NrGroupsOfRooms", "20"));
generator.addElement("NrRoomsInGroupMin").setText(cfg.getProperty("Generator.NrRoomsInGroupMin", "1"));
generator.addElement("NrRoomsInGroupMax").setText(cfg.getProperty("Generator.NrRoomsInGroupMax", "10"));
generator.addElement("NrRoomInGroupMin").setText(cfg.getProperty("Generator.NrRoomInGroupMin", "1"));
generator.addElement("HardFreeResource").setText(cfg.getProperty("Generator.HardFreeResource", "0.05"));
generator.addElement("SoftFreeResource").setText(cfg.getProperty("Generator.SoftFreeResource", "0.3"));
generator.addElement("SoftUsedResource").setText(cfg.getProperty("Generator.SoftUsedResource", "0.05"));
generator.addElement("SoftUsedActivity").setText(cfg.getProperty("Generator.SoftUsedActivity", "0.05"));
generator.addElement("SoftFreeActivity").setText(cfg.getProperty("Generator.SoftFreeActivity", "0.3"));
generator.addElement("HardFreeActivity").setText(cfg.getProperty("Generator.HardFreeActivity", "0.05"));
generator.addElement("NrDependencies").setText(cfg.getProperty("Generator.NrDependencies", "50"));
}
ArrayList<Resource> rooms = new ArrayList<Resource>();
ArrayList<Resource> classes = new ArrayList<Resource>();
ArrayList<Resource> instructors = new ArrayList<Resource>();
ArrayList<Resource> specials = new ArrayList<Resource>();
ArrayList<Dependence> dependencies = new ArrayList<Dependence>();
for (Constraint<Activity, Location> c : constraints()) {
if (c instanceof Resource) {
Resource r = (Resource) c;
switch(r.getType()) {
case Resource.TYPE_ROOM:
rooms.add(r);
break;
case Resource.TYPE_CLASS:
classes.add(r);
break;
case Resource.TYPE_INSTRUCTOR:
instructors.add(r);
break;
default:
specials.add(r);
}
} else if (c instanceof Dependence) {
dependencies.add((Dependence) c);
}
}
Element problem = root.addElement("Problem");
problem.addAttribute("version", "2.0");
Element problemGen = problem.addElement("General");
problemGen.addElement("DaysPerWeek").setText(String.valueOf(iNrDays));
problemGen.addElement("SlotsPerDay").setText(String.valueOf(iNrHours));
Element resourceGen = problemGen.addElement("Resources");
resourceGen.addElement("Classrooms").setText(String.valueOf(rooms.size()));
resourceGen.addElement("Teachers").setText(String.valueOf(instructors.size()));
resourceGen.addElement("Classes").setText(String.valueOf(classes.size()));
resourceGen.addElement("Special").setText(String.valueOf(specials.size()));
problemGen.addElement("Activities").setText(String.valueOf(variables().size()));
problemGen.addElement("Dependences").setText(String.valueOf(dependencies.size()));
Element resources = problem.addElement("Resources");
Element resEl = resources.addElement("Classrooms");
for (Resource r : rooms) {
Element el = resEl.addElement("Resource");
el.addAttribute("id", r.getResourceId());
el.addElement("Name").setText(r.getName());
Element pref = el.addElement("TimePreferences");
for (Integer slot : new TreeSet<Integer>(r.getDiscouragedSlots())) pref.addElement("Soft").setText(slot.toString());
for (Integer slot : new TreeSet<Integer>(r.getProhibitedSlots())) pref.addElement("Hard").setText(slot.toString());
}
resEl = resources.addElement("Teachers");
for (Resource r : instructors) {
Element el = resEl.addElement("Resource");
el.addAttribute("id", r.getResourceId());
el.addElement("Name").setText(r.getName());
Element pref = el.addElement("TimePreferences");
for (Integer slot : new TreeSet<Integer>(r.getDiscouragedSlots())) pref.addElement("Soft").setText(slot.toString());
for (Integer slot : new TreeSet<Integer>(r.getProhibitedSlots())) pref.addElement("Hard").setText(slot.toString());
}
resEl = resources.addElement("Classes");
for (Resource r : classes) {
Element el = resEl.addElement("Resource");
el.addAttribute("id", r.getResourceId());
el.addElement("Name").setText(r.getName());
Element pref = el.addElement("TimePreferences");
for (Integer slot : new TreeSet<Integer>(r.getDiscouragedSlots())) pref.addElement("Soft").setText(slot.toString());
for (Integer slot : new TreeSet<Integer>(r.getProhibitedSlots())) pref.addElement("Hard").setText(slot.toString());
}
resEl = resources.addElement("Special");
for (Resource r : specials) {
Element el = resEl.addElement("Resource");
el.addAttribute("id", r.getResourceId());
el.addElement("Name").setText(r.getName());
Element pref = el.addElement("TimePreferences");
for (Integer slot : new TreeSet<Integer>(r.getDiscouragedSlots())) pref.addElement("Soft").setText(slot.toString());
for (Integer slot : new TreeSet<Integer>(r.getProhibitedSlots())) pref.addElement("Hard").setText(slot.toString());
}
boolean hasSolution = false;
Element actEl = problem.addElement("Activities");
for (Activity a : variables()) {
Element el = actEl.addElement("Activity");
el.addAttribute("id", a.getActivityId());
el.addElement("Name").setText(a.getName());
el.addElement("Length").setText(String.valueOf(a.getLength()));
if (assignment.getValue(a) != null)
hasSolution = true;
Element pref = el.addElement("TimePreferences");
for (Integer slot : new TreeSet<Integer>(a.getDiscouragedSlots())) pref.addElement("Soft").setText(slot.toString());
for (Integer slot : new TreeSet<Integer>(a.getProhibitedSlots())) pref.addElement("Hard").setText(slot.toString());
Element reqRes = el.addElement("RequiredResources");
for (List<Resource> gr : a.getResourceGroups()) {
if (gr.size() == 1) {
reqRes.addElement("Resource").setText(gr.get(0).getResourceId());
} else {
Element grEl = reqRes.addElement("Group").addAttribute("conjunctive", "no");
for (Resource r : gr) grEl.addElement("Resource").setText(r.getResourceId());
}
}
}
Element depEl = problem.addElement("Dependences");
for (Dependence d : dependencies) {
Element el = depEl.addElement("Dependence");
el.addAttribute("id", d.getResourceId());
el.addElement("FirstActivity").setText((d.first()).getActivityId());
el.addElement("SecondActivity").setText((d.second()).getActivityId());
switch(d.getType()) {
case Dependence.TYPE_AFTER:
el.addElement("Operator").setText("After");
break;
case Dependence.TYPE_BEFORE:
el.addElement("Operator").setText("Before");
break;
case Dependence.TYPE_CLOSELY_BEFORE:
el.addElement("Operator").setText("Closely before");
break;
case Dependence.TYPE_CLOSELY_AFTER:
el.addElement("Operator").setText("Closely after");
break;
case Dependence.TYPE_CONCURRENCY:
el.addElement("Operator").setText("Concurrently");
break;
default:
el.addElement("Operator").setText("Unknown");
}
}
if (hasSolution) {
Element solutionEl = root.addElement("Solution");
solutionEl.addAttribute("version", "2.0");
for (Activity a : variables()) {
Element el = solutionEl.addElement("Activity");
el.addAttribute("id", a.getActivityId());
Location location = assignment.getValue(a);
if (location != null) {
el.addElement("StartTime").setText(String.valueOf(location.getSlot()));
Element res = el.addElement("UsedResources");
for (int i = 0; i < location.getResources().length; i++) res.addElement("Resource").setText(location.getResources()[i].getResourceId());
}
}
}
FileOutputStream fos = new FileOutputStream(outFile);
(new XMLWriter(fos, OutputFormat.createPrettyPrint())).write(document);
fos.flush();
fos.close();
}
use of org.cpsolver.ifs.model.Constraint in project cpsolver by UniTime.
the class StructuredCSPModel method generate.
@SuppressWarnings("unchecked")
private void generate(long seed) {
int nrVariables = iProperties.getPropertyInt("CSP.NrVariables", 60);
int nrValues = iProperties.getPropertyInt("CSP.DomainSize", 15);
int nrKernels = iProperties.getPropertyInt("CSP.NrKernels", 2);
int nrKernelVariables = iProperties.getPropertyInt("CSP.KernelSize", 8);
int nrPairValues = nrValues * nrValues;
float tightnessPerc = iProperties.getPropertyFloat("CSP.Tightness", 0.01f);
float kernelTightnessPerc = iProperties.getPropertyFloat("CSP.KernelTightness", 0.097f);
int nrCompatiblePairs = (int) Math.round((1.0 - tightnessPerc) * nrPairValues);
int kernelNrCompatiblePairs = (int) Math.round((1.0 - kernelTightnessPerc) * nrPairValues);
int nrPairVariables = (nrVariables * (nrVariables - 1)) / 2;
int nrPairKernelVariables = (nrKernelVariables * (nrKernelVariables - 1)) / 2;
nrPairVariables -= nrKernels * nrPairKernelVariables;
float densityPerc = iProperties.getPropertyFloat("CSP.Density", 0.01f);
float densityKernelPerc = iProperties.getPropertyFloat("CSP.KernelDensity", 0.097f);
int density = Math.round(densityPerc * nrPairVariables);
int kernelDensity = Math.round(densityKernelPerc * nrPairKernelVariables);
Random rnd = new Random(seed);
List<CSPVariable> generalVariables = new ArrayList<CSPVariable>(nrVariables - (nrKernels * nrKernelVariables));
int varId = 1;
for (int i = 0; i < nrVariables - (nrKernels * nrKernelVariables); i++) {
CSPVariable var = new CSPVariable(varId++, nrValues);
generalVariables.add(var);
addVariable(var);
}
sLogger.debug("Created " + generalVariables.size() + " general variables.");
List<CSPVariable>[] kernelVariables = new ArrayList[nrKernels];
for (int k = 0; k < nrKernels; k++) {
kernelVariables[k] = new ArrayList<CSPVariable>(nrKernelVariables);
for (int i = 0; i < nrKernelVariables; i++) {
CSPVariable var = new CSPVariable(varId++, nrValues, k);
kernelVariables[k].add(var);
addVariable(var);
}
if (k == 0)
sLogger.debug("Created " + kernelVariables[0].size() + " kernel variables (per kernel).");
}
sLogger.debug("Created " + variables().size() + " variables at total.");
int constId = 1;
List<CSPBinaryConstraint> generalConstraints = new ArrayList<CSPBinaryConstraint>(density);
for (int i = 0; i < density; i++) {
CSPBinaryConstraint c = new CSPBinaryConstraint(constId++, nrCompatiblePairs);
generalConstraints.add(c);
addConstraint(c);
}
sLogger.debug("Created " + generalConstraints.size() + " general constraints (tightness=" + tightnessPerc + ").");
List<CSPBinaryConstraint>[] kernelConstraints = new List[nrKernels];
for (int k = 0; k < nrKernels; k++) {
kernelConstraints[k] = new ArrayList<CSPBinaryConstraint>(kernelDensity);
for (int i = 0; i < kernelDensity; i++) {
CSPBinaryConstraint c = new CSPBinaryConstraint(constId++, kernelNrCompatiblePairs);
kernelConstraints[k].add(c);
addConstraint(c);
}
if (k == 0)
sLogger.debug("Created " + kernelConstraints[0].size() + " kernel constraints (per kernel, tightness=" + kernelTightnessPerc + ").");
}
sLogger.debug("Created " + constraints().size() + " constraints at total.");
for (int k = 0; k < nrKernels; k++) {
buildBinaryConstraintGraph(kernelVariables[k], kernelConstraints[k], rnd);
}
buildBinaryConstraintGraph2(variables(), nrPairVariables, generalConstraints, rnd);
for (Constraint<CSPVariable, CSPValue> c : constraints()) {
CSPBinaryConstraint constraint = (CSPBinaryConstraint) c;
constraint.init(rnd);
}
if (iProperties.getPropertyBoolean("General.MPP", false)) {
for (CSPVariable variable : variables()) {
variable.generateInitialValue(rnd);
}
}
}
Aggregations