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: import org.cougaar.core.service.LoggingService;
030: import org.cougaar.planning.ldm.plan.*;
031:
032: import java.io.Serializable;
033: import java.util.Enumeration;
034: import java.util.Vector;
035:
036: /**
037: * This class is similar to the DefaultDistributor, but allocates quantities
038: * proportionally, based on input task quantities, rather than just
039: * evenly. Code cribbed extensively from the definition of DefaultDistributor
040: * @see org.cougaar.planning.ldm.plan.AllocationResultDistributor.DefaultDistributor
041: */
042: public class ProportionalDistributor implements
043: AllocationResultDistributor, Serializable {
044: private transient LoggingService myLoggingService = null;
045: public static ProportionalDistributor DEFAULT_PROPORTIONAL_DISTRIBUTOR = new ProportionalDistributor();
046:
047: public ProportionalDistributor() {
048: }
049:
050: public void setLoggingService(LoggingService ls) {
051: myLoggingService = ls;
052: }
053:
054: public LoggingService getLoggingService() {
055: return myLoggingService;
056: }
057:
058: public TaskScoreTable calculate(Vector parents, AllocationResult ar) {
059: int l = parents.size();
060:
061: if (l == 0 || ar == null)
062: return null;
063:
064: if (!ar.isDefined(AspectType.QUANTITY)) {
065: // if there's no quantity in the Allocation result, then we
066: // can just use the Default Distributor
067: return AllocationResultDistributor.DEFAULT.calculate(
068: parents, ar);
069: } else {
070: // this variable is never used, should we delete it?
071: double quantAchieved = ar.getValue(AspectType.QUANTITY);
072: AllocationResult results[] = new AllocationResult[l];
073: double quantProportions[] = new double[l];
074: // the following block serves to set the quantProportions array
075: {
076: // these variables are lexically scoped here --- just used
077: // to compute proportional share...
078: double totalRequestedQuant = 0.0;
079: double quantsRequested[] = new double[l];
080: for (int i = 0; i < l; i++) {
081: double this Quant = getTaskQuantity(((Task) parents
082: .get(i)));
083: if (this Quant == -1.0) {
084: // no quantity was requested, set to zero
085:
086: if (getLoggingService() == null) {
087: System.err
088: .println("ProportionalDistributor: attempting to allocate a proportional share of quantity to a Task which requests no quantity.");
089: } else {
090: getLoggingService()
091: .warn(
092: "ProportionalDistributor: attempting to allocate a proportional share of quantity to a Task which requests no quantity.");
093: }
094: this Quant = 0.0;
095: }
096: totalRequestedQuant += this Quant;
097: quantsRequested[i] = this Quant;
098: }
099: if (totalRequestedQuant == 0.0) {
100: // make sure we catch the boundary condition!
101: for (int i = 0; i < l; i++) {
102: quantProportions[i] = 0.0;
103: }
104: } else {
105: for (int i = 0; i < l; i++) {
106: quantProportions[i] = quantsRequested[i]
107: / totalRequestedQuant;
108: }
109: }
110: }
111:
112: // build a result for each parent task
113: for (int i = 0; i < l; i++) {
114:
115: // create a value vector and fill in the values for the
116: // defined aspects ONLY.
117: int[] types = ar.getAspectTypes();
118: double acc[] = new double[types.length];
119: for (int x = 0; x < types.length; x++) {
120: // if the aspect is COST divide evenly across parents
121: if (types[x] == AspectType.COST) {
122: acc[x] = ar.getValue(types[x]) / l;
123: } else if (types[x] == AspectType.QUANTITY) {
124: // if the aspect is QUANTITY, we'll have to divide
125: // proportionally across parents
126: acc[x] = ar.getValue(types[x])
127: * quantProportions[i];
128: } else {
129: acc[x] = ar.getValue(types[x]);
130: }
131: }
132:
133: results[i] = new AllocationResult(ar
134: .getConfidenceRating(), ar.isSuccess(), types,
135: acc);
136:
137: // fill in the auxiliaryquery info
138: // each of the new allocationresults(for the parents)
139: // will have the SAME
140: // auxiliaryquery info that the allocationresult (of the child) has.
141: for (int aq = 0; aq < AuxiliaryQueryType.AQTYPE_COUNT; aq++) {
142: String info = ar.auxiliaryQuery(aq);
143: if (info != null) {
144: results[i].addAuxiliaryQueryInfo(aq, info);
145: }
146: }
147: }
148:
149: Task tasks[] = new Task[l];
150: parents.copyInto(tasks);
151:
152: return new TaskScoreTable(tasks, results);
153: }
154: }
155:
156: // the following cribbed from LCG/CGI
157: public double getTaskQuantity(Task task) {
158: return getTaskAspectValue(task, AspectType.QUANTITY);
159: } /* end method getTaskQuantity */
160:
161: /**
162: * @return value of the preference on the aspect of the task, or
163: * -1.0 if not defined.
164: * @param at The aspect type.
165: */
166: protected static double getTaskAspectValue(Task task, int at) {
167: //
168: // Grab the designated aspect value.
169: //
170: double value = -1.0d;
171: for (Enumeration preferences = task.getPreferences(); preferences
172: .hasMoreElements();) {
173: Preference preference = (Preference) preferences
174: .nextElement();
175: if (preference.getAspectType() == at) {
176: ScoringFunction sf = preference.getScoringFunction();
177: AspectScorePoint asp = sf.getBest();
178: AspectValue av = asp.getAspectValue();
179: value = av.getValue();
180: }
181: }
182: return (value);
183: }
184:
185: }
|