Search in sources :

Example 6 with Constraint

use of org.cpsolver.ifs.model.Constraint in project cpsolver by UniTime.

the class InstructorSchedulingModel method load.

/**
 * Load the problem (and its solution) from an XML format
 * @param document XML document
 * @param assignment current assignment
 * @return true, if the problem was successfully loaded in
 */
public boolean load(Document document, Assignment<TeachingRequest.Variable, TeachingAssignment> assignment) {
    boolean loadInitial = getProperties().getPropertyBoolean("Xml.LoadInitial", true);
    boolean loadBest = getProperties().getPropertyBoolean("Xml.LoadBest", true);
    boolean loadSolution = getProperties().getPropertyBoolean("Xml.LoadSolution", true);
    String defaultBtb = getProperties().getProperty("Defaults.BackToBack", "0");
    String defaultSameDays = getProperties().getProperty("Defaults.SameDays", "0");
    String defaultSameRoom = getProperties().getProperty("Defaults.SameRoom", "0");
    String defaultConjunctive = getProperties().getProperty("Defaults.Conjunctive", "false");
    String defaultRequired = getProperties().getProperty("Defaults.Required", "false");
    String defaultSameCourse = getProperties().getProperty("Defaults.SameCourse", "R");
    String defaultSameCommon = getProperties().getProperty("Defaults.SameCommon", "R");
    Element root = document.getRootElement();
    if (!"instructor-schedule".equals(root.getName()))
        return false;
    Map<String, Attribute.Type> types = new HashMap<String, Attribute.Type>();
    Map<Long, Attribute> attributes = new HashMap<Long, Attribute>();
    Map<Long, Long> parents = new HashMap<Long, Long>();
    if (root.element("attributes") != null) {
        for (Iterator<?> i = root.element("attributes").elementIterator("type"); i.hasNext(); ) {
            Element typeEl = (Element) i.next();
            Attribute.Type type = new Attribute.Type(Long.parseLong(typeEl.attributeValue("id")), typeEl.attributeValue("name"), "true".equalsIgnoreCase(typeEl.attributeValue("conjunctive", defaultConjunctive)), "true".equalsIgnoreCase(typeEl.attributeValue("required", defaultRequired)));
            addAttributeType(type);
            if (type.getTypeName() != null)
                types.put(type.getTypeName(), type);
            for (Iterator<?> j = typeEl.elementIterator("attribute"); j.hasNext(); ) {
                Element attributeEl = (Element) j.next();
                Attribute attribute = new Attribute(Long.parseLong(attributeEl.attributeValue("id")), attributeEl.attributeValue("name"), type);
                attributes.put(attribute.getAttributeId(), attribute);
                if (attributeEl.attributeValue("parent") != null)
                    parents.put(attribute.getAttributeId(), Long.parseLong(attributeEl.attributeValue("parent")));
            }
        }
    }
    Map<Long, Course> courses = new HashMap<Long, Course>();
    if (root.element("courses") != null) {
        for (Iterator<?> i = root.element("courses").elementIterator("course"); i.hasNext(); ) {
            Element courseEl = (Element) i.next();
            Course course = new Course(Long.parseLong(courseEl.attributeValue("id")), courseEl.attributeValue("name"));
            courses.put(course.getCourseId(), course);
        }
    }
    Map<Long, Instructor> instructors = new HashMap<Long, Instructor>();
    for (Iterator<?> i = root.element("instructors").elementIterator("instructor"); i.hasNext(); ) {
        Element instructorEl = (Element) i.next();
        Instructor instructor = new Instructor(Long.parseLong(instructorEl.attributeValue("id")), instructorEl.attributeValue("externalId"), instructorEl.attributeValue("name"), string2preference(instructorEl.attributeValue("preference")), Float.parseFloat(instructorEl.attributeValue("maxLoad", "0")));
        instructor.setBackToBackPreference(Integer.valueOf(instructorEl.attributeValue("btb", defaultBtb)));
        instructor.setSameDaysPreference(Integer.valueOf(instructorEl.attributeValue("same-days", defaultSameDays)));
        instructor.setSameRoomPreference(Integer.valueOf(instructorEl.attributeValue("same-room", defaultSameRoom)));
        for (Iterator<?> j = instructorEl.elementIterator("attribute"); j.hasNext(); ) {
            Element f = (Element) j.next();
            Long attributeId = Long.valueOf(f.attributeValue("id"));
            Attribute attribute = attributes.get(attributeId);
            if (attribute == null) {
                Attribute.Type type = types.get(f.attributeValue("type"));
                if (type == null) {
                    type = new Attribute.Type(types.size(), f.attributeValue("type"), "true".equalsIgnoreCase(f.attributeValue("conjunctive", defaultConjunctive)), "true".equalsIgnoreCase(f.attributeValue("required", defaultRequired)));
                    types.put(type.getTypeName(), type);
                }
                attribute = new Attribute(attributeId, f.attributeValue("name"), type);
                attributes.put(attributeId, attribute);
                if (f.attributeValue("parent") != null)
                    parents.put(attribute.getAttributeId(), Long.parseLong(f.attributeValue("parent")));
            }
            instructor.addAttribute(attribute);
        }
        for (Iterator<?> j = instructorEl.elementIterator("time"); j.hasNext(); ) {
            Element f = (Element) j.next();
            Element classEl = f.element("section");
            Element courseEl = f.element("course");
            TimeLocation time = null;
            if (classEl != null) {
                time = new EnrolledClass(courseEl == null || courseEl.attributeValue("id") == null ? null : Long.valueOf(courseEl.attributeValue("id")), classEl.attributeValue("id") == null ? null : Long.valueOf(classEl.attributeValue("id")), courseEl == null ? null : courseEl.attributeValue("name"), classEl.attributeValue("type"), classEl.attributeValue("name"), classEl.attributeValue("externalId"), Integer.parseInt(f.attributeValue("days"), 2), Integer.parseInt(f.attributeValue("start")), Integer.parseInt(f.attributeValue("length")), f.attributeValue("datePattern") == null ? null : Long.valueOf(f.attributeValue("datePattern")), f.attributeValue("datePatternName", ""), createBitSet(f.attributeValue("dates")), Integer.parseInt(f.attributeValue("breakTime", "0")), classEl.attributeValue("room"), "instructor".equalsIgnoreCase(classEl.attributeValue("role", "instructor")));
            } else {
                time = new TimeLocation(Integer.parseInt(f.attributeValue("days"), 2), Integer.parseInt(f.attributeValue("start")), Integer.parseInt(f.attributeValue("length")), 0, 0, f.attributeValue("datePattern") == null ? null : Long.valueOf(f.attributeValue("datePattern")), f.attributeValue("datePatternName", ""), createBitSet(f.attributeValue("dates")), Integer.parseInt(f.attributeValue("breakTime", "0")));
            }
            if (f.attributeValue("pattern") != null)
                time.setTimePatternId(Long.valueOf(f.attributeValue("pattern")));
            instructor.addTimePreference(new Preference<TimeLocation>(time, string2preference(f.attributeValue("preference"))));
        }
        for (Iterator<?> j = instructorEl.elementIterator("course"); j.hasNext(); ) {
            Element f = (Element) j.next();
            instructor.addCoursePreference(new Preference<Course>(new Course(Long.parseLong(f.attributeValue("id")), f.attributeValue("name")), string2preference(f.attributeValue("preference"))));
        }
        addInstructor(instructor);
        instructors.put(instructor.getInstructorId(), instructor);
    }
    Map<Long, TeachingRequest> requests = new HashMap<Long, TeachingRequest>();
    Map<TeachingRequest, Map<Integer, Instructor>> current = new HashMap<TeachingRequest, Map<Integer, Instructor>>();
    Map<TeachingRequest, Map<Integer, Instructor>> best = new HashMap<TeachingRequest, Map<Integer, Instructor>>();
    Map<TeachingRequest, Map<Integer, Instructor>> initial = new HashMap<TeachingRequest, Map<Integer, Instructor>>();
    for (Iterator<?> i = root.element("teaching-requests").elementIterator("request"); i.hasNext(); ) {
        Element requestEl = (Element) i.next();
        Element courseEl = requestEl.element("course");
        Course course = null;
        if (courseEl != null) {
            Long courseId = Long.valueOf(courseEl.attributeValue("id"));
            course = courses.get(courseId);
            if (course == null) {
                course = new Course(courseId, courseEl.attributeValue("name"));
            }
        } else {
            course = courses.get(Long.valueOf(requestEl.attributeValue("course")));
        }
        List<Section> sections = new ArrayList<Section>();
        for (Iterator<?> j = requestEl.elementIterator("section"); j.hasNext(); ) {
            Element f = (Element) j.next();
            TimeLocation time = null;
            Element timeEl = f.element("time");
            if (timeEl != null) {
                time = new TimeLocation(Integer.parseInt(timeEl.attributeValue("days"), 2), Integer.parseInt(timeEl.attributeValue("start")), Integer.parseInt(timeEl.attributeValue("length")), 0, 0, timeEl.attributeValue("datePattern") == null ? null : Long.valueOf(timeEl.attributeValue("datePattern")), timeEl.attributeValue("datePatternName", ""), createBitSet(timeEl.attributeValue("dates")), Integer.parseInt(timeEl.attributeValue("breakTime", "0")));
                if (timeEl.attributeValue("pattern") != null)
                    time.setTimePatternId(Long.valueOf(timeEl.attributeValue("pattern")));
            }
            Section section = new Section(Long.valueOf(f.attributeValue("id")), f.attributeValue("externalId"), f.attributeValue("type"), f.attributeValue("name"), time, f.attributeValue("room"), "true".equalsIgnoreCase(f.attributeValue("canOverlap", "false")), "true".equalsIgnoreCase(f.attributeValue("common", "false")));
            sections.add(section);
        }
        TeachingRequest request = new TeachingRequest(Long.parseLong(requestEl.attributeValue("id")), Integer.parseInt(requestEl.attributeValue("nrInstructors", "1")), course, Float.valueOf(requestEl.attributeValue("load", "0")), sections, Constants.preference2preferenceLevel(requestEl.attributeValue("sameCourse", defaultSameCourse)), Constants.preference2preferenceLevel(requestEl.attributeValue("sameCommon", defaultSameCommon)));
        requests.put(request.getRequestId(), request);
        for (Iterator<?> j = requestEl.elementIterator("attribute"); j.hasNext(); ) {
            Element f = (Element) j.next();
            Long attributeId = Long.valueOf(f.attributeValue("id"));
            Attribute attribute = attributes.get(attributeId);
            if (attribute == null) {
                Attribute.Type type = types.get(f.attributeValue("type"));
                if (type == null) {
                    type = new Attribute.Type(types.size(), f.attributeValue("type"), "true".equalsIgnoreCase(f.attributeValue("conjunctive", defaultConjunctive)), "true".equalsIgnoreCase(f.attributeValue("required", defaultRequired)));
                    types.put(type.getTypeName(), type);
                }
                attribute = new Attribute(attributeId, f.attributeValue("name"), type);
                attributes.put(attributeId, attribute);
                if (f.attributeValue("parent") != null)
                    parents.put(attribute.getAttributeId(), Long.parseLong(f.attributeValue("parent")));
            }
            request.addAttributePreference(new Preference<Attribute>(attribute, string2preference(f.attributeValue("preference"))));
        }
        for (Iterator<?> j = requestEl.elementIterator("instructor"); j.hasNext(); ) {
            Element f = (Element) j.next();
            Long instructorId = Long.valueOf(f.attributeValue("id"));
            Instructor instructor = instructors.get(instructorId);
            if (instructor != null)
                request.addInstructorPreference(new Preference<Instructor>(instructor, string2preference(f.attributeValue("preference"))));
        }
        if (loadBest) {
            for (Iterator<?> j = requestEl.elementIterator("best-instructor"); j.hasNext(); ) {
                Element f = (Element) j.next();
                Map<Integer, Instructor> idx2inst = best.get(request);
                if (idx2inst == null) {
                    idx2inst = new HashMap<Integer, Instructor>();
                    best.put(request, idx2inst);
                }
                int index = 1 + Integer.parseInt(f.attributeValue("index", String.valueOf(idx2inst.size())));
                Instructor instructor = instructors.get(Long.valueOf(f.attributeValue("id")));
                if (instructor != null)
                    idx2inst.put(index, instructor);
            }
        }
        if (loadInitial) {
            for (Iterator<?> j = requestEl.elementIterator("initial-instructor"); j.hasNext(); ) {
                Element f = (Element) j.next();
                Map<Integer, Instructor> idx2inst = initial.get(request);
                if (idx2inst == null) {
                    idx2inst = new HashMap<Integer, Instructor>();
                    initial.put(request, idx2inst);
                }
                int index = 1 + Integer.parseInt(f.attributeValue("index", String.valueOf(idx2inst.size())));
                Instructor instructor = instructors.get(Long.valueOf(f.attributeValue("id")));
                if (instructor != null)
                    idx2inst.put(index, instructor);
            }
        }
        if (loadSolution) {
            for (Iterator<?> j = requestEl.elementIterator("assigned-instructor"); j.hasNext(); ) {
                Element f = (Element) j.next();
                Map<Integer, Instructor> idx2inst = current.get(request);
                if (idx2inst == null) {
                    idx2inst = new HashMap<Integer, Instructor>();
                    current.put(request, idx2inst);
                }
                int index = Integer.parseInt(f.attributeValue("index", String.valueOf(idx2inst.size())));
                Instructor instructor = instructors.get(Long.valueOf(f.attributeValue("id")));
                if (instructor != null)
                    idx2inst.put(index, instructor);
            }
        }
        addRequest(request);
    }
    if (root.element("constraints") != null) {
        for (Iterator<?> i = root.element("constraints").elementIterator(); i.hasNext(); ) {
            Element constraintEl = (Element) i.next();
            Constraint<TeachingRequest.Variable, TeachingAssignment> constraint = null;
            if ("same-link".equals(constraintEl.getName())) {
                constraint = new SameLinkConstraint((constraintEl.attributeValue("id") == null ? null : Long.valueOf(constraintEl.attributeValue("id"))), constraintEl.attributeValue("name"), constraintEl.attributeValue("preference"));
            } else if ("same-instructor".equals(constraintEl.getName())) {
                constraint = new SameInstructorConstraint((constraintEl.attributeValue("id") == null ? null : Long.valueOf(constraintEl.attributeValue("id"))), constraintEl.attributeValue("name"), constraintEl.attributeValue("preference"));
            }
            if (constraint != null) {
                for (Iterator<?> j = constraintEl.elementIterator("request"); j.hasNext(); ) {
                    Element f = (Element) j.next();
                    TeachingRequest request = requests.get(Long.valueOf(f.attributeValue("id")));
                    if (request != null) {
                        int index = Integer.valueOf(f.attributeValue("index", "0"));
                        if (index >= 0 && index < request.getNrInstructors())
                            constraint.addVariable(request.getVariables()[index]);
                    }
                }
                addConstraint(constraint);
            }
        }
    }
    for (Map.Entry<Long, Long> e : parents.entrySet()) attributes.get(e.getKey()).setParentAttribute(attributes.get(e.getValue()));
    for (Map.Entry<TeachingRequest, Map<Integer, Instructor>> e1 : best.entrySet()) for (Map.Entry<Integer, Instructor> e2 : e1.getValue().entrySet()) if (e2.getKey() >= 0 && e2.getKey() < e1.getKey().getNrInstructors()) {
        TeachingRequest.Variable variable = e1.getKey().getVariables()[e2.getKey()];
        variable.setBestAssignment(new TeachingAssignment(variable, e2.getValue()), 0l);
    }
    for (Map.Entry<TeachingRequest, Map<Integer, Instructor>> e1 : initial.entrySet()) for (Map.Entry<Integer, Instructor> e2 : e1.getValue().entrySet()) if (e2.getKey() >= 0 && e2.getKey() < e1.getKey().getNrInstructors()) {
        TeachingRequest.Variable variable = e1.getKey().getVariables()[e2.getKey()];
        variable.setInitialAssignment(new TeachingAssignment(variable, e2.getValue()));
    }
    if (!current.isEmpty()) {
        for (Map.Entry<TeachingRequest, Map<Integer, Instructor>> e1 : current.entrySet()) for (Map.Entry<Integer, Instructor> e2 : e1.getValue().entrySet()) if (e2.getKey() >= 0 && e2.getKey() < e1.getKey().getNrInstructors()) {
            TeachingRequest.Variable variable = e1.getKey().getVariables()[e2.getKey()];
            TeachingAssignment ta = new TeachingAssignment(variable, e2.getValue());
            Set<TeachingAssignment> conf = conflictValues(assignment, ta);
            if (conf.isEmpty()) {
                assignment.assign(0, ta);
            } else {
                sLog.error("Unable to assign " + ta.getName() + " to " + variable.getName());
                sLog.error("Conflicts:" + ToolBox.dict2string(conflictConstraints(assignment, ta), 2));
            }
        }
    }
    return true;
}
Also used : TimeLocation(org.cpsolver.coursett.model.TimeLocation) HashMap(java.util.HashMap) Element(org.dom4j.Element) SameInstructor(org.cpsolver.instructor.criteria.SameInstructor) OriginalInstructor(org.cpsolver.instructor.criteria.OriginalInstructor) ArrayList(java.util.ArrayList) SameLinkConstraint(org.cpsolver.instructor.constraints.SameLinkConstraint) SameCourse(org.cpsolver.instructor.criteria.SameCourse) SameInstructorConstraint(org.cpsolver.instructor.constraints.SameInstructorConstraint) InstructorConstraint(org.cpsolver.instructor.constraints.InstructorConstraint) SameLinkConstraint(org.cpsolver.instructor.constraints.SameLinkConstraint) Constraint(org.cpsolver.ifs.model.Constraint) SameInstructorConstraint(org.cpsolver.instructor.constraints.SameInstructorConstraint) HashMap(java.util.HashMap) Map(java.util.Map)

