001: /*
002: * <copyright>
003: *
004: * Copyright 1999-2004 Honeywell Inc
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.logistics.plugin.packer;
028:
029: //utils
030:
031: import org.cougaar.core.service.AlarmService;
032: import org.cougaar.lib.util.UTILPreference;
033: import org.cougaar.planning.ldm.PlanningFactory;
034: import org.cougaar.planning.ldm.plan.AspectScorePoint;
035: import org.cougaar.planning.ldm.plan.AspectType;
036: import org.cougaar.planning.ldm.plan.AspectValue;
037: import org.cougaar.planning.ldm.plan.Preference;
038: import org.cougaar.planning.ldm.plan.ScoringFunction;
039: import org.cougaar.planning.ldm.plan.Task;
040: import org.cougaar.util.log.Logger;
041: import org.cougaar.util.log.Logging;
042:
043: import java.util.ArrayList;
044: import java.util.Date;
045: import java.util.Iterator;
046:
047: /**
048: * This is the PreferenceAggregator used by the packer created by
049: * HTC. The set of preferences it creates is set up to meet the
050: * needs of the TOPS MCCGlobalMode cluster that will be receiving
051: * the tasks the packer creates.
052: */
053: public class DefaultPreferenceAggregator implements
054: PreferenceAggregator {
055: // Start time is set to 40 days prior to the specified end time
056: private static long MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
057: private AlarmService alarmService;
058:
059: //TODO: find out which logger class to use
060: //private Logger logger;
061: private UTILPreference prefHelper = new UTILPreference(logger);
062: private static Logger logger = Logging
063: .getLogger(DefaultPreferenceAggregator.class);
064:
065: public DefaultPreferenceAggregator(AlarmService alarmService) {
066: this .alarmService = alarmService;
067: // this.logger = logger;
068: }
069:
070: /**
071: * Will create a preference as follows:
072: * START_TIME should be at or greater than 0.0
073: * END_TIME should be bracketed around the earliest END_TIME of
074: * the input tasks and
075: * QUANTITY should be set at the sum of the quantities of the
076: * input tasks.
077: */
078: public ArrayList aggregatePreferences(Iterator tasks,
079: PlanningFactory rootFactory) {
080: ArrayList prefs = new ArrayList();
081: double best = java.lang.Double.POSITIVE_INFINITY;
082: double earliest = 0.0;
083: double latest = java.lang.Double.POSITIVE_INFINITY;
084: double startTime = 0.0;
085: double quantity = 0.0;
086:
087: // find values for endTime and quantity
088: while (tasks.hasNext()) {
089: Task t = (Task) tasks.next();
090: Date taskBest = prefHelper.getBestDate(t);
091: if (taskBest.getTime() < best)
092: best = taskBest.getTime();
093:
094: Preference endDatePref = t
095: .getPreference(AspectType.END_TIME);
096: ScoringFunction sf = endDatePref.getScoringFunction();
097: AspectScorePoint aspStart = sf.getDefinedRange()
098: .getRangeStartPoint();
099: Date taskEarlyDate = new Date((long) aspStart.getValue());
100: if (taskEarlyDate.getTime() > earliest) {
101: earliest = taskEarlyDate.getTime();
102: }
103: AspectScorePoint aspEnd = sf.getDefinedRange()
104: .getRangeEndPoint();
105: Date taskLateDate = new Date((long) aspEnd.getValue());
106: if (taskLateDate.getTime() < latest) {
107: latest = taskLateDate.getTime();
108: }
109: quantity += t.getPreferredValue(AspectType.QUANTITY);
110: }
111:
112: //TODO: change this to be latestStart = min END_TIME - OST, earliestStart Tomorrow
113: startTime = alarmService.currentTimeMillis() + MILLIS_PER_DAY;
114: // System.out.println(" PREFERENCEAGG--> agg quant is " + quantity);
115: //startTime = getStartOfPeriod();
116: prefs.add(makeStartPreference(startTime, rootFactory));
117: if (earliest < startTime) {
118: earliest = startTime + 60000; // earliest arrival should never be before start time
119: }
120: // make the endTime preference...
121: prefs
122: .add(makeEndPreference(earliest, best, latest,
123: rootFactory));
124: prefs.add(makeQuantityPreference(quantity, rootFactory));
125: return prefs;
126: }
127:
128: // Added the rootFactory argument. Seemed to need it to make the pref. CGW
129: private Preference makeQuantityPreference(double amount,
130: PlanningFactory rootFactory) {
131: AspectValue av = AspectValue.newAspectValue(
132: AspectType.QUANTITY, amount);
133: ScoringFunction sf = ScoringFunction.createNearOrBelow(av, 0.1);
134: Preference pref = rootFactory.newPreference(
135: AspectType.QUANTITY, sf);
136: return pref;
137: }
138:
139: private Preference makeStartPreference(double startDate,
140: PlanningFactory rootFactory) {
141: AspectValue startTime = AspectValue.newAspectValue(
142: AspectType.START_TIME, startDate);
143: ScoringFunction sf = ScoringFunction.createNearOrAbove(
144: startTime, 0.0);
145: Preference pref = rootFactory.newPreference(
146: AspectType.START_TIME, sf);
147: return pref;
148: }
149:
150: /**
151: * makeEndPreference -
152: * separate earliest, best, and latest for TOPS. Picked 1 day out
153: * of the blue (with help from Gordon
154: */
155: private Preference makeEndPreference(double earliest, double best,
156: double latest, PlanningFactory rootFactory) {
157:
158: AspectValue earliestAV = AspectValue.newAspectValue(
159: AspectType.END_TIME, earliest);
160:
161: AspectValue bestAV = AspectValue.newAspectValue(
162: AspectType.END_TIME, best);
163:
164: AspectValue latestAV = AspectValue.newAspectValue(
165: AspectType.END_TIME, latest);
166:
167: ScoringFunction sf = ScoringFunction.createVScoringFunction(
168: earliestAV, bestAV, latestAV);
169: Preference pref = rootFactory.newPreference(
170: AspectType.END_TIME, sf);
171: return pref;
172: }
173:
174: private long getStartOfPeriod() {
175: long timeIn = alarmService.currentTimeMillis();
176: //truncate to the whole number that represents the period num since the start of time.
177: long periods = (long) (timeIn / MILLIS_PER_DAY);
178: //Multiply it back to which gives the start of the period.
179: long timeOut = timeIn * MILLIS_PER_DAY;
180: return timeOut;
181: }
182: }
|