package net.sf.cpsolver.tt;
import java.util.*;
import javolution.util.FastMap;
import javolution.util.FastSet;
import net.sf.cpsolver.ifs.model.*;
import net.sf.cpsolver.ifs.util.FastVector;
/**
* UniActivity (variable).
* It encodes a name, length
*
* @version
* IFS 1.1 (Iterative Forward Search)<br>
* Copyright (C) 2006 Tomas Muller<br>
* <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
* Lazenska 391, 76314 Zlin, Czech Republic<br>
* <br>
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* <br><br>
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* <br><br>
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
public class UniActivity extends Variable {
private int duration;
private String iActivityId;
private String iName;
private List<Collection<UniResource>> iResorces = new ArrayList();
private Set<Integer> iProhibitedSlots = FastSet.newInstance();
private Map<Integer, Float> iDiscouragedSlots = FastMap.newInstance();
private int days;
private int hours;
public UniActivity(int length, String id, String name) {
super(null);
duration = length;
iActivityId = id;
iName = name;
}
@Override
public void setModel(Model model) {
super.setModel(model);
UniTimeSimpleModel m = (UniTimeSimpleModel) getModel();
hours = m.getNrHours();
days = m.getNrDays();
}
@Override
public String getName() {
return iName;
}
public String getActivityId() {
return iActivityId;
}
public int getDuration() {
return duration;
}
public void addResourceGroup(Collection<UniResource> resources) {
for (UniResource res : resources) {
res.addVariable(this);
}
iResorces.add(resources);
}
public void addResourceGroup(UniResource[] resources) {
List rg = new ArrayList(resources.length);
for (int i = 0; i < resources.length; i++) {
rg.add(resources[i]);
resources[i].addVariable(this);
}
iResorces.add(rg);
}
public void addResourceGroup(UniResource resource) {
List rg = new ArrayList(1);
rg.add(resource);
iResorces.add(rg);
resource.addVariable(this);
}
public Collection<UniResource> getResourceGroup(int idx) {
return iResorces.get(idx);
}
public List<Collection<UniResource>> getResourceGroups() {
return iResorces;
}
public Set<Integer> getProhibitedSlots() {
return iProhibitedSlots;
}
public Set<Integer> getDiscouragedSlots() {
return iDiscouragedSlots.keySet();
}
public void addProhibitedSlot(int slot) {
iProhibitedSlots.add(slot);
}
public boolean isProhibitedSlot(int slot) {
return iProhibitedSlots.contains(slot);
}
public void addDiscourage(int slot, float weight) {
iDiscouragedSlots.put(slot, weight);
}
public Float getDiscourage(int slot) {
Float res = iDiscouragedSlots.get(slot);
if (res == null)
return 0f;
else
return res;
}
public boolean isDiscouragedSlot(int slot) {
return iDiscouragedSlots.containsKey(slot);
}
public boolean isProhibited(int day, int hour, int duration) {
int slot = hours * day + hour;
for (int i = 0; i < duration; i++) {
if (iProhibitedSlots.contains(slot + i))
return true;
}
return false;
}
public void init() {
setValues(computeValues());
}
public Vector<Value> computeValues() {
Vector values = new FastVector();
UniResource[] res = new UniResource[getResourceGroups().size()];
for (int day = 0; day < days; day++) {
for (int hour = 0; hour <= hours - getDuration(); hour++) {
if (isProhibited(day, hour, getDuration()))
continue;
addValues(values, day, hour, 0, res);
}
}
return values;
}
private void addValues(Collection<Value> values, int day, int hour, int level, UniResource[] resources) {
if (level == getResourceGroups().size()) {
values.add(new UniAssignment(this, day, hour, (UniResource[]) resources.clone()));
return;
}
Collection<UniResource> rg = getResourceGroups().get(level);
for (UniResource r : rg) {
if (r.isProhibited(day, hour, getDuration()))
continue;
resources[level] = r;
addValues(values, day, hour, level + 1, resources);
}
}
}