Example 7 with Constraint

use of org.cpsolver.ifs.model.Constraint in project cpsolver by UniTime.

the class LinkedSections method computeConflicts.

/**
 * Compute conflicting enrollments. If the given enrollment contains sections of this link
 * (one for each subpart in {@link LinkedSections#getSubparts(Offering)}), another assignment
 * of this student is in a conflict, if it does not contain the appropriate sections from
 * {@link LinkedSections#getSubparts(Offering)} and {@link LinkedSections#getSections(Subpart)}.
 *
 * @param enrollment given enrollment
 * @param assignment custom assignment
 * @param conflicts found conflicts are given to this interface, see {@link ConflictHandler#onConflict(Enrollment)}
 */
public void computeConflicts(Enrollment enrollment, EnrollmentAssignment assignment, ConflictHandler conflicts) {
    if (enrollment == null || enrollment.getCourse() == null)
        return;
    if (enrollment.getReservation() != null && enrollment.getReservation().canBreakLinkedSections())
        return;
    Map<Subpart, Set<Section>> subparts = iSections.get(enrollment.getCourse().getOffering());
    if (subparts == null || subparts.isEmpty())
        return;
    boolean match = false, partial = false;
    for (Section section : enrollment.getSections()) {
        Set<Section> sections = subparts.get(section.getSubpart());
        if (sections != null) {
            if (sections.contains(section))
                match = true;
            else
                partial = true;
        }
    }
    boolean full = match && !partial;
    if (isMustBeUsed()) {
        if (!full) {
            // not full match -> conflict if there is no other linked section constraint with a full match
            // check if there is some other constraint taking care of this case
            boolean hasOtherMatch = false;
            for (LinkedSections other : enrollment.getStudent().getLinkedSections()) {
                if (other.hasFullMatch(enrollment) && nrSharedOfferings(other) > 1) {
                    hasOtherMatch = true;
                    break;
                }
            }
            // no other match -> problem
            if (!hasOtherMatch && !conflicts.onConflict(enrollment))
                return;
        }
    }
    if (full) {
        // full match -> check other enrollments
        for (int i = 0; i < enrollment.getStudent().getRequests().size(); i++) {
            Request request = enrollment.getStudent().getRequests().get(i);
            // given enrollment
            if (request.equals(enrollment.getRequest()))
                continue;
            Enrollment otherEnrollment = assignment.getEnrollment(request, i);
            // not assigned or not course request
            if (otherEnrollment == null || otherEnrollment.getCourse() == null)
                continue;
            if (otherEnrollment.getReservation() != null && otherEnrollment.getReservation().canBreakLinkedSections())
                continue;
            Map<Subpart, Set<Section>> otherSubparts = iSections.get(otherEnrollment.getCourse().getOffering());
            // offering is not in the link
            if (otherSubparts == null || otherSubparts.isEmpty())
                continue;
            boolean otherMatch = false, otherPartial = false;
            for (Section section : otherEnrollment.getSections()) {
                Set<Section> otherSections = otherSubparts.get(section.getSubpart());
                if (otherSections != null) {
                    if (otherSections.contains(section))
                        otherMatch = true;
                    else
                        otherPartial = true;
                }
            }
            boolean otherFull = otherMatch && !otherPartial;
            // not full match -> conflict
            if (!otherFull && !conflicts.onConflict(otherEnrollment))
                return;
        }
    } else {
        // no or only partial match -> there should be no match in other offerings too
        for (int i = 0; i < enrollment.getStudent().getRequests().size(); i++) {
            Request request = enrollment.getStudent().getRequests().get(i);
            // given enrollment
            if (request.equals(enrollment.getRequest()))
                continue;
            Enrollment otherEnrollment = assignment.getEnrollment(request, i);
            // not assigned or not course request
            if (otherEnrollment == null || otherEnrollment.getCourse() == null)
                continue;
            if (otherEnrollment.getReservation() != null && otherEnrollment.getReservation().canBreakLinkedSections())
                continue;
            Map<Subpart, Set<Section>> otherSubparts = iSections.get(otherEnrollment.getCourse().getOffering());
            // offering is not in the link
            if (otherSubparts == null || otherSubparts.isEmpty())
                continue;
            boolean otherMatch = false, otherPartial = false;
            for (Section section : otherEnrollment.getSections()) {
                Set<Section> otherSections = otherSubparts.get(section.getSubpart());
                if (otherSections != null) {
                    if (otherSections.contains(section))
                        otherMatch = true;
                    else
                        otherPartial = true;
                }
            }
            boolean otherFull = otherMatch && !otherPartial;
            // full match -> conflict
            if (otherFull && !conflicts.onConflict(otherEnrollment))
                return;
        }
    }
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Subpart(org.cpsolver.studentsct.model.Subpart) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request) Enrollment(org.cpsolver.studentsct.model.Enrollment) Section(org.cpsolver.studentsct.model.Section) Constraint(org.cpsolver.ifs.model.Constraint)

