001package org.cpsolver.ifs.example.tt; 002 003import org.cpsolver.ifs.model.Value; 004 005/** 006 * Location (value, i.e., a single placement of the activity). Location encodes 007 * a slot and a selection of resources. 008 * 009 * @version IFS 1.3 (Iterative Forward Search)<br> 010 * Copyright (C) 2006 - 2014 Tomáš Müller<br> 011 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 012 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 013 * <br> 014 * This library is free software; you can redistribute it and/or modify 015 * it under the terms of the GNU Lesser General Public License as 016 * published by the Free Software Foundation; either version 3 of the 017 * License, or (at your option) any later version. <br> 018 * <br> 019 * This library is distributed in the hope that it will be useful, but 020 * WITHOUT ANY WARRANTY; without even the implied warranty of 021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 022 * Lesser General Public License for more details. <br> 023 * <br> 024 * You should have received a copy of the GNU Lesser General Public 025 * License along with this library; if not see 026 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 027 */ 028public class Location extends Value<Activity, Location> { 029 private int iSlot; 030 private Resource[] iResources; 031 private int iNrOfDiscouragedSlots = -1; 032 033 /** 034 * Constructor. 035 * 036 * @param activity 037 * parent activity 038 * @param slot 039 * starting time 040 * @param resources 041 * selection of resources 042 */ 043 public Location(Activity activity, int slot, Resource[] resources) { 044 super(activity); 045 iSlot = slot; 046 iResources = resources; 047 iNrOfDiscouragedSlots = computeNrOfDiscouragedSlots(); 048 } 049 050 /** 051 * Constructor. slot = nrHours * day + hour 052 * 053 * @param activity 054 * parent activity 055 * @param day 056 * day 057 * @param hour 058 * starting hour 059 * @param resources 060 * required resources 061 */ 062 public Location(Activity activity, int day, int hour, Resource[] resources) { 063 super(activity); 064 iSlot = ((TimetableModel) activity.getModel()).getNrHours() * day + hour; 065 iResources = resources; 066 iNrOfDiscouragedSlots = computeNrOfDiscouragedSlots(); 067 } 068 069 /** Gets slot 070 * @return slot 071 **/ 072 public int getSlot() { 073 return iSlot; 074 } 075 076 /** Gets selection of resources 077 * @return selection of resources 078 **/ 079 public Resource[] getResources() { 080 return iResources; 081 } 082 083 /** Gets given resource 084 * @param idx index 085 * @return given resource 086 **/ 087 public Resource getResource(int idx) { 088 return iResources[idx]; 089 } 090 091 /** Returns true if the given resource is used by this location 092 * @param resource given resource 093 * @return true if the given resource is used by this location 094 **/ 095 public boolean containResource(Resource resource) { 096 for (int i = 0; i < iResources.length; i++) 097 if (iResources[i].equals(resource)) 098 return true; 099 return false; 100 } 101 102 /** Number of slots (over all resources) which are discouraged 103 * @return number of slots (over all resources) which are discouraged 104 **/ 105 public int getNrOfDiscouragedSlots() { 106 return iNrOfDiscouragedSlots; 107 } 108 109 /** Placement value (for optimization) -- getNrOfDiscouragedSlots() is returned */ 110 @Override 111 public double toDouble() { 112 return iNrOfDiscouragedSlots; 113 } 114 115 /** 116 * Computes number of discouraged slots (over all resources and the 117 * activity) 118 * @return number of discouraged slots 119 */ 120 public int computeNrOfDiscouragedSlots() { 121 Activity a = variable(); 122 int ret = 0; 123 for (int i = getSlot(); i < getSlot() + a.getLength(); i++) { 124 if (a.isDiscouragedSlot(i)) 125 ret++; 126 for (int j = 0; j < getResources().length; j++) 127 if (getResource(j).isDiscouragedSlot(i)) 128 ret++; 129 } 130 return ret; 131 } 132 133 /** 134 * Returns true if the location intersects with another location. This means 135 * the same resource is used in the same time. 136 * @param location another location 137 * @return true if this location intersects with the other location 138 */ 139 public boolean hasIntersection(Location location) { 140 int s1 = getSlot(); 141 int l1 = variable().getLength(); 142 int s2 = location.getSlot(); 143 int l2 = location.variable().getLength(); 144 return !(s1 + l1 <= s2 || s2 + l2 <= s1); 145 } 146 147 /** 148 * Returns true if the location is prohibited. This means that the activity 149 * or a required resource has a time slot which is used by this location 150 * prohibited. 151 * @return true if the location is prohibited 152 */ 153 public boolean isProhibited() { 154 Activity a = variable(); 155 for (int i = getSlot(); i < getSlot() + a.getLength(); i++) { 156 if (a.isProhibitedSlot(i)) 157 return true; 158 for (int j = 0; j < getResources().length; j++) 159 if (getResource(j).isProhibitedSlot(i)) 160 return true; 161 } 162 return false; 163 } 164 165 @Override 166 public String getName() { 167 StringBuffer sb = new StringBuffer(getSlot() + "/"); 168 for (int i = 0; i < iResources.length; i++) { 169 if (i > 0) 170 sb.append(","); 171 sb.append(iResources[i].getName()); 172 } 173 return sb.toString(); 174 } 175}