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