org.cpsolver.exam.model

## Class Exam

- java.lang.Object
- - org.cpsolver.ifs.model.Variable<Exam,ExamPlacement>
  - - org.cpsolver.exam.model.Exam

- All Implemented Interfaces:
    Comparable<Exam>

      public class Exam
      extends Variable<Exam,ExamPlacement>

  Representation of an exam (problem variable). Each exam has defined a length (in minutes), type (whether it is a section or a course exam), seating type (whether it requires normal or alternate seating) and a maximal number of rooms. If the maximal number of rooms is zero, the exam will be timetabled only in time (it does not require a room).
  An exam can be only assigned to a period `ExamPeriod` that is long enough (see `ExamPeriod.getLength()`) and that is available for the exam (see `getPeriodPlacements()`).
  A set of rooms that are available in the given period (see `ExamRoom.isAvailable(ExamPeriod)`, `ExamRoomPlacement.isAvailable(ExamPeriod)`), and which together cover the size of exam (number of students attending the exam) has to be assigned to an exam. Based on the type of seating (see `hasAltSeating()`), either room sizes (see `ExamRoom.getSize()`) or alternative seating sizes (see `ExamRoom.getAltSize()`) are used. An exam has a list of available rooms with their penalties assiciated with (see `getRoomPlacements()`).
  Various penalties for an assignment of a period or a set of rooms may apply. See `ExamPlacement` for more details.
  Version:
    ExamTT 1.3 (Examination Timetabling)
    Copyright (C) 2008 - 2014 Tomáš Müller
    muller@unitime.org
    http://muller.unitime.org
    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
    This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    You should have received a copy of the GNU Lesser General Public License along with this library; if not see http://www.gnu.org/licenses/.
  Author:
    Tomáš Müller

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected static DecimalFormat` | `sDoubleFormat`

    - ### Fields inherited from class org.cpsolver.ifs.model.Variable

      `iId, iIndex, iValue`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `Exam(long id, String name, int length, boolean altSeating, int maxRooms, int minSize, List<ExamPeriodPlacement> periodPlacements, List<ExamRoomPlacement> roomPlacements)` Constructor

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `addContstraint(Constraint<Exam,ExamPlacement> constraint)` Adds a constraint.
    `void` | `allowAllStudentConflicts(Assignment<Exam,ExamPlacement> assignment, ExamPeriod period)` Allow all direct student conflict for the given period (see `ExamStudent.canConflict(Exam, Exam)`).
    `boolean` | `checkDistributionConstraints(Assignment<Exam,ExamPlacement> assignment, ExamPeriodPlacement period)` Check all distribution constraint that this exam is involved in
    `boolean` | `checkDistributionConstraints(Assignment<Exam,ExamPlacement> assignment, ExamRoomPlacement room)` Check all distribution constraint that this exam is involved in
    `int` | `compareTo(Exam o)` An exam with more correlated exams is preferred ( `nrStudentCorrelatedExams()`).
    `int` | `countInstructorConflicts(Assignment<Exam,ExamPlacement> assignment, ExamPeriodPlacement period)` Number of instructor of this exam (that does not have direct conflicts allowed, see `ExamInstructor.canConflict(Exam, Exam)`) that attend some other exam in the given period.
    `int` | `countStudentConflicts(Assignment<Exam,ExamPlacement> assignment, ExamPeriodPlacement period)` Number of students of this exam (that does not have direct conflicts allowed, see `ExamStudent.canConflict(Exam, Exam)`) that attend some other exam in the given period.
    `Set<ExamRoomPlacement>` | `findBestAvailableRooms(Assignment<Exam,ExamPlacement> assignment, ExamPeriodPlacement period)` Find best available rooms for the exam in the given period.
    `Set<ExamRoomPlacement>` | `findRoomsRandom(Assignment<Exam,ExamPlacement> assignment, ExamPeriodPlacement period)` Randomly find a set of available rooms for the exam in the given period.
    `Set<ExamRoomPlacement>` | `findRoomsRandom(Assignment<Exam,ExamPlacement> assignment, ExamPeriodPlacement period, boolean checkConflicts)` Randomly find a set of available rooms for the exam in the given period.
    `int` | `getAveragePeriod()` Average period.
    `int` | `getDistributionConstraintPenalty(Assignment<Exam,ExamPlacement> assignment, ExamRoomPlacement room)` Check all soft distribution constraint that this exam is involved in
    `List<ExamDistributionConstraint>` | `getDistributionConstraints()` List of distribution constraints that this exam is involved in
    `List<ExamInstructor>` | `getInstructors()` List of instructors that are assigned to this exam
    `Map<Exam,List<ExamStudent>>` | `getJointEnrollments()` Joint enrollments
    `int` | `getLength()` Length of the exam in minutes.
    `int` | `getMaxRooms()` Maximal number of rooms that can be assigned to the exam
    `int` | `getMinSize()` Minimal exam size, see `getSize()`
    `String` | `getName()` Exam name
    `List<ExamOwner>` | `getOwners()` Courses and/or sections that are having this exam
    `Collection<ExamOwner>` | `getOwners(ExamInstructor instructor)` Courses/sections of this exam into which the given instructor is enrolled into
    `Collection<ExamOwner>` | `getOwners(ExamStudent student)` Courses/sections of this exam into which the given student is enrolled into
    `ExamPeriodPlacement` | `getPeriodPlacement(ExamPeriod period)` Returns appropriate `ExamPeriodPlacement` for the given period, if it is available for this exam, null otherwise.
    `ExamPeriodPlacement` | `getPeriodPlacement(Long periodId)` Returns appropriate `ExamPeriodPlacement` for the given period, if it is available for this exam, null otherwise.
    `List<ExamPeriodPlacement>` | `getPeriodPlacements()` Return list of possible period placements.
    `List<ExamRoomPlacement>` | `getPreferredRoomPlacements()` Return list of possible room placements that are strongly preferred.
    `Integer` | `getPrintOffset()` Print offset -- for reporting purposes
    `ExamRoomPlacement` | `getRoomPlacement(ExamRoom room)` Returns appropriate `ExamRoomPlacement` for the given room, if it is available for this exam, null otherwise.
    `ExamRoomPlacement` | `getRoomPlacement(long roomId)` Returns appropriate `ExamRoomPlacement` for the given room, if it is available for this exam, null otherwise.
    `List<ExamRoomPlacement>` | `getRoomPlacements()` Return list of possible room placements.
    `int` | `getSize()` Exam size, it is bigger from `getMinSize()` and the number of students enrolled into the exam `getStudents()`.
    `Integer` | `getSizeOverride()` Override exam size with given value (revert to default when null)
    `HashSet<Exam>` | `getStudentConflicts(Assignment<Exam,ExamPlacement> assignment, ExamPeriod period)` List of exams that are assigned to the given period and share one or more students with this exam (that does not have direct conflicts allowed, see `ExamStudent.canConflict(Exam, Exam)`).
    `Set<Exam>` | `getStudentCorrelatedExams()` Exams that are correlated with this exam (there is at least one student attending both exams).
    `List<ExamStudent>` | `getStudents()` List of students that are enrolled in the exam
    `boolean` | `hasAltSeating()` True if alternative seating is required (`ExamRoom.getAltSize()` is to be used), false if normal seating is required ( `ExamRoom.getSize()` is to be used).
    `boolean` | `hasAveragePeriod()` True if there is an average period assigned to the exam.
    `boolean` | `hasName()` Exam name
    `boolean` | `hasStudentConflictWithPreAssigned(Assignment<Exam,ExamPlacement> assignment, ExamPeriod period)` True, if there is a student of this exam (that does not have direct conflicts allowed, see `ExamStudent.canConflict(Exam, Exam)`) that attends some other exam in the given period.
    `boolean` | `hasValues()` Return true if there are some values in the domain of this variable
    `boolean` | `isAllowDirectConflicts()` True if a direct student conflict is allowed, see `ExamStudent.canConflict(Exam, Exam)`
    `int` | `nrStudentCorrelatedExams()` Number of exams that are correlated with this exam (there is at least one student attending both exams).
    `void` | `removeContstraint(Constraint<Exam,ExamPlacement> constraint)` Removes a constraint.
    `void` | `setAllowDirectConflicts(boolean allowDirectConflicts)` Set whether a direct student conflict is allowed, see `ExamStudent.canConflict(Exam, Exam)`
    `void` | `setAveragePeriod(int period)` Set average period.
    `void` | `setMaxRooms(int maxRooms)` Set maximal number of rooms that can be assigned to the exam
    `void` | `setMinSize(int minSize)` Minimal exam size, see `getSize()`
    `void` | `setName(String name)` Exam name
    `void` | `setPrintOffset(Integer printOffset)` Print offset -- for reporting purposes
    `void` | `setSizeOverride(Integer size)` Override exam size with given value (revert to default when null)
    `String` | `toString()` String representation
    `List<ExamPlacement>` | `values(Assignment<Exam,ExamPlacement> assignment)` Values (assignment of a period and a set of rooms)
    `void` | `variableAssigned(Assignment<Exam,ExamPlacement> assignment, long iteration, ExamPlacement placement)` A value was assigned to this variable

    - ### Methods inherited from class org.cpsolver.ifs.model.Variable

      `addVariableListener, assign, constraints, constraintVariables, equals, getAssignment, getAssignment, getAssignments, getBestAssignment, getBestAssignmentIteration, getDescription, getExtra, getId, getIndex, getInitialAssignment, getLastIteration, getModel, getVariableListeners, hardConstraints, hasAssignment, hasAssignment, hashCode, hasInitialAssignment, removeInitialValue, removeValue, removeVariableListener, setAssignment, setBestAssignment, setExtra, setIndex, setInitialAssignment, setLastIteration, setModel, setValues, softConstraints, unassign, values, variableUnassigned`

    - ### Methods inherited from class java.lang.Object

      `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### sDoubleFormat

          protected static DecimalFormat sDoubleFormat

  - ### Constructor Detail

    - #### Exam

          public Exam(long id,
                      String name,
                      int length,
                      boolean altSeating,
                      int maxRooms,
                      int minSize,
                      List<ExamPeriodPlacement> periodPlacements,
                      List<ExamRoomPlacement> roomPlacements)

      Constructor
      Parameters:
        `id` - exam unique id
        `name` - exam name
        `length` - exam length in minutes
        `altSeating` - true if alternative seating is requested
        `maxRooms` - maximum number of rooms to be used
        `minSize` - minimal size of rooms into which an exam can be assigned (see `getSize()`)
        `periodPlacements` - list of periods and their penalties `ExamPeriodPlacement` into which an exam can be assigned
        `roomPlacements` - list of rooms and their penalties `ExamRoomPlacement` into which an exam can be assigned

  - ### Method Detail

    - #### getSize

          public int getSize()

      Exam size, it is bigger from `getMinSize()` and the number of students enrolled into the exam `getStudents()`. If `getMaxRooms()` is greater than zero, an exam must be assigned into rooms which overall size (or alternative seating size if `hasAltSeating()`) must be equal or greater than this size.
      Returns:
        examination size

    - #### setSizeOverride

          public void setSizeOverride(Integer size)

      Override exam size with given value (revert to default when null)
      Parameters:
        `size` - examination size override

    - #### getSizeOverride

          public Integer getSizeOverride()

      Override exam size with given value (revert to default when null)
      Returns:
        examination size override

    - #### getPrintOffset

          public Integer getPrintOffset()

      Print offset -- for reporting purposes
      Returns:
        print offset in minutes

    - #### setPrintOffset

          public void setPrintOffset(Integer printOffset)

      Print offset -- for reporting purposes
      Parameters:
        `printOffset` - print offset in minutes

    - #### getMinSize

          public int getMinSize()

      Minimal exam size, see `getSize()`
      Returns:
        minimal examination size

    - #### setMinSize

          public void setMinSize(int minSize)

      Minimal exam size, see `getSize()`
      Parameters:
        `minSize` - minimal examination size

    - #### values

          public List<ExamPlacement> values(Assignment<Exam,ExamPlacement> assignment)

      Values (assignment of a period and a set of rooms)
      Overrides:
        `values` in class `Variable<Exam,ExamPlacement>`
      Parameters:
        `assignment` - current assignment (if the domain is dependent on the current assignment)
      Returns:
        list of `ExamPlacement`

    - #### getRoomPlacements

          public List<ExamRoomPlacement> getRoomPlacements()

      Return list of possible room placements.
      Returns:
        list of `ExamRoomPlacement`

    - #### getPreferredRoomPlacements

          public List<ExamRoomPlacement> getPreferredRoomPlacements()

      Return list of possible room placements that are strongly preferred.
      Returns:
        list of `ExamRoomPlacement`

    - #### getPeriodPlacements

          public List<ExamPeriodPlacement> getPeriodPlacements()

      Return list of possible period placements.
      Returns:
        list of `ExamPeriodPlacement`

    - #### hasAltSeating

          public boolean hasAltSeating()

      True if alternative seating is required (`ExamRoom.getAltSize()` is to be used), false if normal seating is required ( `ExamRoom.getSize()` is to be used).
      Returns:
        true if alternative seating is required, false otherwise

    - #### getLength

          public int getLength()

      Length of the exam in minutes. The assigned period has to be of the same or greater length.
      Returns:
        length of the exam in minutes

    - #### setAveragePeriod

          public void setAveragePeriod(int period)

      Set average period. This represents an average period that the exam was assigned to in the past. If set, it is used in exam rotation penalty `ExamRotationPenalty` in order to put more weight on exams that were badly assigned last time(s) and ensuring some form of fairness.
      Parameters:
        `period` - average period

    - #### getAveragePeriod

          public int getAveragePeriod()

      Average period. This represents an average period that the exam was assigned to in the past. If set, it is used in exam rotation penalty `ExamRotationPenalty` in order to put more weight on exams that were badly assigned last time(s) and ensuring some form of fairness.
      Returns:
        average period

    - #### hasAveragePeriod

          public boolean hasAveragePeriod()

      True if there is an average period assigned to the exam. This represents an average period that the exam was assigned to in the past. If set, it is used in exam rotation penalty `ExamRotationPenalty` in order to put more weight on exams that were badly assigned last time(s) and ensuring some form of fairness.
      Returns:
        true if the exam has an average period set

    - #### isAllowDirectConflicts

          public boolean isAllowDirectConflicts()

      True if a direct student conflict is allowed, see `ExamStudent.canConflict(Exam, Exam)`
      Returns:
        true if a direct student conflict is allowed

    - #### setAllowDirectConflicts

          public void setAllowDirectConflicts(boolean allowDirectConflicts)

      Set whether a direct student conflict is allowed, see `ExamStudent.canConflict(Exam, Exam)`
      Parameters:
        `allowDirectConflicts` - true if a direct student conflict is allowed

    - #### addContstraint

          public void addContstraint(Constraint<Exam,ExamPlacement> constraint)

      Adds a constraint. Called automatically when the constraint is added to the model, i.e., `Model.addConstraint(Constraint)` is called.
      Overrides:
        `addContstraint` in class `Variable<Exam,ExamPlacement>`
      Parameters:
        `constraint` - added constraint

    - #### removeContstraint

          public void removeContstraint(Constraint<Exam,ExamPlacement> constraint)

      Removes a constraint. Called automatically when the constraint is removed from the model, i.e., `Model.removeConstraint(Constraint)` is called.
      Overrides:
        `removeContstraint` in class `Variable<Exam,ExamPlacement>`
      Parameters:
        `constraint` - added constraint

    - #### getStudents

          public List<ExamStudent> getStudents()

      List of students that are enrolled in the exam
      Returns:
        list of `ExamStudent`

    - #### getDistributionConstraints

          public List<ExamDistributionConstraint> getDistributionConstraints()

      List of distribution constraints that this exam is involved in
      Returns:
        list of `ExamDistributionConstraint`

    - #### getInstructors

          public List<ExamInstructor> getInstructors()

      List of instructors that are assigned to this exam
      Returns:
        list of `ExamInstructor`

    - #### checkDistributionConstraints

          public boolean checkDistributionConstraints(Assignment<Exam,ExamPlacement> assignment,
                                                      ExamPeriodPlacement period)

      Check all distribution constraint that this exam is involved in
      Parameters:
        `assignment` - current assignment
        `period` - a period to be assigned to this exam
      Returns:
        true, if there is no assignment of some other exam in conflict with the given period

    - #### checkDistributionConstraints

          public boolean checkDistributionConstraints(Assignment<Exam,ExamPlacement> assignment,
                                                      ExamRoomPlacement room)

      Check all distribution constraint that this exam is involved in
      Parameters:
        `assignment` - current assignment
        `room` - a room to be assigned to this exam
      Returns:
        true, if there is no assignment of some other exam in conflict with the given room

    - #### getDistributionConstraintPenalty

          public int getDistributionConstraintPenalty(Assignment<Exam,ExamPlacement> assignment,
                                                      ExamRoomPlacement room)

      Check all soft distribution constraint that this exam is involved in
      Parameters:
        `assignment` - current assignment
        `room` - a room to be assigned to this exam
      Returns:
        sum of penalties of violated distribution constraints

    - #### getMaxRooms

          public int getMaxRooms()

      Maximal number of rooms that can be assigned to the exam
      Returns:
        maximal number of rooms that can be assigned to the exam

    - #### setMaxRooms

          public void setMaxRooms(int maxRooms)

      Set maximal number of rooms that can be assigned to the exam
      Parameters:
        `maxRooms` - maximal number of rooms that can be assigned to the exam

    - #### findBestAvailableRooms

          public Set<ExamRoomPlacement> findBestAvailableRooms(Assignment<Exam,ExamPlacement> assignment,
                                                               ExamPeriodPlacement period)

      Find best available rooms for the exam in the given period. First of all, it tries to find the minimal number of rooms that cover the size of the exam. Among these, a set of rooms of total smallest size is preferred. If the original room is available and of enough size, it is returned. All necessary checks are made (availability of rooms, room penalties, room sizes etc.).
      Parameters:
        `assignment` - current assignment
        `period` - given period.
      Returns:
        best available rooms for the exam in the given period, null if there is no valid assignment

    - #### findRoomsRandom

          public Set<ExamRoomPlacement> findRoomsRandom(Assignment<Exam,ExamPlacement> assignment,
                                                        ExamPeriodPlacement period)

      Randomly find a set of available rooms for the exam in the given period. First of all, it tries to find the minimal number of rooms that cover the size of the exam. Among these, a set of rooms of total smallest size is preferred. All necessary checks are made (availability of rooms, room penalties, room sizes etc.).
      Parameters:
        `assignment` - current assignment
        `period` - given period.
      Returns:
        randomly computed set of available rooms for the exam in the given period, null if there is no valid assignment

    - #### findRoomsRandom

          public Set<ExamRoomPlacement> findRoomsRandom(Assignment<Exam,ExamPlacement> assignment,
                                                        ExamPeriodPlacement period,
                                                        boolean checkConflicts)

      Randomly find a set of available rooms for the exam in the given period. First of all, it tries to find the minimal number of rooms that cover the size of the exam. Among these, a set of rooms of total smallest size is preferred. All necessary checks are made (availability of rooms, room penalties, room sizes etc.).
      Parameters:
        `assignment` - current assignment
        `period` - given period.
        `checkConflicts` - if false, room and distribution conflicts are not checked
      Returns:
        randomly computed set of available rooms for the exam in the given period, null if there is no valid assignment

    - #### nrStudentCorrelatedExams

          public int nrStudentCorrelatedExams()

      Number of exams that are correlated with this exam (there is at least one student attending both exams).
      Returns:
        number of correlated exams

    - #### getStudentCorrelatedExams

          public Set<Exam> getStudentCorrelatedExams()

      Exams that are correlated with this exam (there is at least one student attending both exams).
      Returns:
        number of correlated exams

    - #### compareTo

          public int compareTo(Exam o)

      An exam with more correlated exams is preferred ( `nrStudentCorrelatedExams()`). If it is the same, ratio number of students / number of available periods is used. If the same, exam ids are used.
      Specified by:
        `compareTo` in interface `Comparable<Exam>`
      Overrides:
        `compareTo` in class `Variable<Exam,ExamPlacement>`

    - #### hasStudentConflictWithPreAssigned

          public boolean hasStudentConflictWithPreAssigned(Assignment<Exam,ExamPlacement> assignment,
                                                           ExamPeriod period)

      True, if there is a student of this exam (that does not have direct conflicts allowed, see `ExamStudent.canConflict(Exam, Exam)`) that attends some other exam in the given period.
      Parameters:
        `assignment` - current assignment
        `period` - a period
      Returns:
        true if there is a student conflict

    - #### countStudentConflicts

          public int countStudentConflicts(Assignment<Exam,ExamPlacement> assignment,
                                           ExamPeriodPlacement period)

      Number of students of this exam (that does not have direct conflicts allowed, see `ExamStudent.canConflict(Exam, Exam)`) that attend some other exam in the given period.
      Parameters:
        `assignment` - current assignment
        `period` - a period
      Returns:
        number of direct student conflicts that are prohibited

    - #### countInstructorConflicts

          public int countInstructorConflicts(Assignment<Exam,ExamPlacement> assignment,
                                              ExamPeriodPlacement period)

      Number of instructor of this exam (that does not have direct conflicts allowed, see `ExamInstructor.canConflict(Exam, Exam)`) that attend some other exam in the given period.
      Parameters:
        `assignment` - current assignment
        `period` - a period
      Returns:
        number of direct student conflicts that are prohibited

    - #### getStudentConflicts

          public HashSet<Exam> getStudentConflicts(Assignment<Exam,ExamPlacement> assignment,
                                                   ExamPeriod period)

      List of exams that are assigned to the given period and share one or more students with this exam (that does not have direct conflicts allowed, see `ExamStudent.canConflict(Exam, Exam)`).
      Parameters:
        `assignment` - current assignment
        `period` - a period
      Returns:
        list of `Exam` (other than this exam, that are placed in the given period and create prohibited direct conflicts)

    - #### allowAllStudentConflicts

          public void allowAllStudentConflicts(Assignment<Exam,ExamPlacement> assignment,
                                               ExamPeriod period)

      Allow all direct student conflict for the given period (see `ExamStudent.canConflict(Exam, Exam)`).
      Parameters:
        `assignment` - current assignment
        `period` - a period

    - #### toString

          public String toString()

      String representation
      Overrides:
        `toString` in class `Variable<Exam,ExamPlacement>`
      Returns:
        exam id (periods: number of periods, rooms: number of rooms, student: number of students, maxRooms: max rooms[, alt if alternate seating is required])

    - #### getName

          public String getName()

      Exam name
      Overrides:
        `getName` in class `Variable<Exam,ExamPlacement>`
      Returns:
        variable name

    - #### setName

          public void setName(String name)

      Exam name
      Parameters:
        `name` - examination name

    - #### hasName

          public boolean hasName()

      Exam name
      Returns:
        true if the examination name is set and it is not empty

    - #### getJointEnrollments

          public Map<Exam,List<ExamStudent>> getJointEnrollments()

      Joint enrollments
      Returns:
        table `Exam` (an exam that has at least one student in common with this exam) → `List` (list of students in common)

    - #### getOwners

          public List<ExamOwner> getOwners()

      Courses and/or sections that are having this exam
      Returns:
        list of `ExamOwner`

    - #### getOwners

          public Collection<ExamOwner> getOwners(ExamStudent student)

      Courses/sections of this exam into which the given student is enrolled into
      Parameters:
        `student` - a student that is enrolled into this exam
      Returns:
        list of courses/sections `ExamOwner` which are having this exam with the given student enrolled in

    - #### getOwners

          public Collection<ExamOwner> getOwners(ExamInstructor instructor)

      Courses/sections of this exam into which the given instructor is enrolled into
      Parameters:
        `instructor` - an instructor that is enrolled into this exam
      Returns:
        list of courses/sections `ExamOwner` which are having this exam with the given instructor enrolled in

    - #### getPeriodPlacement

          public ExamPeriodPlacement getPeriodPlacement(Long periodId)

      Returns appropriate `ExamPeriodPlacement` for the given period, if it is available for this exam, null otherwise.
      Parameters:
        `periodId` - period unique id
      Returns:
        the appropriate period placement

    - #### getRoomPlacement

          public ExamRoomPlacement getRoomPlacement(long roomId)

      Returns appropriate `ExamRoomPlacement` for the given room, if it is available for this exam, null otherwise.
      Parameters:
        `roomId` - room unique id
      Returns:
        the appropriate room placement

    - #### getPeriodPlacement

          public ExamPeriodPlacement getPeriodPlacement(ExamPeriod period)

      Returns appropriate `ExamPeriodPlacement` for the given period, if it is available for this exam, null otherwise.
      Parameters:
        `period` - period in question
      Returns:
        the appropriate period placement

    - #### getRoomPlacement

          public ExamRoomPlacement getRoomPlacement(ExamRoom room)

      Returns appropriate `ExamRoomPlacement` for the given room, if it is available for this exam, null otherwise.
      Parameters:
        `room` - room in question
      Returns:
        the appropriate room placement

    - #### hasValues

          public boolean hasValues()

      Return true if there are some values in the domain of this variable
      Overrides:
        `hasValues` in class `Variable<Exam,ExamPlacement>`
      Returns:
        true if there is at least one value in the domain

    - #### variableAssigned

          public void variableAssigned(Assignment<Exam,ExamPlacement> assignment,
                                       long iteration,
                                       ExamPlacement placement)

      Description copied from class: `Variable`
      A value was assigned to this variable
      Overrides:
        `variableAssigned` in class `Variable<Exam,ExamPlacement>`
      Parameters:
        `assignment` - current assignment
        `iteration` - current iteration
        `placement` - assigned value