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}