Example 8 with Constraint

use of org.cpsolver.ifs.model.Constraint in project cpsolver by UniTime.

the class ExamModel method save.

/**
 * Save model (including its solution) into XML.
 * @param assignment current assignment
 * @return created XML document
 */
public Document save(Assignment<Exam, ExamPlacement> assignment) {
    boolean saveInitial = getProperties().getPropertyBoolean("Xml.SaveInitial", true);
    boolean saveBest = getProperties().getPropertyBoolean("Xml.SaveBest", true);
    boolean saveSolution = getProperties().getPropertyBoolean("Xml.SaveSolution", true);
    boolean saveConflictTable = getProperties().getPropertyBoolean("Xml.SaveConflictTable", false);
    boolean saveParams = getProperties().getPropertyBoolean("Xml.SaveParameters", true);
    boolean anonymize = getProperties().getPropertyBoolean("Xml.Anonymize", false);
    boolean idconv = getProperties().getPropertyBoolean("Xml.ConvertIds", anonymize);
    Document document = DocumentHelper.createDocument();
    document.addComment("Examination Timetable");
    if (assignment != null && assignment.nrAssignedVariables() > 0) {
        StringBuffer comments = new StringBuffer("Solution Info:\n");
        Map<String, String> solutionInfo = (getProperties().getPropertyBoolean("Xml.ExtendedInfo", false) ? getExtendedInfo(assignment) : getInfo(assignment));
        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("examtt");
    root.addAttribute("version", "1.0");
    root.addAttribute("campus", getProperties().getProperty("Data.Initiative"));
    root.addAttribute("term", getProperties().getProperty("Data.Term"));
    root.addAttribute("year", getProperties().getProperty("Data.Year"));
    root.addAttribute("created", String.valueOf(new Date()));
    if (saveParams) {
        Map<String, String> params = new HashMap<String, String>();
        for (Criterion<Exam, ExamPlacement> criterion : getCriteria()) {
            if (criterion instanceof ExamCriterion)
                ((ExamCriterion) criterion).getXmlParameters(params);
        }
        params.put("maxRooms", String.valueOf(getMaxRooms()));
        params.put("checkForPeriodOverlaps", isCheckForPeriodOverlaps() ? "true" : "false");
        Element parameters = root.addElement("parameters");
        for (String key : new TreeSet<String>(params.keySet())) {
            parameters.addElement("property").addAttribute("name", key).addAttribute("value", params.get(key));
        }
    }
    Element periods = root.addElement("periods");
    for (ExamPeriod period : getPeriods()) {
        Element periodEl = periods.addElement("period").addAttribute("id", getId(idconv, "period", String.valueOf(period.getId()))).addAttribute("length", String.valueOf(period.getLength())).addAttribute("day", period.getDayStr()).addAttribute("time", period.getTimeStr()).addAttribute("penalty", String.valueOf(period.getPenalty()));
        if (period.getStartTime() != null)
            periodEl.addAttribute("start", period.getStartTime().toString());
    }
    Element rooms = root.addElement("rooms");
    for (ExamRoom room : getRooms()) {
        Element r = rooms.addElement("room");
        r.addAttribute("id", getId(idconv, "room", String.valueOf(room.getId())));
        if (!anonymize && room.hasName())
            r.addAttribute("name", room.getName());
        r.addAttribute("size", String.valueOf(room.getSize()));
        r.addAttribute("alt", String.valueOf(room.getAltSize()));
        if (!room.isHard())
            r.addAttribute("hard", "false");
        if (room.getCoordX() != null && room.getCoordY() != null)
            r.addAttribute("coordinates", room.getCoordX() + "," + room.getCoordY());
        for (ExamPeriod period : getPeriods()) {
            if (!room.isAvailable(period))
                r.addElement("period").addAttribute("id", getId(idconv, "period", String.valueOf(period.getId()))).addAttribute("available", "false");
            else if (room.getPenalty(period) != 0)
                r.addElement("period").addAttribute("id", getId(idconv, "period", String.valueOf(period.getId()))).addAttribute("penalty", String.valueOf(room.getPenalty(period)));
        }
        Map<Long, Integer> travelTimes = getDistanceMetric().getTravelTimes().get(room.getId());
        if (travelTimes != null)
            for (Map.Entry<Long, Integer> time : travelTimes.entrySet()) r.addElement("travel-time").addAttribute("id", getId(idconv, "room", time.getKey().toString())).addAttribute("minutes", time.getValue().toString());
    }
    Element exams = root.addElement("exams");
    for (Exam exam : variables()) {
        Element ex = exams.addElement("exam");
        ex.addAttribute("id", getId(idconv, "exam", String.valueOf(exam.getId())));
        if (!anonymize && exam.hasName())
            ex.addAttribute("name", exam.getName());
        ex.addAttribute("length", String.valueOf(exam.getLength()));
        if (exam.getSizeOverride() != null)
            ex.addAttribute("size", exam.getSizeOverride().toString());
        if (exam.getMinSize() != 0)
            ex.addAttribute("minSize", String.valueOf(exam.getMinSize()));
        ex.addAttribute("alt", (exam.hasAltSeating() ? "true" : "false"));
        if (exam.getMaxRooms() != getMaxRooms())
            ex.addAttribute("maxRooms", String.valueOf(exam.getMaxRooms()));
        if (exam.getPrintOffset() != null && !anonymize)
            ex.addAttribute("printOffset", exam.getPrintOffset().toString());
        if (!anonymize)
            ex.addAttribute("enrl", String.valueOf(exam.getStudents().size()));
        if (!anonymize)
            for (ExamOwner owner : exam.getOwners()) {
                Element o = ex.addElement("owner");
                o.addAttribute("id", getId(idconv, "owner", String.valueOf(owner.getId())));
                o.addAttribute("name", owner.getName());
            }
        for (ExamPeriodPlacement period : exam.getPeriodPlacements()) {
            Element pe = ex.addElement("period").addAttribute("id", getId(idconv, "period", String.valueOf(period.getId())));
            int penalty = period.getExamPenalty();
            if (penalty != 0)
                pe.addAttribute("penalty", String.valueOf(penalty));
        }
        for (ExamRoomPlacement room : exam.getRoomPlacements()) {
            Element re = ex.addElement("room").addAttribute("id", getId(idconv, "room", String.valueOf(room.getId())));
            if (room.getPenalty() != 0)
                re.addAttribute("penalty", String.valueOf(room.getPenalty()));
            if (room.getMaxPenalty() != 100)
                re.addAttribute("maxPenalty", String.valueOf(room.getMaxPenalty()));
        }
        if (exam.hasAveragePeriod())
            ex.addAttribute("average", String.valueOf(exam.getAveragePeriod()));
        ExamPlacement p = (assignment == null ? null : assignment.getValue(exam));
        if (p != null && saveSolution) {
            Element asg = ex.addElement("assignment");
            asg.addElement("period").addAttribute("id", getId(idconv, "period", String.valueOf(p.getPeriod().getId())));
            for (ExamRoomPlacement r : p.getRoomPlacements()) {
                asg.addElement("room").addAttribute("id", getId(idconv, "room", String.valueOf(r.getId())));
            }
        }
        p = exam.getInitialAssignment();
        if (p != null && saveInitial) {
            Element ini = ex.addElement("initial");
            ini.addElement("period").addAttribute("id", getId(idconv, "period", String.valueOf(p.getPeriod().getId())));
            for (ExamRoomPlacement r : p.getRoomPlacements()) {
                ini.addElement("room").addAttribute("id", getId(idconv, "room", String.valueOf(r.getId())));
            }
        }
        p = exam.getBestAssignment();
        if (p != null && saveBest) {
            Element ini = ex.addElement("best");
            ini.addElement("period").addAttribute("id", getId(idconv, "period", String.valueOf(p.getPeriod().getId())));
            for (ExamRoomPlacement r : p.getRoomPlacements()) {
                ini.addElement("room").addAttribute("id", getId(idconv, "room", String.valueOf(r.getId())));
            }
        }
        if (iRoomSharing != null)
            iRoomSharing.save(exam, ex, anonymize ? IdConvertor.getInstance() : null);
    }
    Element students = root.addElement("students");
    for (ExamStudent student : getStudents()) {
        Element s = students.addElement("student");
        s.addAttribute("id", getId(idconv, "student", String.valueOf(student.getId())));
        for (Exam ex : student.variables()) {
            Element x = s.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(ex.getId())));
            if (!anonymize)
                for (ExamOwner owner : ex.getOwners(student)) {
                    x.addElement("owner").addAttribute("id", getId(idconv, "owner", String.valueOf(owner.getId())));
                }
        }
        for (ExamPeriod period : getPeriods()) {
            if (!student.isAvailable(period))
                s.addElement("period").addAttribute("id", getId(idconv, "period", String.valueOf(period.getId()))).addAttribute("available", "false");
        }
    }
    Element instructors = root.addElement("instructors");
    for (ExamInstructor instructor : getInstructors()) {
        Element i = instructors.addElement("instructor");
        i.addAttribute("id", getId(idconv, "instructor", String.valueOf(instructor.getId())));
        if (!anonymize && instructor.hasName())
            i.addAttribute("name", instructor.getName());
        for (Exam ex : instructor.variables()) {
            Element x = i.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(ex.getId())));
            if (!anonymize)
                for (ExamOwner owner : ex.getOwners(instructor)) {
                    x.addElement("owner").addAttribute("id", getId(idconv, "owner", String.valueOf(owner.getId())));
                }
        }
        for (ExamPeriod period : getPeriods()) {
            if (!instructor.isAvailable(period))
                i.addElement("period").addAttribute("id", getId(idconv, "period", String.valueOf(period.getId()))).addAttribute("available", "false");
        }
    }
    Element distConstraints = root.addElement("constraints");
    for (ExamDistributionConstraint distConstraint : getDistributionConstraints()) {
        Element dc = distConstraints.addElement(distConstraint.getTypeString());
        dc.addAttribute("id", getId(idconv, "constraint", String.valueOf(distConstraint.getId())));
        if (!distConstraint.isHard()) {
            dc.addAttribute("hard", "false");
            dc.addAttribute("weight", String.valueOf(distConstraint.getWeight()));
        }
        for (Exam exam : distConstraint.variables()) {
            dc.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(exam.getId())));
        }
    }
    if (saveConflictTable && assignment != null) {
        Element conflicts = root.addElement("conflicts");
        Map<ExamStudent, Set<Exam>> studentsOfPreviousPeriod = null;
        for (ExamPeriod period : getPeriods()) {
            Map<ExamStudent, Set<Exam>> studentsOfPeriod = getStudentsOfPeriod(assignment, period);
            for (Map.Entry<ExamStudent, Set<Exam>> entry : studentsOfPeriod.entrySet()) {
                ExamStudent student = entry.getKey();
                Set<Exam> examsOfStudent = entry.getValue();
                if (examsOfStudent.size() > 1) {
                    Element dir = conflicts.addElement("direct").addAttribute("student", getId(idconv, "student", String.valueOf(student.getId())));
                    for (Exam exam : examsOfStudent) {
                        dir.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(exam.getId())));
                    }
                }
                if (examsOfStudent.size() > 0 && studentsOfPreviousPeriod != null && (isDayBreakBackToBack() || period.prev().getDay() == period.getDay())) {
                    Set<Exam> previousExamsOfStudent = studentsOfPreviousPeriod.get(student);
                    if (previousExamsOfStudent != null) {
                        for (Exam ex1 : previousExamsOfStudent) for (Exam ex2 : examsOfStudent) {
                            Element btb = conflicts.addElement("back-to-back").addAttribute("student", getId(idconv, "student", String.valueOf(student.getId())));
                            btb.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(ex1.getId())));
                            btb.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(ex2.getId())));
                            if (getBackToBackDistance() >= 0 && period.prev().getDay() == period.getDay()) {
                                double dist = (assignment.getValue(ex1)).getDistanceInMeters(assignment.getValue(ex2));
                                if (dist > 0)
                                    btb.addAttribute("distance", String.valueOf(dist));
                            }
                        }
                    }
                }
            }
            if (period.next() == null || period.next().getDay() != period.getDay()) {
                Map<ExamStudent, Set<Exam>> studentsOfDay = getStudentsOfDay(assignment, period);
                for (Map.Entry<ExamStudent, Set<Exam>> entry : studentsOfDay.entrySet()) {
                    ExamStudent student = entry.getKey();
                    Set<Exam> examsOfStudent = entry.getValue();
                    if (examsOfStudent.size() > 2) {
                        Element mt2 = conflicts.addElement("more-2-day").addAttribute("student", getId(idconv, "student", String.valueOf(student.getId())));
                        for (Exam exam : examsOfStudent) {
                            mt2.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(exam.getId())));
                        }
                    }
                }
            }
            studentsOfPreviousPeriod = studentsOfPeriod;
        }
    /*
            Element conflicts = root.addElement("conflicts");
            for (ExamStudent student : getStudents()) {
                for (ExamPeriod period : getPeriods()) {
                    int nrExams = student.getExams(assignment, period).size();
                    if (nrExams > 1) {
                        Element dir = conflicts.addElement("direct").addAttribute("student", getId(idconv, "student", String.valueOf(student.getId())));
                        for (Exam exam : student.getExams(assignment, period)) {
                            dir.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(exam.getId())));
                        }
                    }
                    if (nrExams > 0) {
                        if (period.next() != null && !student.getExams(assignment, period.next()).isEmpty()
                                && (!isDayBreakBackToBack() || period.next().getDay() == period.getDay())) {
                            for (Exam ex1 : student.getExams(assignment, period)) {
                                for (Exam ex2 : student.getExams(assignment, period.next())) {
                                    Element btb = conflicts.addElement("back-to-back").addAttribute("student", getId(idconv, "student", String.valueOf(student.getId())));
                                    btb.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(ex1.getId())));
                                    btb.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(ex2.getId())));
                                    if (getBackToBackDistance() >= 0) {
                                        double dist = (assignment.getValue(ex1)).getDistanceInMeters(assignment.getValue(ex2));
                                        if (dist > 0)
                                            btb.addAttribute("distance", String.valueOf(dist));
                                    }
                                }
                            }
                        }
                    }
                    if (period.next() == null || period.next().getDay() != period.getDay()) {
                        int nrExamsADay = student.getExamsADay(assignment, period.getDay()).size();
                        if (nrExamsADay > 2) {
                            Element mt2 = conflicts.addElement("more-2-day").addAttribute("student", getId(idconv, "student", String.valueOf(student.getId())));
                            for (Exam exam : student.getExamsADay(assignment, period.getDay())) {
                                mt2.addElement("exam").addAttribute("id", getId(idconv, "exam", String.valueOf(exam.getId())));
                            }
                        }
                    }
                }
            }
            */
    }
    return document;
}
Also used : TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) Element(org.dom4j.Element) Document(org.dom4j.Document) TreeSet(java.util.TreeSet) Date(java.util.Date) Constraint(org.cpsolver.ifs.model.Constraint) ExamCriterion(org.cpsolver.exam.criteria.ExamCriterion) HashMap(java.util.HashMap) Map(java.util.Map)

