#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, IExecutable { // state: messagehandler private IMessageHandler h; 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 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)); } public override IOperation Apply() { 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; //TODO: SELECT MIGRATION STRATEGY // TODO: select individuals based on quality var popQualities = QualityParameter.ActualValue; var selectedMigStrat = MigrationStrategyParameter.Value.Value; // select best as emigrant 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]; emigrantScope.ClearParentScopes(); var msgScope = new Scope(); var cloner = new Cloner(); foreach (var variable in emigrantScope.Variables) { msgScope.Variables.Add((IVariable)variable.Clone(cloner)); } 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 random individual in current population var rand = Random; var replIdx = rand.Next(scope.SubScopes.Count); scope.SubScopes.RemoveAt(replIdx); 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(); } public bool EnabledByDefault { get { return false; } } #region IExecutable Members public event EventHandler> ExceptionOccurred; public ExecutionState ExecutionState { get { return ExecutionState.Prepared; } } public event EventHandler ExecutionStateChanged; public TimeSpan ExecutionTime { get { return new TimeSpan(); } } public event EventHandler ExecutionTimeChanged; public void Pause() { int i = 0; } public event EventHandler Paused; public void Prepare() { int i = 0; } public event EventHandler Prepared; public void Start() { int i = 0; } public event EventHandler Started; public void Stop() { int i = 0; } public event EventHandler Stopped; #endregion } }