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}