Example 9 with Constraint

use of org.cpsolver.ifs.model.Constraint in project cpsolver by UniTime.

the class ExamModel method load.

/**
 * Load model (including its solution) from XML.
 * @param document XML document
 * @param assignment assignment to be loaded
 * @param saveBest callback executed once the best assignment is loaded and assigned
 * @return true if successfully loaded
 */
public boolean load(Document document, Assignment<Exam, ExamPlacement> assignment, Callback saveBest) {
    boolean loadInitial = getProperties().getPropertyBoolean("Xml.LoadInitial", true);
    boolean loadBest = getProperties().getPropertyBoolean("Xml.LoadBest", true);
    boolean loadSolution = getProperties().getPropertyBoolean("Xml.LoadSolution", true);
    boolean loadParams = getProperties().getPropertyBoolean("Xml.LoadParameters", false);
    Integer softPeriods = getProperties().getPropertyInteger("Exam.SoftPeriods", null);
    Integer softRooms = getProperties().getPropertyInteger("Exam.SoftRooms", null);
    Integer softDistributions = getProperties().getPropertyInteger("Exam.SoftDistributions", null);
    Element root = document.getRootElement();
    if (!"examtt".equals(root.getName()))
        return false;
    if (root.attribute("campus") != null)
        getProperties().setProperty("Data.Campus", root.attributeValue("campus"));
    else if (root.attribute("initiative") != null)
        getProperties().setProperty("Data.Initiative", root.attributeValue("initiative"));
    if (root.attribute("term") != null)
        getProperties().setProperty("Data.Term", root.attributeValue("term"));
    if (root.attribute("year") != null)
        getProperties().setProperty("Data.Year", root.attributeValue("year"));
    if (loadParams && root.element("parameters") != null) {
        Map<String, String> params = new HashMap<String, String>();
        for (Iterator<?> i = root.element("parameters").elementIterator("property"); i.hasNext(); ) {
            Element e = (Element) i.next();
            params.put(e.attributeValue("name"), e.attributeValue("value"));
        }
        for (Criterion<Exam, ExamPlacement> criterion : getCriteria()) {
            if (criterion instanceof ExamCriterion)
                ((ExamCriterion) criterion).setXmlParameters(params);
        }
        try {
            setMaxRooms(Integer.valueOf(params.get("maxRooms")));
        } catch (NumberFormatException e) {
        } catch (NullPointerException e) {
        }
        setCheckForPeriodOverlaps("true".equalsIgnoreCase(params.get("checkForPeriodOverlaps")));
    }
    for (Iterator<?> i = root.element("periods").elementIterator("period"); i.hasNext(); ) {
        Element e = (Element) i.next();
        ExamPeriod p = addPeriod(Long.valueOf(e.attributeValue("id")), e.attributeValue("day"), e.attributeValue("time"), Integer.parseInt(e.attributeValue("length")), Integer.parseInt(e.attributeValue("penalty") == null ? e.attributeValue("weight", "0") : e.attributeValue("penalty")));
        if (e.attributeValue("start") != null)
            p.setStartTime(Integer.valueOf(e.attributeValue("start")));
    }
    HashMap<Long, ExamRoom> rooms = new HashMap<Long, ExamRoom>();
    HashMap<String, ArrayList<ExamRoom>> roomGroups = new HashMap<String, ArrayList<ExamRoom>>();
    for (Iterator<?> i = root.element("rooms").elementIterator("room"); i.hasNext(); ) {
        Element e = (Element) i.next();
        String coords = e.attributeValue("coordinates");
        ExamRoom room = new ExamRoom(this, Long.parseLong(e.attributeValue("id")), e.attributeValue("name"), Integer.parseInt(e.attributeValue("size")), Integer.parseInt(e.attributeValue("alt")), (coords == null ? null : Double.valueOf(coords.substring(0, coords.indexOf(',')))), (coords == null ? null : Double.valueOf(coords.substring(coords.indexOf(',') + 1))));
        room.setHard("true".equalsIgnoreCase(e.attributeValue("hard", "true")));
        addConstraint(room);
        getRooms().add(room);
        rooms.put(Long.valueOf(room.getId()), room);
        for (Iterator<?> j = e.elementIterator("period"); j.hasNext(); ) {
            Element pe = (Element) j.next();
            ExamPeriod period = getPeriod(Long.valueOf(pe.attributeValue("id")));
            if (period == null)
                continue;
            if ("false".equals(pe.attributeValue("available"))) {
                if (softRooms == null)
                    room.setAvailable(period, false);
                else
                    room.setPenalty(period, softRooms);
            } else
                room.setPenalty(period, Integer.parseInt(pe.attributeValue("penalty")));
        }
        String av = e.attributeValue("available");
        if (av != null) {
            for (int j = 0; j < getPeriods().size(); j++) if ('0' == av.charAt(j))
                room.setAvailable(getPeriods().get(j), false);
        }
        String g = e.attributeValue("groups");
        if (g != null) {
            for (StringTokenizer s = new StringTokenizer(g, ","); s.hasMoreTokens(); ) {
                String gr = s.nextToken();
                ArrayList<ExamRoom> roomsThisGrop = roomGroups.get(gr);
                if (roomsThisGrop == null) {
                    roomsThisGrop = new ArrayList<ExamRoom>();
                    roomGroups.put(gr, roomsThisGrop);
                }
                roomsThisGrop.add(room);
            }
        }
        for (Iterator<?> j = e.elementIterator("travel-time"); j.hasNext(); ) {
            Element travelTimeEl = (Element) j.next();
            getDistanceMetric().addTravelTime(room.getId(), Long.valueOf(travelTimeEl.attributeValue("id")), Integer.valueOf(travelTimeEl.attributeValue("minutes")));
        }
    }
    ArrayList<ExamPlacement> assignments = new ArrayList<ExamPlacement>();
    HashMap<Long, Exam> exams = new HashMap<Long, Exam>();
    HashMap<Long, ExamOwner> courseSections = new HashMap<Long, ExamOwner>();
    for (Iterator<?> i = root.element("exams").elementIterator("exam"); i.hasNext(); ) {
        Element e = (Element) i.next();
        ArrayList<ExamPeriodPlacement> periodPlacements = new ArrayList<ExamPeriodPlacement>();
        if (softPeriods != null) {
            for (ExamPeriod period : getPeriods()) {
                int penalty = softPeriods;
                for (Iterator<?> j = e.elementIterator("period"); j.hasNext(); ) {
                    Element pe = (Element) j.next();
                    if (period.getId().equals(Long.valueOf(pe.attributeValue("id")))) {
                        penalty = Integer.parseInt(pe.attributeValue("penalty", "0"));
                        break;
                    }
                }
                periodPlacements.add(new ExamPeriodPlacement(period, penalty));
            }
        } else {
            for (Iterator<?> j = e.elementIterator("period"); j.hasNext(); ) {
                Element pe = (Element) j.next();
                ExamPeriod p = getPeriod(Long.valueOf(pe.attributeValue("id")));
                if (p != null)
                    periodPlacements.add(new ExamPeriodPlacement(p, Integer.parseInt(pe.attributeValue("penalty", "0"))));
            }
        }
        ArrayList<ExamRoomPlacement> roomPlacements = new ArrayList<ExamRoomPlacement>();
        if (softRooms != null) {
            for (ExamRoom room : getRooms()) {
                boolean av = false;
                for (ExamPeriodPlacement p : periodPlacements) {
                    if (room.isAvailable(p.getPeriod()) && room.getPenalty(p.getPeriod()) != softRooms) {
                        av = true;
                        break;
                    }
                }
                if (!av)
                    continue;
                int penalty = softRooms, maxPenalty = softRooms;
                for (Iterator<?> j = e.elementIterator("room"); j.hasNext(); ) {
                    Element re = (Element) j.next();
                    if (room.getId() == Long.parseLong(re.attributeValue("id"))) {
                        penalty = Integer.parseInt(re.attributeValue("penalty", "0"));
                        maxPenalty = Integer.parseInt(re.attributeValue("maxPenalty", softRooms.toString()));
                    }
                }
                roomPlacements.add(new ExamRoomPlacement(room, penalty, maxPenalty));
            }
        } else {
            for (Iterator<?> j = e.elementIterator("room"); j.hasNext(); ) {
                Element re = (Element) j.next();
                ExamRoomPlacement room = new ExamRoomPlacement(rooms.get(Long.valueOf(re.attributeValue("id"))), Integer.parseInt(re.attributeValue("penalty", "0")), Integer.parseInt(re.attributeValue("maxPenalty", "100")));
                if (room.getRoom().isAvailable())
                    roomPlacements.add(room);
            }
        }
        String g = e.attributeValue("groups");
        if (g != null) {
            HashMap<ExamRoom, Integer> allRooms = new HashMap<ExamRoom, Integer>();
            for (StringTokenizer s = new StringTokenizer(g, ","); s.hasMoreTokens(); ) {
                String gr = s.nextToken();
                ArrayList<ExamRoom> roomsThisGrop = roomGroups.get(gr);
                if (roomsThisGrop != null)
                    for (ExamRoom r : roomsThisGrop) allRooms.put(r, 0);
            }
            for (Iterator<?> j = e.elementIterator("original-room"); j.hasNext(); ) {
                allRooms.put((rooms.get(Long.valueOf(((Element) j.next()).attributeValue("id")))), Integer.valueOf(-1));
            }
            for (Map.Entry<ExamRoom, Integer> entry : allRooms.entrySet()) {
                ExamRoomPlacement room = new ExamRoomPlacement(entry.getKey(), entry.getValue(), 100);
                roomPlacements.add(room);
            }
            if (periodPlacements.isEmpty()) {
                for (ExamPeriod p : getPeriods()) {
                    periodPlacements.add(new ExamPeriodPlacement(p, 0));
                }
            }
        }
        Exam exam = new Exam(Long.parseLong(e.attributeValue("id")), e.attributeValue("name"), Integer.parseInt(e.attributeValue("length")), "true".equals(e.attributeValue("alt")), (e.attribute("maxRooms") == null ? getMaxRooms() : Integer.parseInt(e.attributeValue("maxRooms"))), Integer.parseInt(e.attributeValue("minSize", "0")), periodPlacements, roomPlacements);
        if (e.attributeValue("size") != null)
            exam.setSizeOverride(Integer.valueOf(e.attributeValue("size")));
        if (e.attributeValue("printOffset") != null)
            exam.setPrintOffset(Integer.valueOf(e.attributeValue("printOffset")));
        exams.put(Long.valueOf(exam.getId()), exam);
        addVariable(exam);
        if (e.attribute("average") != null)
            exam.setAveragePeriod(Integer.parseInt(e.attributeValue("average")));
        Element asg = e.element("assignment");
        if (asg != null && loadSolution) {
            Element per = asg.element("period");
            if (per != null) {
                HashSet<ExamRoomPlacement> rp = new HashSet<ExamRoomPlacement>();
                for (Iterator<?> j = asg.elementIterator("room"); j.hasNext(); ) rp.add(exam.getRoomPlacement(Long.parseLong(((Element) j.next()).attributeValue("id"))));
                ExamPeriodPlacement pp = exam.getPeriodPlacement(Long.valueOf(per.attributeValue("id")));
                if (pp != null)
                    assignments.add(new ExamPlacement(exam, pp, rp));
            }
        }
        Element ini = e.element("initial");
        if (ini != null && loadInitial) {
            Element per = ini.element("period");
            if (per != null) {
                HashSet<ExamRoomPlacement> rp = new HashSet<ExamRoomPlacement>();
                for (Iterator<?> j = ini.elementIterator("room"); j.hasNext(); ) rp.add(exam.getRoomPlacement(Long.parseLong(((Element) j.next()).attributeValue("id"))));
                ExamPeriodPlacement pp = exam.getPeriodPlacement(Long.valueOf(per.attributeValue("id")));
                if (pp != null)
                    exam.setInitialAssignment(new ExamPlacement(exam, pp, rp));
            }
        }
        Element best = e.element("best");
        if (best != null && loadBest) {
            Element per = best.element("period");
            if (per != null) {
                HashSet<ExamRoomPlacement> rp = new HashSet<ExamRoomPlacement>();
                for (Iterator<?> j = best.elementIterator("room"); j.hasNext(); ) rp.add(exam.getRoomPlacement(Long.parseLong(((Element) j.next()).attributeValue("id"))));
                ExamPeriodPlacement pp = exam.getPeriodPlacement(Long.valueOf(per.attributeValue("id")));
                if (pp != null)
                    exam.setBestAssignment(new ExamPlacement(exam, pp, rp), 0);
            }
        }
        for (Iterator<?> j = e.elementIterator("owner"); j.hasNext(); ) {
            Element f = (Element) j.next();
            ExamOwner owner = new ExamOwner(exam, Long.parseLong(f.attributeValue("id")), f.attributeValue("name"));
            exam.getOwners().add(owner);
            courseSections.put(Long.valueOf(owner.getId()), owner);
        }
        if (iRoomSharing != null)
            iRoomSharing.load(exam, e);
    }
    for (Iterator<?> i = root.element("students").elementIterator("student"); i.hasNext(); ) {
        Element e = (Element) i.next();
        ExamStudent student = new ExamStudent(this, Long.parseLong(e.attributeValue("id")));
        for (Iterator<?> j = e.elementIterator("exam"); j.hasNext(); ) {
            Element x = (Element) j.next();
            Exam ex = exams.get(Long.valueOf(x.attributeValue("id")));
            student.addVariable(ex);
            for (Iterator<?> k = x.elementIterator("owner"); k.hasNext(); ) {
                Element f = (Element) k.next();
                ExamOwner owner = courseSections.get(Long.valueOf(f.attributeValue("id")));
                student.getOwners().add(owner);
                owner.getStudents().add(student);
            }
        }
        String available = e.attributeValue("available");
        if (available != null)
            for (ExamPeriod period : getPeriods()) {
                if (available.charAt(period.getIndex()) == '0')
                    student.setAvailable(period.getIndex(), false);
            }
        for (Iterator<?> j = e.elementIterator("period"); j.hasNext(); ) {
            Element pe = (Element) j.next();
            ExamPeriod period = getPeriod(Long.valueOf(pe.attributeValue("id")));
            if (period == null)
                continue;
            if ("false".equals(pe.attributeValue("available")))
                student.setAvailable(period.getIndex(), false);
        }
        addConstraint(student);
        getStudents().add(student);
    }
    if (root.element("instructors") != null)
        for (Iterator<?> i = root.element("instructors").elementIterator("instructor"); i.hasNext(); ) {
            Element e = (Element) i.next();
            ExamInstructor instructor = new ExamInstructor(this, Long.parseLong(e.attributeValue("id")), e.attributeValue("name"));
            for (Iterator<?> j = e.elementIterator("exam"); j.hasNext(); ) {
                Element x = (Element) j.next();
                Exam ex = exams.get(Long.valueOf(x.attributeValue("id")));
                instructor.addVariable(ex);
                for (Iterator<?> k = x.elementIterator("owner"); k.hasNext(); ) {
                    Element f = (Element) k.next();
                    ExamOwner owner = courseSections.get(Long.valueOf(f.attributeValue("id")));
                    instructor.getOwners().add(owner);
                    owner.getIntructors().add(instructor);
                }
            }
            String available = e.attributeValue("available");
            if (available != null)
                for (ExamPeriod period : getPeriods()) {
                    if (available.charAt(period.getIndex()) == '0')
                        instructor.setAvailable(period.getIndex(), false);
                }
            for (Iterator<?> j = e.elementIterator("period"); j.hasNext(); ) {
                Element pe = (Element) j.next();
                ExamPeriod period = getPeriod(Long.valueOf(pe.attributeValue("id")));
                if (period == null)
                    continue;
                if ("false".equals(pe.attributeValue("available")))
                    instructor.setAvailable(period.getIndex(), false);
            }
            addConstraint(instructor);
            getInstructors().add(instructor);
        }
    if (root.element("constraints") != null)
        for (Iterator<?> i = root.element("constraints").elementIterator(); i.hasNext(); ) {
            Element e = (Element) i.next();
            ExamDistributionConstraint dc = new ExamDistributionConstraint(Long.parseLong(e.attributeValue("id")), e.getName(), softDistributions != null ? false : "true".equals(e.attributeValue("hard", "true")), (softDistributions != null && "true".equals(e.attributeValue("hard", "true")) ? softDistributions : Integer.parseInt(e.attributeValue("weight", "0"))));
            for (Iterator<?> j = e.elementIterator("exam"); j.hasNext(); ) {
                dc.addVariable(exams.get(Long.valueOf(((Element) j.next()).attributeValue("id"))));
            }
            addConstraint(dc);
            getDistributionConstraints().add(dc);
        }
    init();
    if (loadBest && saveBest != null && assignment != null) {
        for (Exam exam : variables()) {
            ExamPlacement placement = exam.getBestAssignment();
            if (placement == null)
                continue;
            assignment.assign(0, placement);
        }
        saveBest.execute();
        for (Exam exam : variables()) {
            if (assignment.getValue(exam) != null)
                assignment.unassign(0, exam);
        }
    }
    if (assignment != null) {
        for (ExamPlacement placement : assignments) {
            Exam exam = placement.variable();
            Set<ExamPlacement> conf = conflictValues(assignment, placement);
            if (!conf.isEmpty()) {
                for (Map.Entry<Constraint<Exam, ExamPlacement>, Set<ExamPlacement>> entry : conflictConstraints(assignment, placement).entrySet()) {
                    Constraint<Exam, ExamPlacement> constraint = entry.getKey();
                    Set<ExamPlacement> values = entry.getValue();
                    if (constraint instanceof ExamStudent) {
                        ((ExamStudent) constraint).setAllowDirectConflicts(true);
                        exam.setAllowDirectConflicts(true);
                        for (ExamPlacement p : values) p.variable().setAllowDirectConflicts(true);
                    }
                }
                conf = conflictValues(assignment, placement);
            }
            if (conf.isEmpty()) {
                assignment.assign(0, placement);
            } else {
                sLog.error("Unable to assign " + exam.getInitialAssignment().getName() + " to exam " + exam.getName());
                sLog.error("Conflicts:" + ToolBox.dict2string(conflictConstraints(assignment, exam.getInitialAssignment()), 2));
            }
        }
    }
    return true;
}
Also used : TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) Constraint(org.cpsolver.ifs.model.Constraint) Element(org.dom4j.Element) ArrayList(java.util.ArrayList) Iterator(java.util.Iterator) HashSet(java.util.HashSet) Constraint(org.cpsolver.ifs.model.Constraint) StringTokenizer(java.util.StringTokenizer) ExamCriterion(org.cpsolver.exam.criteria.ExamCriterion) HashMap(java.util.HashMap) Map(java.util.Map)

