Free cookie consent management tool by TermsFeed Policy Generator

source: branches/thasling/DistributedGA/DistributedGA.Hive/P2PMigrationAnalyzer.cs @ 16147

Last change on this file since 16147 was 14265, checked in by thasling, 8 years ago

#2615:
changed default entries in P2PMigrationAnalyzer

File size: 13.5 KB
RevLine 
[13905]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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;
[14019]23using System.Collections;
[13905]24using System.Collections.Generic;
25using System.IO;
[14013]26using System.Linq;
[14019]27using DistributedGA.Core.Domain;
[13905]28using DistributedGA.Core.Implementation;
29using DistributedGA.Core.Interface;
[14253]30using DistributedGA.Core.Util;
[13957]31using DistributedGA.Hive;
[13905]32using HeuristicLab.Common;
33using HeuristicLab.Core;
34using HeuristicLab.Data;
35using HeuristicLab.Operators;
36using HeuristicLab.Parameters;
37using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
38
39namespace HeuristicLab.Optimization.Operators {
40  [Item("P2PMigrationAnalyzer", "Migrates individuals using a P2P network.")]
41  [StorableClass]
[14252]42  public class P2PMigrationAnalyzer : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator, IDisposable {
[13905]43    // state: messagehandler
[14033]44    [ExcludeFromObjectGraphTraversalAttribute]
[13905]45    private IMessageHandler h;
46
[13969]47    public bool EnabledByDefault { get { return false; } }
48
[13960]49    public ILookupParameter<BoolValue> MaximizationParameter {
50      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
51    }
52    // for name translation
53    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
54      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
55    }
[13905]56    public ILookupParameter<IntValue> MigrationIterationsParameter {
57      get { return (ILookupParameter<IntValue>)Parameters["MigrationIterations"]; }
58    }
[14061]59    public IValueParameter<PercentValue> MigrationRatesParameter {
60      get { return (IValueParameter<PercentValue>)Parameters["MigrationRate"]; }
[13957]61    }
[14061]62    public IValueParameter<PercentValue> CommunicationRatesParameter {
63      get { return (IValueParameter<PercentValue>)Parameters["CommunicationRate"]; }
[13957]64    }
[14061]65    public IValueParameter<IntValue> MessageCacheCapacityParameter {
66      get { return (IValueParameter<IntValue>)Parameters["MessageCacheCapacity"]; }
[13957]67    }
[13905]68    public ILookupParameter<IRandom> RandomParameter {
69      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
70    }
71    public IValueParameter<IntValue> MigrationIntervalParameter {
72      get { return (IValueParameter<IntValue>)Parameters["MigrationInterval"]; }
73    }
74    public IValueParameter<ILog> LogParameter {
75      get { return (IValueParameter<ILog>)Parameters["Log"]; }
76    }
[14060]77    public IValueParameter<StringValue> JobGuidParameter {
78      get { return (IValueParameter<StringValue>)Parameters["JobGUID"]; }
[14019]79    }
[13905]80
[14009]81    public IConstrainedValueParameter<EnumValue<MigrationStrategy>> MigrationStrategySelectParameter {
82      get { return (IConstrainedValueParameter<EnumValue<MigrationStrategy>>)Parameters["MigrationStrategySelect"]; }
[13960]83    }
84
[14009]85    public IConstrainedValueParameter<EnumValue<MigrationStrategy>> MigrationStrategyReplaceParameter {
86      get { return (IConstrainedValueParameter<EnumValue<MigrationStrategy>>)Parameters["MigrationStrategyReplace"]; }
87    }
88
[13960]89    public BoolValue Maximization {
90      get { return MaximizationParameter.ActualValue; }
91    }
[13905]92    public IntValue MigrationIterations {
93      get { return MigrationIterationsParameter.ActualValue; }
94    }
95
96    public IntValue MigrationInterval {
97      get { return MigrationIntervalParameter.Value; }
98    }
99
100    public IRandom Random {
101      get { return RandomParameter.ActualValue; }
102    }
103
104    [StorableConstructor]
105    protected P2PMigrationAnalyzer(bool deserializing) : base(deserializing) { }
106    protected P2PMigrationAnalyzer(P2PMigrationAnalyzer original, Cloner cloner) : base(original, cloner) { }
107
108    public P2PMigrationAnalyzer()
109      : base() {
110      Parameters.Add(new LookupParameter<IntValue>("MigrationIterations"));
[13960]111      Parameters.Add(new LookupParameter<BoolValue>("Maximization"));
112      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", 1));
[14009]113      Parameters.Add(new ValueParameter<IntValue>("MigrationInterval", "", new IntValue(5)));
[13960]114      Parameters.Add(new ValueParameter<PercentValue>("MigrationRate", "", new PercentValue(0.05)));
[14265]115      Parameters.Add(new ValueParameter<PercentValue>("CommunicationRate", "", new PercentValue(0.25)));
116      Parameters.Add(new ValueParameter<IntValue>("MessageCacheCapacity", "", new IntValue(40)));
[13905]117      Parameters.Add(new ValueParameter<StringValue>("LanIpPrefix", "", new StringValue("10.")));
118      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator"));
[14265]119      Parameters.Add(new ValueParameter<StringValue>("ContactServerURL", "", new StringValue("net.tcp://10.20.71.18:9090/DistributedGA.ContactServer/ContactService")));
[13905]120      Parameters.Add(new ValueParameter<StringValue>("JobGUID", "", new StringValue(Guid.NewGuid().ToString())));
121      Parameters.Add(new ValueParameter<ILog>("Log", "The log", new Log(1000)));
[14253]122      Parameters.Add(new ValueParameter<IntValue>("ByteArraysAllocated", new IntValue(0)));
123      Parameters.Add(new ValueParameter<IntValue>("ByteArraysFreed", new IntValue(0)));
124      Parameters.Add(new ValueParameter<IntValue>("ByteArraysAlive", new IntValue(0)));
[13960]125
126      var validValues = new ItemSet<EnumValue<MigrationStrategy>>();
[14009]127      validValues.Add(new EnumValue<MigrationStrategy>(MigrationStrategy.Best));
128      validValues.Add(new EnumValue<MigrationStrategy>(MigrationStrategy.Worst));
129      validValues.Add(new EnumValue<MigrationStrategy>(MigrationStrategy.Random));
130      Parameters.Add(new ConstrainedValueParameter<EnumValue<MigrationStrategy>>("MigrationStrategySelect", validValues, (new EnumValue<MigrationStrategy>(MigrationStrategy.Random))));
131      Parameters.Add(new ConstrainedValueParameter<EnumValue<MigrationStrategy>>("MigrationStrategyReplace", validValues, (new EnumValue<MigrationStrategy>(MigrationStrategy.Random))));
[13960]132
[13905]133    }
134
135    public override IDeepCloneable Clone(Cloner cloner) {
136      return new P2PMigrationAnalyzer(this, cloner);
137    }
138
[14013]139    public override void ClearState() {
140      base.ClearState();
[14252]141      Dispose();
[14013]142    }
143
[13969]144    private void Init() {
[13905]145      h = new PeerNetworkMessageHandler();
146      var lanIpPrefix = ((StringValue)(Parameters["LanIpPrefix"].ActualValue)).Value;
147      var contactServerUri = ((StringValue)(Parameters["ContactServerURL"].ActualValue)).Value;
[13956]148      var problemInstance = ((StringValue)Parameters["JobGUID"].ActualValue).Value;
[13960]149      var communicationRate = ((PercentValue)Parameters["CommunicationRate"].ActualValue).Value;
[13957]150      var messageCacheCapacity = ((IntValue)Parameters["MessageCacheCapacity"].ActualValue).Value;
[14253]151      h.Init(lanIpPrefix, contactServerUri, problemInstance, messageCacheCapacity, (int)(100 * communicationRate));
[13969]152      h.ExceptionOccurend += ExceptionThrown;
[13905]153    }
154
155    public override IOperation Apply() {
[13969]156      if (h == null) {
157        Init();
[14013]158      }
[14009]159
[13905]160      if (MigrationIterationsParameter.ActualValue == null) {
161        MigrationIterationsParameter.ActualValue = new IntValue(0);
162      }
163
164      if (MigrationIterations.Value % MigrationInterval.Value == 0) {
165
166        IScope scope = ExecutionContext.Scope;
167        List<IScope> emigrantsList = new List<IScope>();
168
[13957]169        //define how many migrants to send
[13960]170        var migrationRate = ((PercentValue)Parameters["MigrationRate"].ActualValue).Value;
[13970]171        int noOfEmigrants = Convert.ToInt32(scope.SubScopes.Count * migrationRate);
172        if (noOfEmigrants == 0 && scope.SubScopes.Count > 0) {
[14010]173          noOfEmigrants = 1;
[13970]174        }
[13960]175        var popQualities = QualityParameter.ActualValue;
[14013]176        var pop = new List<IScope>(scope.SubScopes);
177
178        List<IScope> sortedPop;
179        if (Maximization.Value) {
180          sortedPop = pop.Zip(popQualities, Tuple.Create).OrderByDescending(t => t.Item2).Select(t => t.Item1).ToList();
181        } else {
182          sortedPop = pop.Zip(popQualities, Tuple.Create).OrderBy(t => t.Item2).Select(t => t.Item1).ToList();
183        }
184
[14009]185        var selectedMigStratSelect = MigrationStrategySelectParameter.Value.Value;
186        var selectedMigStratReplace = MigrationStrategyReplaceParameter.Value.Value;
[13960]187
[13969]188        var rand = Random;
189        int replIdx = 0;
190        IScope emigrants = null;
[13905]191
[13970]192        for (int i = 0; i < noOfEmigrants; i++) {
[13969]193          //select emigrant depending on strategy
[14009]194          switch (selectedMigStratSelect) {
195            case MigrationStrategy.Best:
[14013]196              emigrants = sortedPop[i];
[13969]197              emigrantsList.Add(emigrants);
198              break;
199
[14009]200            case MigrationStrategy.Random:
[14013]201              replIdx = rand.Next(sortedPop.Count);
202              emigrants = sortedPop[replIdx];
[13969]203              emigrantsList.Add(emigrants);
204              break;
205
[14009]206            case MigrationStrategy.Worst:
[14013]207              emigrants = sortedPop[scope.SubScopes.Count - i - 1];
[13969]208              emigrantsList.Add(emigrants);
209              break;
210          }
211        }
212
[13905]213        {
214          // send
215          for (int ei = 0; ei < emigrantsList.Count; ei++) {
216            using (var stream = new MemoryStream()) {
[13972]217              byte[] message;
[13905]218              var emigrantScope = emigrantsList[ei];
[13969]219
[13960]220              var msgScope = new Scope();
221              var cloner = new Cloner();
222              foreach (var variable in emigrantScope.Variables) {
223                msgScope.Variables.Add((IVariable)variable.Clone(cloner));
224              }
225              HeuristicLab.Persistence.Default.Xml.XmlGenerator.Serialize(msgScope, stream);
[13972]226              message = stream.GetBuffer();
[14253]227              h.PublishDataToNetwork(ByteArrayWrapper.CreateByteArrayWrapper(message));
[13905]228            }
229          }
230        }
231
232
233        {
234          // recieve
235          var message = h.GetDataFromNetwork();
[14253]236          List<KeyValuePair<PeerInfo, ByteArrayWrapper>> immigrants = new List<KeyValuePair<PeerInfo, ByteArrayWrapper>>();
[14019]237          //limit number of immigrants to use
[14061]238          if (noOfEmigrants < message.Count) {
[14019]239            immigrants = message.Skip(Math.Max(0, message.Count() - noOfEmigrants)).ToList();
240          } else {
241            immigrants = message;
242          }
[14061]243
[14013]244          // remove individuals from population to make place for immigrants
[14019]245          for (int i = 0; i < immigrants.Count; i++) {
[14013]246            switch (selectedMigStratReplace) {
247              case MigrationStrategy.Best:
248                scope.SubScopes.Remove(sortedPop[0]);
249                sortedPop.RemoveAt(0);
250                break;
251
252              case MigrationStrategy.Random:
253                replIdx = rand.Next(sortedPop.Count);
254                scope.SubScopes.Remove(sortedPop[replIdx]);
255                sortedPop.RemoveAt(replIdx);
256                break;
257
258              case MigrationStrategy.Worst:
259                //replace random
260                scope.SubScopes.Remove(sortedPop[sortedPop.Count - 1]);
261                sortedPop.RemoveAt(sortedPop.Count - 1);
262                break;
263            }
264          }
265
266          //insert individual sorted in population
267          var qualities = QualityParameter.ActualValue;
268          var qualityTranslatedName = QualityParameter.TranslatedName;
[14019]269          foreach (var msg in immigrants) {
[14253]270            using (var stream = new MemoryStream(msg.Value.Array)) {
[13905]271              var immigrantScope = HeuristicLab.Persistence.Default.Xml.XmlParser.Deserialize<IScope>(stream);
272
[13960]273              var qImmigrant = ((DoubleValue)immigrantScope.Variables[qualityTranslatedName].Value).Value;
274              var insertPos = scope.SubScopes.Count;
275              var maximization = Maximization.Value;
276              for (int i = 0; i < qualities.Length; i++) {
277                var qi = qualities[i].Value;
278                if ((maximization && qi < qImmigrant) || (!maximization && qi > qImmigrant)) {
279                  insertPos = i;
280                  break;
281                }
282              }
283
284              scope.SubScopes.Insert(insertPos, immigrantScope);
285
[14261]286               var log = LogParameter.Value;
287               double quality = qImmigrant;
288               log.LogMessage(string.Format("Recieved individual with quality {0} from peer {1}:{2} ; Job: {3}",
289                                             quality, msg.Key.IpAddress, msg.Key.Port, msg.Key.ProblemInstance));
[13905]290            }
291          }
292        }
293      }
294
295      MigrationIterations.Value++;
[14253]296
297      ((IValueParameter<IntValue>)Parameters["ByteArraysAllocated"]).Value.Value = ByteArrayWrapper.AllocatedCounter;
298      ((IValueParameter<IntValue>)Parameters["ByteArraysFreed"]).Value.Value = ByteArrayWrapper.FreedCounter;
299      ((IValueParameter<IntValue>)Parameters["ByteArraysAlive"]).Value.Value = ByteArrayWrapper.AliveCounter;
300
[13905]301      return base.Apply();
302    }
303
[13969]304    private void ExceptionThrown(object sender, Exception e) {
305      var log = LogParameter.Value;
306      log.LogMessage(e.Message);
[13965]307    }
308
[14252]309    public void Dispose() {
310      h.Dispose();
311      h = null;
312    }
313
[13905]314  }
315}
Note: See TracBrowser for help on using the repository browser.