#region License Information /* HeuristicLab * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Data.SqlTypes; using System.IO; using System.ServiceModel.Configuration; using System.Threading; using DistributedGA.Core.Domain; using DistributedGA.Core.Implementation; using DistributedGA.Core.Interface; using DistributedGA.Hive; using HeuristicLab.Clients.Hive; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Operators; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Optimization.Operators { [Item("P2PMigrationAnalyzer", "Migrates individuals using a P2P network.")] [StorableClass] public class P2PMigrationAnalyzer : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator { // state: messagehandler private IMessageHandler h; public bool EnabledByDefault { get { return false; } } public ILookupParameter MaximizationParameter { get { return (ILookupParameter)Parameters["Maximization"]; } } // for name translation public ScopeTreeLookupParameter QualityParameter { get { return (ScopeTreeLookupParameter)Parameters["Quality"]; } } public ILookupParameter MigrationIterationsParameter { get { return (ILookupParameter)Parameters["MigrationIterations"]; } } public ILookupParameter MigrationRatesParameter { get { return (ILookupParameter)Parameters["MigrationRate"]; } } public ILookupParameter CommunicationRatesParameter { get { return (ILookupParameter)Parameters["CommunicationRate"]; } } public ILookupParameter MessageCacheCapacityParameter { get { return (ILookupParameter)Parameters["MessageCacheCapacity"]; } } public ILookupParameter RandomParameter { get { return (ILookupParameter)Parameters["Random"]; } } public IValueParameter MigrationIntervalParameter { get { return (IValueParameter)Parameters["MigrationInterval"]; } } public IValueParameter LogParameter { get { return (IValueParameter)Parameters["Log"]; } } public IConstrainedValueParameter> MigrationStrategyParameter { get { return (IConstrainedValueParameter>)Parameters["MigrationStrategy"]; } } public BoolValue Maximization { get { return MaximizationParameter.ActualValue; } } public IntValue MigrationIterations { get { return MigrationIterationsParameter.ActualValue; } } public IntValue MigrationInterval { get { return MigrationIntervalParameter.Value; } } public IRandom Random { get { return RandomParameter.ActualValue; } } [StorableConstructor] protected P2PMigrationAnalyzer(bool deserializing) : base(deserializing) { } protected P2PMigrationAnalyzer(P2PMigrationAnalyzer original, Cloner cloner) : base(original, cloner) { } public P2PMigrationAnalyzer() : base() { Parameters.Add(new LookupParameter("MigrationIterations")); Parameters.Add(new LookupParameter("Maximization")); Parameters.Add(new ScopeTreeLookupParameter("Quality", 1)); Parameters.Add(new ValueParameter("MigrationInterval", "", new IntValue(1))); Parameters.Add(new ValueParameter("MigrationRate", "", new PercentValue(0.05))); Parameters.Add(new ValueParameter("CommunicationRate", "", new PercentValue(0.10))); Parameters.Add(new ValueParameter("MessageCacheCapacity", "", new IntValue(100))); Parameters.Add(new ValueParameter("LanIpPrefix", "", new StringValue("10."))); Parameters.Add(new LookupParameter("Random", "The random number generator")); Parameters.Add(new ValueParameter("ContactServerURL", "", new StringValue("net.tcp://10.42.1.150:9090/DistributedGA.ContactServer/ContactService"))); Parameters.Add(new ValueParameter("JobGUID", "", new StringValue(Guid.NewGuid().ToString()))); Parameters.Add(new ValueParameter("Log", "The log", new Log(1000))); var validValues = new ItemSet>(); validValues.Add(new EnumValue(MigrationStrategy.TakeBestReplaceBad)); validValues.Add(new EnumValue(MigrationStrategy.TakeBestReplaceRandom)); validValues.Add(new EnumValue(MigrationStrategy.TakeRandomReplaceBad)); validValues.Add(new EnumValue(MigrationStrategy.TakeRandomReplaceRandom)); Parameters.Add(new ConstrainedValueParameter>("MigrationStrategy", validValues, (new EnumValue(MigrationStrategy.TakeBestReplaceBad)))); } public override IDeepCloneable Clone(Cloner cloner) { return new P2PMigrationAnalyzer(this, cloner); } public override void ClearState() { base.ClearState(); h.Dispose(); h = null; } public override void InitializeState() { base.InitializeState(); // init P2P Init(); } private void Init() { h = new PeerNetworkMessageHandler(); var lanIpPrefix = ((StringValue)(Parameters["LanIpPrefix"].ActualValue)).Value; var contactServerUri = ((StringValue)(Parameters["ContactServerURL"].ActualValue)).Value; var problemInstance = ((StringValue)Parameters["JobGUID"].ActualValue).Value; var communicationRate = ((PercentValue)Parameters["CommunicationRate"].ActualValue).Value; var messageCacheCapacity = ((IntValue)Parameters["MessageCacheCapacity"].ActualValue).Value; h.Init(lanIpPrefix, contactServerUri, problemInstance, (int)(100 * messageCacheCapacity), (int)(100 * communicationRate)); h.ExceptionOccurend += ExceptionThrown; } public override IOperation Apply() { if (h == null) { Init(); } if (MigrationIterationsParameter.ActualValue == null) { MigrationIterationsParameter.ActualValue = new IntValue(0); } if (MigrationIterations.Value % MigrationInterval.Value == 0) { IScope scope = ExecutionContext.Scope; List emigrantsList = new List(); //define how many migrants to send var migrationRate = ((PercentValue)Parameters["MigrationRate"].ActualValue).Value; var popQualities = QualityParameter.ActualValue; var selectedMigStrat = MigrationStrategyParameter.Value.Value; var rand = Random; int replIdx = 0; IScope emigrants = null; //determine how many emigrants to send int max = Convert.ToInt32(scope.SubScopes.Count * migrationRate); if (max == 0 && scope.SubScopes.Count > 0) { max = 0; } for (int i = 0; i < max; i++) { //select emigrant depending on strategy switch (selectedMigStrat) { case MigrationStrategy.TakeBestReplaceBad: emigrants = scope.SubScopes[i]; emigrantsList.Add(emigrants); break; case MigrationStrategy.TakeBestReplaceRandom: emigrants = scope.SubScopes[i]; emigrantsList.Add(emigrants); break; case MigrationStrategy.TakeRandomReplaceBad: replIdx = rand.Next(scope.SubScopes.Count); emigrants = scope.SubScopes[replIdx]; emigrantsList.Add(emigrants); break; case MigrationStrategy.TakeRandomReplaceRandom: replIdx = rand.Next(scope.SubScopes.Count); emigrants = scope.SubScopes[replIdx]; emigrantsList.Add(emigrants); break; default: break; } } //each subscope is one emigrand //IScope emigrants = scope.SubScopes[1]; //emigrantsList.Add(emigrants); { // send var message = new byte[emigrantsList.Count][]; for (int ei = 0; ei < emigrantsList.Count; ei++) { using (var stream = new MemoryStream()) { var emigrantScope = emigrantsList[ei]; var msgScope = new Scope(); var cloner = new Cloner(); foreach (var variable in emigrantScope.Variables) { msgScope.Variables.Add((IVariable)variable.Clone(cloner)); } msgScope.ClearParentScopes(); HeuristicLab.Persistence.Default.Xml.XmlGenerator.Serialize(msgScope, stream); message[ei] = stream.GetBuffer(); } } h.PublishDataToNetwork(message); } { // recieve var message = h.GetDataFromNetwork(); for (int ei = 0; ei < message.Length; ei++) { using (var stream = new MemoryStream(message[ei])) { var immigrantScope = HeuristicLab.Persistence.Default.Xml.XmlParser.Deserialize(stream); // replace individual in current population switch (selectedMigStrat) { case MigrationStrategy.TakeBestReplaceBad: scope.SubScopes.RemoveAt(0); break; case MigrationStrategy.TakeRandomReplaceBad: scope.SubScopes.RemoveAt(0); break; case MigrationStrategy.TakeBestReplaceRandom: //replace random replIdx = rand.Next(scope.SubScopes.Count); scope.SubScopes.RemoveAt(replIdx); break; case MigrationStrategy.TakeRandomReplaceRandom: //replace random replIdx = rand.Next(scope.SubScopes.Count); scope.SubScopes.RemoveAt(replIdx); break; default: break; } //insert individual sortet in population var qualities = QualityParameter.ActualValue; var qualityTranslatedName = QualityParameter.TranslatedName; var qImmigrant = ((DoubleValue)immigrantScope.Variables[qualityTranslatedName].Value).Value; var insertPos = scope.SubScopes.Count; var maximization = Maximization.Value; for (int i = 0; i < qualities.Length; i++) { var qi = qualities[i].Value; if ((maximization && qi < qImmigrant) || (!maximization && qi > qImmigrant)) { insertPos = i; break; } } scope.SubScopes.Insert(insertPos, immigrantScope); var log = LogParameter.Value; double quality = 0.0; quality = qImmigrant; log.LogMessage(string.Format("Recieved individual with quality {0}", quality)); } } } } MigrationIterations.Value++; return base.Apply(); } private void ExceptionThrown(object sender, Exception e) { var log = LogParameter.Value; log.LogMessage(e.Message); } } }