Example 10 with Constraint

use of org.cpsolver.ifs.model.Constraint in project cpsolver by UniTime.

the class Test method test.

private static void test(DataProperties properties) throws Exception {
    boolean sameProblemStep = properties.getPropertyBoolean("CSP.SameProblemEachStep", false);
    boolean sameProblemTest = properties.getPropertyBoolean("CSP.SameProblemEachTest", false);
    int nrVars = properties.getPropertyInt("CSP.NrVariables", 20);
    int nrKernels = properties.getPropertyInt("CSP.NrKernels", 2);
    int nrKernelVariables = properties.getPropertyInt("CSP.KernelSize", 8);
    int nrVariablesMin = properties.getPropertyInt("CSP.NrVariablesMin", nrVars);
    int nrVariablesMax = properties.getPropertyInt("CSP.NrVariablesMax", nrVars);
    int nrVariablesStep = properties.getPropertyInt("CSP.NrVariablesStep", 1);
    int nrValues = properties.getPropertyInt("CSP.DomainSize", 10);
    double nrValuesRatio = properties.getPropertyDouble("CSP.DomainSizeRatio", -1);
    float kernelTightness = properties.getPropertyFloat("CSP.KernelTightness", 0.097f);
    float kernelDensity = properties.getPropertyFloat("CSP.KernelDensity", 0.097f);
    float tightnessInit = properties.getPropertyFloat("CSP.Tightness", 0.4f);
    float tightnessMin = properties.getPropertyFloat("CSP.TightnessMin", tightnessInit);
    float tightnessMax = properties.getPropertyFloat("CSP.TightnessMax", tightnessInit) + 1e-6f;
    float tightnessStep = properties.getPropertyFloat("CSP.TightnessStep", 0.1f);
    float densityInit = properties.getPropertyFloat("CSP.Density", 0.4f);
    float densityMin = properties.getPropertyFloat("CSP.DensityMin", densityInit);
    float densityMax = properties.getPropertyFloat("CSP.DensityMax", densityInit) + 1e-6f;
    float densityStep = properties.getPropertyFloat("CSP.DensityStep", 0.1f);
    long seed = properties.getPropertyLong("CSP.Seed", System.currentTimeMillis());
    int nrTests = properties.getPropertyInt("CPS.NrTests", 10);
    boolean mpp = properties.getPropertyBoolean("General.MPP", false);
    PrintWriter logStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator + "rcsp_" + nrVariablesMin + "_" + nrValues + ".csv"));
    PrintWriter logAvgStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator + "avg_stat.csv"));
    PrintWriter log = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator + "info.txt"));
    logStat.println("testNr;nrVars;nrVals;density[%];tightness[%];time[s];iters;speed[it/s];unassConstr;assigned;assigned[%]" + (mpp ? ";perts;perts[%]" : "") + ";value;totalValue");
    logAvgStat.println("nrVars;nrVals;density[%];tightness[%];time[s];RMStime[s];iters;RMSiters;speed[it/s];unassConst;assigned;RMSassigned;assigned[%]" + (mpp ? ";perts;RMSperts;perts[%]" : "") + ";value;RMSvalue;totalValue;RMStotalValue");
    System.out.println("Number of variables: " + nrVariablesMin + " .. " + nrVariablesMax + "  (step=" + nrVariablesStep + ")");
    System.out.println("Density:             " + densityMin + " .. " + densityMax + "  (step=" + densityStep + ")");
    System.out.println("Tightness:           " + tightnessMin + " .. " + tightnessMax + "  (step=" + tightnessStep + ")");
    for (int nrVariables = nrVariablesMin; nrVariables <= nrVariablesMax; nrVariables += nrVariablesStep) {
        if (nrValuesRatio > 0.0)
            nrValues = (int) Math.round(nrValuesRatio * nrVariables);
        for (float density = densityMin; density <= densityMax; density += densityStep) {
            for (float tightness = tightnessMin; tightness <= tightnessMax; tightness += tightnessStep) {
                log.println("CSP{#Var=" + nrVariables + ", #Val=" + nrValues + ", P(density)=" + sDoubleFormat.format(100.0 * density) + "%, P(tighness)=" + sDoubleFormat.format(100.0 * tightness) + ", " + nrKernels + "x Kernel{#Var=" + nrKernelVariables + ", P(density)=" + sDoubleFormat.format(100.0 * kernelDensity) + "%, P(tighness)=" + sDoubleFormat.format(100.0 * kernelTightness) + "%}}");
                double sumTime = 0;
                double sumTime2 = 0;
                int sumIters = 0;
                int sumIters2 = 0;
                int sumConfl = 0;
                int sumAssign = 0;
                int sumAssign2 = 0;
                int sumPert = 0;
                int sumPert2 = 0;
                int sumVal = 0;
                int sumVal2 = 0;
                int sumTotalVal = 0;
                int sumTotalVal2 = 0;
                for (int test = 1; test <= nrTests; test++) {
                    log.println("  " + test + ". test");
                    log.flush();
                    properties.setProperty("CSP.NrVariables", String.valueOf(nrVariables));
                    properties.setProperty("CSP.Tightness", String.valueOf(tightness));
                    properties.setProperty("CSP.Density", String.valueOf(density));
                    long currentSeed = (seed * 1000000L) + (1000 * (long) ((sameProblemStep ? densityMin : density) * 1000.0)) + ((long) ((sameProblemStep ? tightnessMin : tightness) * 1000.0));
                    currentSeed = (currentSeed * nrTests) + (sameProblemTest ? 0 : test - 1);
                    sLogger.debug("Seed: " + currentSeed);
                    StructuredCSPModel csp = new StructuredCSPModel(properties, currentSeed);
                    Solver<CSPVariable, CSPValue> s = new Solver<CSPVariable, CSPValue>(properties);
                    s.setInitalSolution(csp);
                    s.currentSolution().clearBest();
                    s.start();
                    try {
                        s.getSolverThread().join();
                    } catch (NullPointerException npe) {
                    }
                    if (s.lastSolution().getBestInfo() == null)
                        sLogger.error("No solution found :-(");
                    sLogger.debug("Last solution:" + s.lastSolution().getInfo());
                    Solution<CSPVariable, CSPValue> best = s.lastSolution();
                    sLogger.debug("Best solution:" + s.lastSolution().getBestInfo());
                    best.restoreBest();
                    int val = 0;
                    for (CSPValue v : best.getAssignment().assignedValues()) val += (int) v.toDouble();
                    int totalVal = val + (best.getModel().unassignedVariables(best.getAssignment()).size() * nrValues);
                    sLogger.debug("Last solution:" + best.getInfo());
                    logStat.println(test + ";" + nrVariables + ";" + nrValues + ";" + sDoubleFormat.format(density) + ";" + sDoubleFormat.format(tightness) + ";" + sDoubleFormat.format(best.getTime()) + ";" + best.getIteration() + ";" + sDoubleFormat.format((best.getIteration()) / best.getTime()) + ";" + best.getModel().unassignedHardConstraints(best.getAssignment()).size() + ";" + best.getModel().assignedVariables(best.getAssignment()).size() + ";" + sDoubleFormat.format(100.0 * best.getModel().assignedVariables(best.getAssignment()).size() / best.getModel().variables().size()) + (mpp ? ";" + (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel().unassignedVariables(best.getAssignment()).size()) + ";" + sDoubleFormat.format(100.0 * (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel().unassignedVariables(best.getAssignment()).size()) / best.getModel().variables().size()) : "") + ";" + val + ";" + totalVal);
                    log.println("    seed:         " + currentSeed);
                    log.println("    constraints:  " + best.getModel().constraints().size());
                    for (Iterator<Constraint<CSPVariable, CSPValue>> i = best.getModel().constraints().iterator(); i.hasNext(); ) {
                        CSPBinaryConstraint c = (CSPBinaryConstraint) i.next();
                        log.println("      " + c.getName() + " (" + c.first().getName() + "," + c.second().getName() + ")");
                        for (CSPValue v0 : c.first().values(best.getAssignment())) {
                            log.print("        ");
                            for (CSPValue v1 : c.second().values(best.getAssignment())) log.print(c.isConsistent(v0, v1) ? "1 " : "0 ");
                        }
                        log.println();
                    }
                    log.println("    time:         " + sDoubleFormat.format(best.getTime()) + " s");
                    log.println("    iteration:    " + best.getIteration());
                    log.println("    speed:        " + sDoubleFormat.format((best.getIteration()) / best.getTime()) + " it/s");
                    log.println("    assigned:     " + best.getModel().assignedVariables(best.getAssignment()).size() + " (" + sDoubleFormat.format(100.0 * best.getModel().assignedVariables(best.getAssignment()).size() / best.getModel().variables().size()) + "%)");
                    log.println("    total value:  " + val);
                    if (mpp)
                        log.println("    perturbations:" + (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel().unassignedVariables(best.getAssignment()).size()) + " (" + sDoubleFormat.format(100.0 * (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel().unassignedVariables(best.getAssignment()).size()) / best.getModel().variables().size()) + "%)");
                    log.print("    solution:     ");
                    for (CSPVariable v : ((CSPModel) best.getModel()).variables()) {
                        if (v.getBestAssignment() == null)
                            continue;
                        log.print(v.getName() + "=" + v.getBestAssignment().getName());
                        log.print(", ");
                    }
                    log.println();
                    sumTime += best.getTime();
                    sumTime2 += best.getTime() * best.getTime();
                    sumIters += best.getIteration();
                    sumIters2 += best.getIteration() * best.getIteration();
                    sumConfl += best.getModel().unassignedHardConstraints(best.getAssignment()).size();
                    sumAssign += best.getModel().assignedVariables(best.getAssignment()).size();
                    sumAssign2 += best.getModel().assignedVariables(best.getAssignment()).size() * best.getModel().assignedVariables(best.getAssignment()).size();
                    sumVal += val;
                    sumVal2 += val * val;
                    sumTotalVal += totalVal;
                    sumTotalVal2 += totalVal * totalVal;
                    if (mpp) {
                        sumPert += (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel().unassignedVariables(best.getAssignment()).size());
                        sumPert2 += (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel().unassignedVariables(best.getAssignment()).size()) * (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel().unassignedVariables(best.getAssignment()).size());
                    }
                    log.flush();
                    logStat.flush();
                }
                logAvgStat.println(nrVariables + ";" + nrValues + ";" + sDoubleFormat.format(density) + ";" + sDoubleFormat.format(tightness) + ";" + sDoubleFormat.format(sumTime / nrTests) + ";" + sDoubleFormat.format(ToolBox.rms(nrTests, sumTime, sumTime2)) + ";" + sDoubleFormat.format(((double) sumIters) / nrTests) + ";" + sDoubleFormat.format(ToolBox.rms(nrTests, sumIters, sumIters2)) + ";" + sDoubleFormat.format((sumIters) / sumTime) + ";" + sDoubleFormat.format(((double) sumConfl) / nrTests) + ";" + sDoubleFormat.format(((double) sumAssign) / nrTests) + ";" + sDoubleFormat.format(ToolBox.rms(nrTests, sumAssign, sumAssign2)) + ";" + sDoubleFormat.format(100.0 * (sumAssign) / (nrVariables * nrTests)) + (mpp ? ";" + sDoubleFormat.format(((double) sumPert) / nrTests) + ";" + sDoubleFormat.format(ToolBox.rms(nrTests, sumPert, sumPert2)) + ";" + sDoubleFormat.format(100.0 * (sumPert) / (nrVariables * nrTests)) : "") + ";" + sDoubleFormat.format(((double) sumVal) / (nrTests * nrVariables)) + ";" + sDoubleFormat.format(ToolBox.rms(nrTests, (double) sumVal / nrVariables, (double) sumVal2 / (nrVariables * nrVariables))) + ";" + sDoubleFormat.format(((double) sumTotalVal) / nrTests) + ";" + sDoubleFormat.format(ToolBox.rms(nrTests, sumTotalVal, sumTotalVal2)));
                logAvgStat.flush();
            }
        }
    }
    log.flush();
    log.close();
    logStat.flush();
    logStat.close();
    logAvgStat.flush();
    logAvgStat.close();
}
Also used : Solver(org.cpsolver.ifs.solver.Solver) Constraint(org.cpsolver.ifs.model.Constraint) FileWriter(java.io.FileWriter) Constraint(org.cpsolver.ifs.model.Constraint) PrintWriter(java.io.PrintWriter)

Aggregations

Constraint (org.cpsolver.ifs.model.Constraint)18 ArrayList (java.util.ArrayList)11 HashSet (java.util.HashSet)10 HashMap (java.util.HashMap)8 TreeSet (java.util.TreeSet)7 Lecture (org.cpsolver.coursett.model.Lecture)7 Placement (org.cpsolver.coursett.model.Placement)7 Element (org.dom4j.Element)7 Map (java.util.Map)6 Set (java.util.Set)6 BitSet (java.util.BitSet)4 List (java.util.List)4 GroupConstraint (org.cpsolver.coursett.constraint.GroupConstraint)4 InstructorConstraint (org.cpsolver.coursett.constraint.InstructorConstraint)4 RoomConstraint (org.cpsolver.coursett.constraint.RoomConstraint)4 SpreadConstraint (org.cpsolver.coursett.constraint.SpreadConstraint)4 RoomLocation (org.cpsolver.coursett.model.RoomLocation)4 Student (org.cpsolver.coursett.model.Student)4 FileWriter (java.io.FileWriter)3 PrintWriter (java.io.PrintWriter)3