    001package org.cpsolver.ifs.example.tt;
    002
    003import java.util.HashSet;
    004import java.util.Set;
    005
    006import org.cpsolver.ifs.assignment.Assignment;
    007import org.cpsolver.ifs.assignment.context.AssignmentConstraintContext;
    008import org.cpsolver.ifs.assignment.context.ConstraintWithContext;
    009
    010
    011/**
    012 * Resource constraint
    013 *
    014 * @author  Tomáš Müller
    015 * @version IFS 1.3 (Iterative Forward Search)<br>
    016 *          Copyright (C) 2006 - 2014 Tomáš Müller<br>
    017 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
    018 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
    019 * <br>
    020 *          This library is free software; you can redistribute it and/or modify
    021 *          it under the terms of the GNU Lesser General Public License as
    022 *          published by the Free Software Foundation; either version 3 of the
    023 *          License, or (at your option) any later version. <br>
    024 * <br>
    025 *          This library is distributed in the hope that it will be useful, but
    026 *          WITHOUT ANY WARRANTY; without even the implied warranty of
    027 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    028 *          Lesser General Public License for more details. <br>
    029 * <br>
    030 *          You should have received a copy of the GNU Lesser General Public
    031 *          License along with this library; if not see
    032 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
    033 */
    034public class Resource extends ConstraintWithContext<Activity, Location, Resource.Context> {
    035    private String iName = null;
    036    private String iResourceId = null;
    037    private Set<Integer> iProhibitedSlots = new HashSet<Integer>();
    038    private Set<Integer> iDiscouragedSlots = new HashSet<Integer>();
    039    private int iType = TYPE_OTHER;
    040
    041    public static final int TYPE_ROOM = 0;
    042    public static final int TYPE_INSTRUCTOR = 1;
    043    public static final int TYPE_CLASS = 2;
    044    public static final int TYPE_OTHER = 3;
    045
    046    public Resource(String id, int type, String name) {
    047        super();
    048        iResourceId = id;
    049        iName = name;
    050        iType = type;
    051    }
    052
    053    public String getResourceId() { return iResourceId; }
    054    @Override
    055    public String getName() { return iName; }
    056    public int getType() { return iType; }
    057    public Set<Integer> getProhibitedSlots() { return iProhibitedSlots; }
    058    public Set<Integer> getDiscouragedSlots() { return iDiscouragedSlots; }
    059    public void addProhibitedSlot(int day, int hour) {
    060        iProhibitedSlots.add(((TimetableModel)getModel()).getNrHours()*day+hour);
    061    }
    062    public void addDiscouragedSlot(int day, int hour) {
    063        iDiscouragedSlots.add(((TimetableModel)getModel()).getNrHours()*day+hour);
    064    }
    065    public boolean isProhibitedSlot(int day, int hour) {
    066        return iProhibitedSlots.contains(((TimetableModel)getModel()).getNrHours()*day+hour);
    067    }
    068    public boolean isDiscouragedSlot(int day, int hour) {
    069        return iDiscouragedSlots.contains(((TimetableModel)getModel()).getNrHours()*day+hour);
    070    }
    071    public void addProhibitedSlot(int slot) {
    072        iProhibitedSlots.add(slot);
    073    }
    074    public void addDiscouragedSlot(int slot) {
    075        iDiscouragedSlots.add(slot);
    076    }
    077    public boolean isProhibitedSlot(int slot) {
    078        return iProhibitedSlots.contains(slot);
    079    }
    080    public boolean isDiscouragedSlot(int slot) {
    081        return iDiscouragedSlots.contains(slot);
    082    }
    083    public boolean isProhibited(int day, int hour, int length) {
    084        int slot = ((TimetableModel)getModel()).getNrHours()*day+hour;
    085        for (int i=0;i<length;i++)
    086            if (iProhibitedSlots.contains(slot+i)) return true;
    087        return false;
    088    }
    089
    090    @Override
    091    public void computeConflicts(Assignment<Activity, Location> assignment, Location location, Set<Location> conflicts) {
    092        Activity activity = location.variable();
    093        if (!location.containResource(this)) return;
    094        Context context = getContext(assignment);
    095        for (int i=location.getSlot(); i<location.getSlot()+activity.getLength(); i++) {
    096            Activity conf = context.getActivity(i);
    097            if (conf!=null && !activity.equals(conf))
    098                conflicts.add(assignment.getValue(conf));
    099        }
    100    }
    101
    102    @Override
    103        public boolean inConflict(Assignment<Activity, Location> assignment, Location location) {
    104        Activity activity = location.variable();
    105        if (!location.containResource(this)) return false;
    106        Context context = getContext(assignment);
    107        for (int i=location.getSlot(); i<location.getSlot()+activity.getLength(); i++) {
    108            if (context.getActivity(i) != null) return true;
    109        }
    110        return false;
    111    }
    112
    113    @Override
    114        public boolean isConsistent(Location l1, Location l2) {
    115        return !l1.containResource(this) || !l2.containResource(this) || !l1.hasIntersection(l2);
    116    }
    117
    118    @Override
    119    public Context createAssignmentContext(Assignment<Activity, Location> assignment) {
    120        return new Context(assignment);
    121    }
    122
    123    /**
    124     * Assignment context
    125     */
    126    public class Context implements AssignmentConstraintContext<Activity, Location> {
    127        private Activity[] iResource;
    128
    129        public Context(Assignment<Activity, Location> assignment) {
    130            TimetableModel model = (TimetableModel)getModel();
    131            iResource = new Activity[model.getNrDays() * model.getNrHours()];
    132            for (int i=0;i<iResource.length;i++)
    133                    iResource[i] = null;
    134            for (Location location: assignment.assignedValues())
    135                assigned(assignment, location);
    136        }
    137
    138        @Override
    139        public void assigned(Assignment<Activity, Location> assignment, Location location) {
    140            Activity activity = location.variable();
    141            if (!location.containResource(Resource.this)) return;
    142            for (int i=location.getSlot(); i<location.getSlot()+activity.getLength(); i++) {
    143                iResource[i] = activity;
    144            }
    145        }
    146
    147        public Activity getActivity(int slot) {
    148            return iResource[slot];
    149        }
    150
    151        @Override
    152        public void unassigned(Assignment<Activity, Location> assignment, Location location) {
    153            Activity activity = location.variable();
    154            if (!location.containResource(Resource.this)) return;
    155            for (int i=location.getSlot(); i<location.getSlot()+activity.getLength(); i++) {
    156                iResource[i] = null;
    157            }
    158        }
    159    }
    160}