Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/General/Moves/MultiVRPMoveOperator/MultiVRPMoveGenerator.cs @ 4205

Last change on this file since 4205 was 4205, checked in by svonolfe, 14 years ago

Added MultiVRPMove (#1039)

File size: 11.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Linq;
24using HeuristicLab.Collections;
25using HeuristicLab.Core;
26using HeuristicLab.Operators;
27using HeuristicLab.Optimization;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30using HeuristicLab.PluginInfrastructure;
31using HeuristicLab.Data;
32using System.Collections.Generic;
33
34namespace HeuristicLab.Problems.VehicleRouting.Encodings.General {
35  [Item("MultiVRPMoveGenerator", "Randomly selects and applies its move generators.")]
36  [StorableClass]
37  public class MultiVRPMoveGenerator : CheckedMultiOperator<IMultiVRPMoveGenerator>, IMultiVRPMoveOperator,
38    IStochasticOperator, IMultiMoveGenerator {
39    public override bool CanChangeName {
40      get { return false; }
41    }
42
43    public IValueLookupParameter<IntValue> SampleSizeParameter {
44      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
45    }
46
47    public ILookupParameter<IVRPEncoding> VRPToursParameter {
48      get { return (ILookupParameter<IVRPEncoding>)Parameters["VRPTours"]; }
49    }
50
51    public ILookupParameter VRPMoveParameter {
52      get { return (ILookupParameter)Parameters["VRPMove"]; }
53    }
54
55    public int Cities {
56      get { return CoordinatesParameter.ActualValue.Rows - 1; }
57    }
58    public ILookupParameter<DoubleMatrix> CoordinatesParameter {
59      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
60    }
61    public ILookupParameter<DoubleMatrix> DistanceMatrixParameter {
62      get { return (ILookupParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
63    }
64    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
65      get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
66    }
67    public ILookupParameter<IntValue> VehiclesParameter {
68      get { return (ILookupParameter<IntValue>)Parameters["Vehicles"]; }
69    }
70    public ILookupParameter<DoubleValue> CapacityParameter {
71      get { return (ILookupParameter<DoubleValue>)Parameters["Capacity"]; }
72    }
73    public ILookupParameter<DoubleArray> DemandParameter {
74      get { return (ILookupParameter<DoubleArray>)Parameters["Demand"]; }
75    }
76    public ILookupParameter<DoubleArray> ReadyTimeParameter {
77      get { return (ILookupParameter<DoubleArray>)Parameters["ReadyTime"]; }
78    }
79    public ILookupParameter<DoubleArray> DueTimeParameter {
80      get { return (ILookupParameter<DoubleArray>)Parameters["DueTime"]; }
81    }
82    public ILookupParameter<DoubleArray> ServiceTimeParameter {
83      get { return (ILookupParameter<DoubleArray>)Parameters["ServiceTime"]; }
84    }
85
86    public ValueLookupParameter<DoubleArray> ProbabilitiesParameter {
87      get { return (ValueLookupParameter<DoubleArray>)Parameters["Probabilities"]; }
88    }
89    public ILookupParameter<IRandom> RandomParameter {
90      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
91    }
92
93    public DoubleArray Probabilities {
94      get { return ProbabilitiesParameter.Value; }
95      set { ProbabilitiesParameter.Value = value; }
96    }
97
98    [StorableConstructor]
99    private MultiVRPMoveGenerator(bool deserializing) : base(deserializing) { }
100    public MultiVRPMoveGenerator()
101      : base() {
102      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
103      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
104      Parameters.Add(new ValueLookupParameter<DoubleArray>("Probabilities", "The array of relative probabilities for each operator.", new DoubleArray()));
105
106      Parameters.Add(new ValueLookupParameter<IntValue>("Cities", "The city count."));
107      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The coordinates of the cities."));
108      Parameters.Add(new LookupParameter<DoubleMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
109      Parameters.Add(new LookupParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated and used for evaluation, otherwise false."));
110      Parameters.Add(new LookupParameter<IntValue>("Vehicles", "The number of vehicles."));
111      Parameters.Add(new LookupParameter<DoubleValue>("Capacity", "The capacity of each vehicle."));
112      Parameters.Add(new LookupParameter<DoubleArray>("Demand", "The demand of each customer."));
113      Parameters.Add(new LookupParameter<DoubleArray>("ReadyTime", "The ready time of each customer."));
114      Parameters.Add(new LookupParameter<DoubleArray>("DueTime", "The due time of each customer."));
115      Parameters.Add(new LookupParameter<DoubleArray>("ServiceTime", "The service time of each customer."));
116
117      Parameters.Add(new LookupParameter<IVRPEncoding>("VRPTours", "The VRP tours."));
118      Parameters.Add(new LookupParameter<IVRPMove>("VRPMove", "The generated moves."));
119
120      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(IMultiVRPMoveGenerator))) {
121        if (!typeof(MultiOperator<IMultiVRPMoveGenerator>).IsAssignableFrom(type))
122          Operators.Add((IMultiVRPMoveGenerator)Activator.CreateInstance(type), true);
123      }
124    }
125
126    protected override void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IMultiVRPMoveGenerator>> e) {
127      base.Operators_ItemsRemoved(sender, e);
128      if (Probabilities != null && Probabilities.Length > Operators.Count) {
129        List<double> probs = new List<double>(Probabilities.Cast<double>());
130        var sorted = e.Items.OrderByDescending(x => x.Index);
131        foreach (IndexedItem<IMultiVRPMoveGenerator> item in sorted)
132          if (probs.Count > item.Index) probs.RemoveAt(item.Index);
133        Probabilities = new DoubleArray(probs.ToArray());
134      }
135    }
136
137    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IMultiVRPMoveGenerator>> e) {
138      base.Operators_ItemsReplaced(sender, e);
139      ParameterizeMoveGenerators();
140    }
141
142    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IMultiVRPMoveGenerator>> e) {
143      base.Operators_ItemsAdded(sender, e);
144      ParameterizeMoveGenerators();
145
146      if (Probabilities != null && Probabilities.Length < Operators.Count) {
147        double avg = (Probabilities.Where(x => x > 0).Count() > 0) ? (Probabilities.Where(x => x > 0).Average()) : (1);
148        // add the average of all probabilities in the respective places (the new operators)
149        var added = e.Items.OrderBy(x => x.Index).ToList();
150        int insertCount = 0;
151        DoubleArray probs = new DoubleArray(Operators.Count);
152        for (int i = 0; i < Operators.Count; i++) {
153          if (insertCount < added.Count && i == added[insertCount].Index) {
154            probs[i] = avg;
155            insertCount++;
156          } else if (i - insertCount < Probabilities.Length) {
157            probs[i] = Probabilities[i - insertCount];
158          } else probs[i] = avg;
159        }
160        Probabilities = probs;
161      }
162    }
163
164    private void ParameterizeMoveGenerators() {
165      foreach (IMultiVRPMoveOperator moveGenerator in Operators.OfType<IMultiVRPMoveOperator>()) {
166        if (moveGenerator.CoordinatesParameter != null) moveGenerator.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
167        if (moveGenerator.DistanceMatrixParameter != null) moveGenerator.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
168        if (moveGenerator.UseDistanceMatrixParameter != null) moveGenerator.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
169        if (moveGenerator.VehiclesParameter != null) moveGenerator.VehiclesParameter.ActualName = VehiclesParameter.Name;
170        if (moveGenerator.CapacityParameter != null) moveGenerator.CapacityParameter.ActualName = CapacityParameter.Name;
171        if (moveGenerator.DemandParameter != null) moveGenerator.DemandParameter.ActualName = DemandParameter.Name;
172        if (moveGenerator.ReadyTimeParameter != null) moveGenerator.ReadyTimeParameter.ActualName = ReadyTimeParameter.Name;
173        if (moveGenerator.DueTimeParameter != null) moveGenerator.DueTimeParameter.ActualName = DueTimeParameter.Name;
174        if (moveGenerator.ServiceTimeParameter != null) moveGenerator.ServiceTimeParameter.ActualName = ServiceTimeParameter.Name;
175
176        moveGenerator.VRPToursParameter.ActualName = VRPToursParameter.Name;
177        moveGenerator.VRPMoveParameter.ActualName = VRPMoveParameter.Name;
178      }
179      foreach (IStochasticOperator moveGenerator in Operators.OfType<IStochasticOperator>()) {
180        moveGenerator.RandomParameter.ActualName = RandomParameter.Name;
181      }
182    }
183
184    public override IOperation Apply() {
185      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one VRP move generator choose from.");
186      OperationCollection next = new OperationCollection(base.Apply());
187
188      for (int i = 0; i < SampleSizeParameter.ActualValue.Value; i++) {
189        IRandom random = RandomParameter.ActualValue;
190        DoubleArray probabilities = ProbabilitiesParameter.ActualValue;
191        if (probabilities.Length != Operators.Count) {
192          throw new InvalidOperationException(Name + ": The list of probabilities has to match the number of operators");
193        }
194        IOperator successor = null;
195        var checkedOperators = Operators.CheckedItems;
196        if (checkedOperators.Count() > 0) {
197          // select a random operator from the checked operators
198          double sum = (from indexedItem in checkedOperators select probabilities[indexedItem.Index]).Sum();
199          if (sum == 0) throw new InvalidOperationException(Name + ": All selected operators have zero probability.");
200          double r = random.NextDouble() * sum;
201          sum = 0;
202          foreach (var indexedItem in checkedOperators) {
203            sum += probabilities[indexedItem.Index];
204            if (sum > r) {
205              successor = indexedItem.Value;
206              break;
207            }
208          }
209        }
210
211        if (successor != null) {
212          next.Insert(0, ExecutionContext.CreateChildOperation(successor));
213        }
214      }
215
216      return next;
217    }
218  }
219}
Note: See TracBrowser for help on using the repository browser.