001    /**
002     * planningtool - A Planning Tool with Critiquing Support.
003     * 
004     * Copyright (C) 2006 olale
005    
006     * This program is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU General Public License
008     * as published by the Free Software Foundation; either version 2
009     * of the License, or (at your option) any later version.
010    
011     * This program is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014     * GNU General Public License for more details.
015    
016     * You should have received a copy of the GNU General Public License
017     * along with this program; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019    
020     * Contact information: 
021     * E-mail: olale@ida.liu.se
022     *         olale@lysator.liu.se
023     */
024    package se.liu.ida.critiquer.scenarios.standard;
025    
026    import java.util.HashMap;
027    import java.util.Vector;
028    
029    import se.liu.ida.critiquer.mics.Utils;
030    import se.liu.ida.critiquer.resources.Agent;
031    import se.liu.ida.critiquer.resources.AgentContributionCalculator;
032    import se.liu.ida.critiquer.resources.ParameterInAgent;
033    import se.liu.ida.critiquer.resources.SingleSelectionParameter;
034    
035    /**
036     * 
037     * <p>
038     * This class contains static factory methods for constructing parameters that
039     * are part of <i>agents</i>, not activities
040     * </p>
041     */
042    public class StandardAgentParameterFactory {
043          
044    
045    
046            private static Vector<Long> createTimeRange() {
047                    Vector<Long> timeRange = new Vector<Long>();
048                    for (long i = 0; i < 200; i += 10) {
049                            timeRange.add(i);
050                    }
051                    
052                    
053                    return timeRange;
054            }
055    
056            private static Vector<Integer> createCapacityRange() {
057                    Vector<Integer> capacityRange = new Vector<Integer>();
058                    for (int i = 0; i < 10; i++) {
059                            capacityRange.add(i);
060                    }
061                    return capacityRange;
062            }
063    
064    
065            public static void createFuelParameters(Agent agent,int fuelTankCapacity,int fuelConsumption) {
066                    agent.addParameter(new SingleSelectionParameter<Integer>(AgentParameterName.FUEL_CAPACITY,agent,
067                                    Utils.toVector(new Integer[] {10,30,50,70,90,110,130}),fuelTankCapacity));
068                    /**
069                     * Fuel consumption in litres per 100 kilometers
070                     */
071                    agent.addParameter(new SingleSelectionParameter<Integer>(AgentParameterName.FUEL_CONSUMPTION,agent,
072                                    Utils.toVector(new Integer[] {
073                                  1,2,3,4,5,6,7,8,9,10,15,20,40,80                                                                                                 
074                                    }),new Integer(fuelConsumption)));
075            }
076            
077            /**
078             * The speed parameter dictates how long time it will take to dispatch units as well as to go between locations later.
079             * */
080            public static void createSpeedParameter(final Agent a,long initialSpeed) {
081    
082                    a.addParameter(new SingleSelectionParameter<Long>(AgentParameterName.SPEED, a,
083                                    createTimeRange(), initialSpeed));
084    
085                    /**
086                     * Calculate time for dispatch mission in minutes
087                     */
088                    a.missionContributionCalculators.put(DispatchActivity.class,
089                                    new AgentContributionCalculator<DispatchActivity>() {
090    
091                                            /**
092                                             * 
093                                             */
094                                            private static final long serialVersionUID = 1L;
095    
096                                            public long perform(DispatchActivity activity,
097                                                            HashMap<String, Integer> attributes) {
098                                                    long speed = a.getParamByClassAndName(Long.class,
099                                                                    AgentParameterName.SPEED).getValue();
100                                                    double distance = activity.getStart().distanceTo(activity.getEnd());
101                                                    return (long) ((distance / speed) * 60);
102                                            }
103    
104                                    });
105    
106            }
107    
108            /**
109             * <p> Creates parameters for taking care of patients, indicating both how many
110             * this agent can cater at a time as well as how long it takes to
111             * administrate first aid to such a group
112             *</p>
113             */
114            public static void createFirstAidParameters(final Agent a,
115                            long initialTime, int initialCapacity) {
116    
117                    a.addParameter(new SingleSelectionParameter<Long>(
118                                    AgentParameterName.FIRST_AID_TIME, a, createTimeRange(), initialTime));
119    
120                    a.addParameter(new SingleSelectionParameter<Integer>(
121                                                    AgentParameterName.FIRST_AID_CAPACITY, a, createCapacityRange(),
122                                                    initialCapacity));
123    
124                    a.missionContributionCalculators.put(FirstAidActivity.class,
125                                    new AgentContributionCalculator<FirstAidActivity>() {
126    
127                                            /**
128                                             * 
129                                             */
130                                            private static final long serialVersionUID = 1L;
131    
132                                            public long perform(FirstAidActivity activity,
133                                                            HashMap<String, Integer> attributes) {
134                                                    long time = a.getParamByClassAndName(Long.class,
135                                                                    AgentParameterName.FIRST_AID_TIME).getValue();
136                                                    int patientsBefore = attributes.get("patients");
137    
138                                                    if (patientsBefore > 0) {
139                                                            int emergencyCapacity = a.getParamByClassAndName(
140                                                                            Integer.class, AgentParameterName.FIRST_AID_CAPACITY)
141                                                                            .getValue();
142                                                            int patientsAfter = Math.max(0, patientsBefore
143                                                                            - emergencyCapacity);
144                                                            attributes.put("patients", patientsAfter);
145                                                            return time;
146                                                    } else {
147                                                            return 0;
148                                                    }
149    
150                                            }
151    
152                                    });
153    
154            }
155    
156            /**
157             * <p>Creates a parameter that describes the transportation capacity of the
158             * agent.
159             * </p> 
160             * <p>This requires a speed parameter to be present and will create one if it
161             * doesn't exist. 
162             * </p> 
163             * <p>Also, we hook up a time calculator for RecoverActivities here.
164             * </p> 
165             */
166            public static void createTransportParameter(final Agent a,int initialCapacity) {
167    
168                    ParameterInAgent<Long> speedParameter = a.getParamByClassAndName(
169                                    Long.class, AgentParameterName.SPEED);
170                    if (speedParameter == null) {
171                            createSpeedParameter(a,100);
172                    }
173                    a.addParameter(new SingleSelectionParameter<Integer>(
174                                    AgentParameterName.TRANSPORT_CAPACITY, a, createCapacityRange(), initialCapacity));
175                    
176                    a.missionContributionCalculators.put(RecoverActivity.class,
177                                    new AgentContributionCalculator<RecoverActivity>() {
178    
179                                            /**
180                                             * 
181                                             */
182                                            private static final long serialVersionUID = 1L;
183    
184                                            public long perform(RecoverActivity activity,
185                                                            HashMap<String, Integer> attributes) {
186                                                    int patientsBefore = attributes.get("patients");
187                                                    int transportCapacity = a.getParamByClassAndName(
188                                                                    Integer.class, AgentParameterName.TRANSPORT_CAPACITY).getValue();
189                                                    int patientsAfter = Math.max(0, patientsBefore
190                                                                    - transportCapacity);
191                                                    attributes.put("patients", patientsAfter);
192                                                    Long speed = a.getParamByClassAndName(Long.class,
193                                                                    AgentParameterName.SPEED).getValue();
194                                                    double distance = activity.getStart().distanceTo(activity.getEnd());
195                                                    return (long) ((distance / speed) * 60);
196                                            }
197    
198                                    });
199            }
200    
201    
202            public static void createRoadBlockTimeParameter(final Agent a,long initialTime) {
203                    a.addParameter(new SingleSelectionParameter<Long>(AgentParameterName.ROADBLOCK_TIME,a,createTimeRange(),initialTime));
204                    a.missionContributionCalculators.put(RoadBlockActivity.class,
205                                    new AgentContributionCalculator<RoadBlockActivity>(){
206                            
207                            /**
208                             * 
209                             */
210                            private static final long serialVersionUID = 1L;
211                            
212                            public long perform(RoadBlockActivity activity, HashMap<String,Integer> attributes) {
213                                    return a.getParamByClassAndName(Long.class,AgentParameterName.ROADBLOCK_TIME).getValue();
214                            }
215                            
216                    });
217            }
218    
219    
220    }