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