Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 4722 was 4722, checked in by swagner, 13 years ago

Merged cloning refactoring branch back into trunk (#922)

File size: 11.3 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.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Collections;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Operators;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.PluginInfrastructure;
34
35namespace HeuristicLab.Problems.VehicleRouting.Encodings.General {
36  [Item("MultiVRPMoveGenerator", "Randomly selects and applies its move generators.")]
37  [StorableClass]
38  public class MultiVRPMoveGenerator : CheckedMultiOperator<IMultiVRPMoveGenerator>, IMultiVRPMoveOperator,
39    IStochasticOperator, IMultiMoveGenerator {
40    public override bool CanChangeName {
41      get { return false; }
42    }
43
44    public IValueLookupParameter<IntValue> SampleSizeParameter {
45      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
46    }
47
48    public ILookupParameter<IVRPEncoding> VRPToursParameter {
49      get { return (ILookupParameter<IVRPEncoding>)Parameters["VRPTours"]; }
50    }
51
52    public ILookupParameter VRPMoveParameter {
53      get { return (ILookupParameter)Parameters["VRPMove"]; }
54    }
55
56    public int Cities {
57      get { return CoordinatesParameter.ActualValue.Rows - 1; }
58    }
59    public ILookupParameter<DoubleMatrix> CoordinatesParameter {
60      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
61    }
62    public ILookupParameter<DoubleMatrix> DistanceMatrixParameter {
63      get { return (ILookupParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
64    }
65    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
66      get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
67    }
68    public ILookupParameter<IntValue> VehiclesParameter {
69      get { return (ILookupParameter<IntValue>)Parameters["Vehicles"]; }
70    }
71    public ILookupParameter<DoubleValue> CapacityParameter {
72      get { return (ILookupParameter<DoubleValue>)Parameters["Capacity"]; }
73    }
74    public ILookupParameter<DoubleArray> DemandParameter {
75      get { return (ILookupParameter<DoubleArray>)Parameters["Demand"]; }
76    }
77    public ILookupParameter<DoubleArray> ReadyTimeParameter {
78      get { return (ILookupParameter<DoubleArray>)Parameters["ReadyTime"]; }
79    }
80    public ILookupParameter<DoubleArray> DueTimeParameter {
81      get { return (ILookupParameter<DoubleArray>)Parameters["DueTime"]; }
82    }
83    public ILookupParameter<DoubleArray> ServiceTimeParameter {
84      get { return (ILookupParameter<DoubleArray>)Parameters["ServiceTime"]; }
85    }
86
87    public ValueLookupParameter<DoubleArray> ProbabilitiesParameter {
88      get { return (ValueLookupParameter<DoubleArray>)Parameters["Probabilities"]; }
89    }
90    public ILookupParameter<IRandom> RandomParameter {
91      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
92    }
93
94    public DoubleArray Probabilities {
95      get { return ProbabilitiesParameter.Value; }
96      set { ProbabilitiesParameter.Value = value; }
97    }
98
99    [StorableConstructor]
100    protected MultiVRPMoveGenerator(bool deserializing) : base(deserializing) { }
101    protected MultiVRPMoveGenerator(MultiVRPMoveGenerator original, Cloner cloner) : base(original, cloner) { }
102    public override IDeepCloneable Clone(Cloner cloner) {
103      return new MultiVRPMoveGenerator(this, cloner);
104    }
105    public MultiVRPMoveGenerator()
106      : base() {
107      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
108      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
109      Parameters.Add(new ValueLookupParameter<DoubleArray>("Probabilities", "The array of relative probabilities for each operator.", new DoubleArray()));
110
111      Parameters.Add(new ValueLookupParameter<IntValue>("Cities", "The city count."));
112      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The coordinates of the cities."));
113      Parameters.Add(new LookupParameter<DoubleMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
114      Parameters.Add(new LookupParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated and used for evaluation, otherwise false."));
115      Parameters.Add(new LookupParameter<IntValue>("Vehicles", "The number of vehicles."));
116      Parameters.Add(new LookupParameter<DoubleValue>("Capacity", "The capacity of each vehicle."));
117      Parameters.Add(new LookupParameter<DoubleArray>("Demand", "The demand of each customer."));
118      Parameters.Add(new LookupParameter<DoubleArray>("ReadyTime", "The ready time of each customer."));
119      Parameters.Add(new LookupParameter<DoubleArray>("DueTime", "The due time of each customer."));
120      Parameters.Add(new LookupParameter<DoubleArray>("ServiceTime", "The service time of each customer."));
121
122      Parameters.Add(new LookupParameter<IVRPEncoding>("VRPTours", "The VRP tours."));
123      Parameters.Add(new LookupParameter<IVRPMove>("VRPMove", "The generated moves."));
124
125      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(IMultiVRPMoveGenerator)).OrderBy(op => op.Name)) {
126        if (!typeof(MultiOperator<IMultiVRPMoveGenerator>).IsAssignableFrom(type))
127          Operators.Add((IMultiVRPMoveGenerator)Activator.CreateInstance(type), true);
128      }
129    }
130
131    protected override void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IMultiVRPMoveGenerator>> e) {
132      base.Operators_ItemsRemoved(sender, e);
133      if (Probabilities != null && Probabilities.Length > Operators.Count) {
134        List<double> probs = new List<double>(Probabilities.Cast<double>());
135        var sorted = e.Items.OrderByDescending(x => x.Index);
136        foreach (IndexedItem<IMultiVRPMoveGenerator> item in sorted)
137          if (probs.Count > item.Index) probs.RemoveAt(item.Index);
138        Probabilities = new DoubleArray(probs.ToArray());
139      }
140    }
141
142    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IMultiVRPMoveGenerator>> e) {
143      base.Operators_ItemsReplaced(sender, e);
144      ParameterizeMoveGenerators();
145    }
146
147    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IMultiVRPMoveGenerator>> e) {
148      base.Operators_ItemsAdded(sender, e);
149      ParameterizeMoveGenerators();
150
151      if (Probabilities != null && Probabilities.Length < Operators.Count) {
152        double avg = (Probabilities.Where(x => x > 0).Count() > 0) ? (Probabilities.Where(x => x > 0).Average()) : (1);
153        // add the average of all probabilities in the respective places (the new operators)
154        var added = e.Items.OrderBy(x => x.Index).ToList();
155        int insertCount = 0;
156        DoubleArray probs = new DoubleArray(Operators.Count);
157        for (int i = 0; i < Operators.Count; i++) {
158          if (insertCount < added.Count && i == added[insertCount].Index) {
159            probs[i] = avg;
160            insertCount++;
161          } else if (i - insertCount < Probabilities.Length) {
162            probs[i] = Probabilities[i - insertCount];
163          } else probs[i] = avg;
164        }
165        Probabilities = probs;
166      }
167    }
168
169    private void ParameterizeMoveGenerators() {
170      foreach (IMultiVRPMoveOperator moveGenerator in Operators.OfType<IMultiVRPMoveOperator>()) {
171        if (moveGenerator.CoordinatesParameter != null) moveGenerator.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
172        if (moveGenerator.DistanceMatrixParameter != null) moveGenerator.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
173        if (moveGenerator.UseDistanceMatrixParameter != null) moveGenerator.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
174        if (moveGenerator.VehiclesParameter != null) moveGenerator.VehiclesParameter.ActualName = VehiclesParameter.Name;
175        if (moveGenerator.CapacityParameter != null) moveGenerator.CapacityParameter.ActualName = CapacityParameter.Name;
176        if (moveGenerator.DemandParameter != null) moveGenerator.DemandParameter.ActualName = DemandParameter.Name;
177        if (moveGenerator.ReadyTimeParameter != null) moveGenerator.ReadyTimeParameter.ActualName = ReadyTimeParameter.Name;
178        if (moveGenerator.DueTimeParameter != null) moveGenerator.DueTimeParameter.ActualName = DueTimeParameter.Name;
179        if (moveGenerator.ServiceTimeParameter != null) moveGenerator.ServiceTimeParameter.ActualName = ServiceTimeParameter.Name;
180
181        moveGenerator.VRPToursParameter.ActualName = VRPToursParameter.Name;
182        moveGenerator.VRPMoveParameter.ActualName = VRPMoveParameter.Name;
183      }
184      foreach (IStochasticOperator moveGenerator in Operators.OfType<IStochasticOperator>()) {
185        moveGenerator.RandomParameter.ActualName = RandomParameter.Name;
186      }
187    }
188
189    public override IOperation Apply() {
190      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one VRP move generator choose from.");
191      OperationCollection next = new OperationCollection(base.Apply());
192
193      for (int i = 0; i < SampleSizeParameter.ActualValue.Value; i++) {
194        IRandom random = RandomParameter.ActualValue;
195        DoubleArray probabilities = ProbabilitiesParameter.ActualValue;
196        if (probabilities.Length != Operators.Count) {
197          throw new InvalidOperationException(Name + ": The list of probabilities has to match the number of operators");
198        }
199        IOperator successor = null;
200        var checkedOperators = Operators.CheckedItems;
201        if (checkedOperators.Count() > 0) {
202          // select a random operator from the checked operators
203          double sum = (from indexedItem in checkedOperators select probabilities[indexedItem.Index]).Sum();
204          if (sum == 0) throw new InvalidOperationException(Name + ": All selected operators have zero probability.");
205          double r = random.NextDouble() * sum;
206          sum = 0;
207          foreach (var indexedItem in checkedOperators) {
208            sum += probabilities[indexedItem.Index];
209            if (sum > r) {
210              successor = indexedItem.Value;
211              break;
212            }
213          }
214        }
215
216        if (successor != null) {
217          next.Insert(0, ExecutionContext.CreateChildOperation(successor));
218        }
219      }
220
221      return next;
222    }
223  }
224}
Note: See TracBrowser for help on using the repository browser.