All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cpsolver.instructor.constraints.SameLinkConstraint Maven / Gradle / Ivy

Go to download

The constraint solver library contains a local search based framework that allows modeling of a problem using constraint programming primitives (variables, values, constraints).

The newest version!
package org.cpsolver.instructor.constraints;

import java.util.HashSet;
import java.util.Set;

import org.cpsolver.coursett.Constants;
import org.cpsolver.ifs.assignment.Assignment;
import org.cpsolver.ifs.assignment.context.AssignmentConstraintContext;
import org.cpsolver.ifs.assignment.context.ConstraintWithContext;
import org.cpsolver.instructor.criteria.SameLink;
import org.cpsolver.instructor.model.Instructor;
import org.cpsolver.instructor.model.TeachingAssignment;
import org.cpsolver.instructor.model.TeachingRequest;

/**
 * Same Link Constraint. Much like the {@link SameInstructorConstraint}, but it is possible to assign multiple instructors
 * to the teaching requests of the same link. It is, however, prohibited (or discouraged) for an instructor to teach
 * have teaching requests than the ones of the link. In prohibited / discouraged variant, each request must / should get
 * a different instructor. 
 * 
 * @author  Tomas Muller
 * @version IFS 1.3 (Instructor Sectioning)
* Copyright (C) 2016 Tomas Muller
* [email protected]
* 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/. */ public class SameLinkConstraint extends ConstraintWithContext { private Long iId; private String iName; private int iPreference = 0; private boolean iRequired = false, iProhibited = false; /** * Constructor * @param id constraint id * @param name link name * @param preference constraint preference (R for required, etc.) */ public SameLinkConstraint(Long id, String name, String preference) { iId = id; iName = name; iPreference = Constants.preference2preferenceLevel(preference); if (Constants.sPreferenceRequired.equals(preference)) { iRequired = true; } else if (Constants.sPreferenceProhibited.equals(preference)) { iProhibited = true; } } /** * Constraint id that was given in the constructor. * @return constraint id */ public Long getConstraintId() { return iId; } @Override public String getName() { return iName; } @Override public String toString() { return "Same Link " + getName(); } /** * Is required? * @return true if the constraint is required */ public boolean isRequired() { return iRequired; } /** * Is prohibited? * @return true if the constraint is prohibited */ public boolean isProhibited() { return iProhibited; } /** * Constraint preference that was provided in the constructor * @return constraint preference */ public int getPreference() { return iPreference; } @Override public boolean isHard() { return isRequired() || isProhibited(); } @Override public void computeConflicts(Assignment assignment, TeachingAssignment value, Set conflicts) { if (isHard()) { Instructor.Context context = value.getInstructor().getContext(assignment); for (TeachingAssignment ta : context.getAssignments()) { if (ta.variable().equals(value.variable()) || conflicts.contains(ta)) continue; if (isRequired() && !variables().contains(ta.variable())) conflicts.add(ta); if (isProhibited() && variables().contains(ta.variable())) conflicts.add(ta); } } } /** * Current constraint preference (if soft) * @param assignment current assignment * @param value proposed change * @return change in the current preference value of this constraint */ public int getCurrentPreference(Assignment assignment, TeachingAssignment value) { if (isHard()) return 0; // no preference TeachingAssignment current = assignment.getValue(value.variable()); if (current != null && current.getInstructor().equals(value.getInstructor())) return 0; int ret = 0; if (getPreference() < 0) { // preferred for (TeachingAssignment other : value.getInstructor().getContext(assignment).getAssignments()) { if (!variables().equals(value.variable()) && !variables().contains(other.variable())) { ret++; } } if (current != null) { for (TeachingAssignment other : current.getInstructor().getContext(assignment).getAssignments()) { if (!variables().equals(value.variable()) && !variables().contains(other.variable())) { ret--; } } } } else if (getPreference() > 0) { for (TeachingAssignment other : value.getInstructor().getContext(assignment).getAssignments()) { if (!variables().equals(value.variable()) && variables().contains(other.variable())) ret++; } if (current != null) { for (TeachingAssignment other : current.getInstructor().getContext(assignment).getAssignments()) { if (!variables().equals(value.variable()) && variables().contains(other.variable())) { ret--; } } } } return ret; } /** * Current constraint preference (if soft) * @param assignment current assignment * @return that is number of requests that are not of this link assigned to the instructors that have at least one request of this link if preferred; * number of additional requests of this link given to the same instructor if discouraged */ public int getCurrentPreference(Assignment assignment) { if (isHard()) return 0; // no preference if (getPreference() < 0) { // preferred int ret = 0; Set checked = new HashSet(); for (TeachingRequest.Variable tr: variables()) { TeachingAssignment ta = assignment.getValue(tr); if (ta == null || !checked.add(ta.getInstructor())) continue; Instructor.Context context = ta.getInstructor().getContext(assignment); for (TeachingAssignment other : context.getAssignments()) { if (!variables().contains(other.variable())) { ret++; } } } return ret; } else if (getPreference() > 0) { int ret = 0; Set checked = new HashSet(); for (TeachingRequest.Variable tr: variables()) { TeachingAssignment ta = assignment.getValue(tr); if (ta == null || !checked.add(ta.getInstructor())) continue; Instructor.Context context = ta.getInstructor().getContext(assignment); for (TeachingAssignment other : context.getAssignments()) { if (!variables().equals(tr) && variables().contains(other.variable())) { ret++; } } } return ret; } else { return 0; } } @Override public Context createAssignmentContext(Assignment assignment) { return new Context(assignment); } /** * Same Link Constraint Context. This context keeps the last preference value and updates the {@link SameLink} criterion. */ public class Context implements AssignmentConstraintContext { private int iLastPreference = 0; public Context(Assignment assignment) { updateCriterion(assignment); } @Override public void assigned(Assignment assignment, TeachingAssignment value) { updateCriterion(assignment); } @Override public void unassigned(Assignment assignment, TeachingAssignment value) { updateCriterion(assignment); } /** * Update the current preference value * @param assignment current assignment */ private void updateCriterion(Assignment assignment) { if (!isHard()) { getModel().getCriterion(SameLink.class).inc(assignment, -iLastPreference); iLastPreference = getCurrentPreference(assignment); getModel().getCriterion(SameLink.class).inc(assignment, iLastPreference); } } /** * Current preference value (see {@link SameLinkConstraint#getCurrentPreference(Assignment)}) * @return current preference value */ public int getPreference() { return iLastPreference; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy