Index: trunk/sources/HeuristicLab 3.3.sln
===================================================================
--- trunk/sources/HeuristicLab 3.3.sln	(revision 11938)
+++ trunk/sources/HeuristicLab 3.3.sln	(revision 11939)
@@ -410,4 +410,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.CodeEditor-3.4", "HeuristicLab.CodeEditor\3.4\HeuristicLab.CodeEditor-3.4.csproj", "{C38691AE-ECB4-489A-A05D-B035554E0168}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3", "HeuristicLab.Algorithms.ParameterlessPopulationPyramid\3.3\HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3.csproj", "{9319C447-8183-4DBC-8145-0E3CF98084CC}"
 EndProject
 Global
@@ -1991,7 +1993,18 @@
 		{C38691AE-ECB4-489A-A05D-B035554E0168}.Release|x86.ActiveCfg = Release|x86
 		{C38691AE-ECB4-489A-A05D-B035554E0168}.Release|x86.Build.0 = Release|x86
+		{9319C447-8183-4DBC-8145-0E3CF98084CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9319C447-8183-4DBC-8145-0E3CF98084CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9319C447-8183-4DBC-8145-0E3CF98084CC}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{9319C447-8183-4DBC-8145-0E3CF98084CC}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{9319C447-8183-4DBC-8145-0E3CF98084CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9319C447-8183-4DBC-8145-0E3CF98084CC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9319C447-8183-4DBC-8145-0E3CF98084CC}.Release|x64.ActiveCfg = Release|Any CPU
+		{9319C447-8183-4DBC-8145-0E3CF98084CC}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
+	GlobalSection(Performance) = preSolution
+		HasPerformanceSessions = true
+	EndGlobalSection
 EndGlobal
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/EnumerableBoolEqualityComparer.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/EnumerableBoolEqualityComparer.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/EnumerableBoolEqualityComparer.cs	(revision 11939)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  public class EnumerableBoolEqualityComparer : IEqualityComparer<IEnumerable<bool>> {
+    public bool Equals(IEnumerable<bool> first, IEnumerable<bool> second) {
+      return first.SequenceEqual(second);
+    }
+    public int GetHashCode(IEnumerable<bool> obj) {
+      int hash = 0;
+      int word = 1;
+      foreach (bool bit in obj) {
+        // load bits into an integer
+        word <<= 1;
+        word |= Convert.ToInt32(bit);
+        // only happens when the leading 1 reaches the sign bit
+        if (word < 0) {
+          // combine word into the hash
+          hash ^= word;
+          word = 1;
+        }
+      }
+      // combine in any remaining content
+      if (word > 1) {
+        hash ^= word;
+      }
+      return hash;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3.csproj	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3.csproj	(revision 11939)
@@ -0,0 +1,142 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{9319C447-8183-4DBC-8145-0E3CF98084CC}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Algorithms.ParameterlessPopulationPyramid</RootNamespace>
+    <AssemblyName>HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="EnumerableBoolEqualityComparer.cs" />
+    <Compile Include="LinkageCrossover.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Problems\DeceptiveStepTrapProblem.cs" />
+    <Compile Include="Problems\DeceptiveTrapProblem.cs" />
+    <Compile Include="HillClimber.cs" />
+    <Compile Include="LinkageTree.cs" />
+    <Compile Include="ParameterlessPopulationPyramid.cs" />
+    <Compile Include="Population.cs" />
+    <Compile Include="Problems\BinaryVectorProblem.cs" />
+    <Compile Include="Problems\EvaluationTracker.cs" />
+    <Compile Include="Problems\HIFFProblem.cs" />
+    <Compile Include="Problems\IBinaryVectorProblem.cs" />
+    <Compile Include="Problems\OneMaxProblem.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425b4-4348-49ed-a457-b7d2c26ddbf9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958b43bc-cc5c-4fa2-8628-2b3b01d890b6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{a9ad58b9-3ef9-4cc1-97e5-8d909039ff5c}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{c36bd924-a541-4a00-afa8-41701378ddc5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.BinaryVectorEncoding\3.3\HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj">
+      <Project>{66d249c3-a01d-42a8-82a2-919bc8ec3d83}</Project>
+      <Name>HeuristicLab.Encodings.BinaryVectorEncoding-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
+      <Project>{56f9106a-079f-4c61-92f6-86a84c2d84b7}</Project>
+      <Name>HeuristicLab.Parameters-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Persistence\3.3\HeuristicLab.Persistence-3.3.csproj">
+      <Project>{102bc7d3-0ef9-439c-8f6d-96ff0fdb8e1b}</Project>
+      <Name>HeuristicLab.Persistence-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186a6a-5176-4402-ae83-886557b53cca}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
+      <Project>{f4539fb6-4708-40c9-be64-0a1390aea197}</Project>
+      <Name>HeuristicLab.Random-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/HillClimber.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/HillClimber.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/HillClimber.cs	(revision 11939)
@@ -0,0 +1,118 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  // This code is based off the publication
+  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
+  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
+  [Item("Hill Climber", "Test algorithm.")]
+  [StorableClass]
+  [Creatable("Parameterless Population Pyramid")]
+  public class HillClimber : BasicAlgorithm {
+    [Storable]
+    private IRandom random;
+
+    private const string IterationsParameterName = "Iterations";
+
+    public override Type ProblemType {
+      get { return typeof(BinaryVectorProblem); }
+    }
+    public new BinaryVectorProblem Problem {
+      get { return (BinaryVectorProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    public IFixedValueParameter<IntValue> IterationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[IterationsParameterName]; }
+    }
+
+    public int Iterations {
+      get { return IterationsParameter.Value.Value; }
+      set { IterationsParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected HillClimber(bool deserializing) : base(deserializing) { }
+    protected HillClimber(HillClimber original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HillClimber(this, cloner);
+    }
+
+    public HillClimber()
+      : base() {
+      random = new MersenneTwister();
+      Parameters.Add(new FixedValueParameter<IntValue>(IterationsParameterName, "", new IntValue(100)));
+    }
+    protected override void Run(CancellationToken cancellationToken) {
+      var BestQuality = new DoubleValue(double.NaN);
+      Results.Add(new Result("Best quality", BestQuality));
+      for (int iteration = 0; iteration < Iterations; iteration++) {
+        bool[] solution = new bool[Problem.Length];
+        for (int i = 0; i < solution.Length; i++) {
+          solution[i] = random.Next(2) == 1;
+        }
+
+        var fitness = Problem.Evaluate(solution);
+
+        fitness = ImproveToLocalOptimum(Problem, solution, fitness, random);
+        if (double.IsNaN(BestQuality.Value) || Problem.IsBetter(fitness, BestQuality.Value)) {
+          BestQuality.Value = fitness;
+        }
+      }
+    }
+    // In the GECCO paper, Section 2.1
+    public static double ImproveToLocalOptimum(IBinaryVectorProblem problem, bool[] solution, double fitness, IRandom rand) {
+      var tried = new HashSet<int>();
+      do {
+        var options = Enumerable.Range(0, solution.Length).Shuffle(rand);
+        foreach (var option in options) {
+          if (tried.Contains(option)) continue;
+          solution[option] = !solution[option];
+          double newFitness = problem.Evaluate(solution);
+          if (problem.IsBetter(newFitness, fitness)) {
+            fitness = newFitness;
+            tried.Clear();
+          } else {
+            solution[option] = !solution[option];
+          }
+          tried.Add(option);
+        }
+      } while (tried.Count != solution.Length);
+      return fitness;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/LinkageCrossover.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/LinkageCrossover.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/LinkageCrossover.cs	(revision 11939)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HeuristicLab.Core;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  // This code is based off the publication
+  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
+  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
+  public static class LinkageCrossover {
+    // In the GECCO paper, Figure 3
+    public static double ImproveUsingTree(LinkageTree tree, IList<bool[]> donors, bool[] solution, double fitness, IBinaryVectorProblem problem, IRandom rand) {
+      var options = Enumerable.Range(0, donors.Count).ToArray();
+      foreach (var cluster in tree.Clusters) {
+        // Find a donor which has at least one gene value different
+        // from the current solution for this cluster of genes
+        bool donorFound = false;
+        foreach (var donorIndex in options.ShuffleList(rand)) {
+          // Attempt the donation
+          fitness = Donate(solution, fitness, donors[donorIndex], cluster, problem, out donorFound);
+          if (donorFound) break;
+        }
+      }
+      return fitness;
+    }
+
+    private static double Donate(bool[] solution, double fitness, bool[] source, IEnumerable<int> cluster, IBinaryVectorProblem problem, out bool changed) {
+      // keep track of which bits flipped to make the donation
+      List<int> flipped = new List<int>();
+      foreach (var index in cluster) {
+        if (solution[index] != source[index]) {
+          flipped.Add(index);
+          solution[index] = !solution[index];
+        }
+      }
+      changed = flipped.Count > 0;
+      if (changed) {
+        double newFitness = problem.Evaluate(solution);
+        // if the original is strictly better, revert the change
+        if (problem.IsBetter(fitness, newFitness)) {
+          foreach (var index in flipped) {
+            solution[index] = !solution[index];
+          }
+        } else {
+          // new solution is no worse than original, keep change to solution
+          fitness = newFitness;
+        }
+      }
+      return fitness;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/LinkageTree.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/LinkageTree.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/LinkageTree.cs	(revision 11939)
@@ -0,0 +1,250 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  // This code is based off the publication
+  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
+  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
+  public class LinkageTree {
+    private readonly int[][][] occurances;
+    private readonly List<int>[] clusters;
+    private List<int> clusterOrdering;
+    private readonly int length;
+    private readonly IRandom rand;
+    private bool rebuildRequired = false;
+
+    public LinkageTree(int length, IRandom rand) {
+      this.length = length;
+      this.rand = rand;
+      occurances = new int[length][][];
+
+      // Create a lower triangular matrix without the diagonal
+      for (int i = 1; i < length; i++) {
+        occurances[i] = new int[i][];
+        for (int j = 0; j < i; j++) {
+          occurances[i][j] = new int[4];
+        }
+      }
+      clusters = new List<int>[2 * length - 1];
+      for (int i = 0; i < clusters.Length; i++) {
+        clusters[i] = new List<int>();
+      }
+      clusterOrdering = new List<int>();
+
+      // first "length" clusters just contain a single gene
+      for (int i = 0; i < length; i++) {
+        clusters[i].Add(i);
+      }
+    }
+
+    public void Add(bool[] solution) {
+      if (solution.Length != length) throw new ArgumentException("The individual has not the correct length.");
+      for (int i = 1; i < solution.Length; i++) {
+        for (int j = 0; j < i; j++) {
+          // Updates the entry of the 4 long array based on the two bits
+
+          var pattern = (Convert.ToByte(solution[j]) << 1) + Convert.ToByte(solution[i]);
+          occurances[i][j][pattern]++;
+        }
+      }
+      rebuildRequired = true;
+    }
+
+    // While "total" always has an integer value, it is a double to reduce
+    // how often type casts are needed to prevent integer divison
+    // In the GECCO paper, calculates Equation 2
+    private static double NegativeEntropy(int[] counts, double total) {
+      double sum = 0;
+      for (int i = 0; i < counts.Length; i++) {
+        if (counts[i] != 0) {
+          sum += ((counts[i] / total) * Math.Log(counts[i] / total));
+        }
+      }
+      return sum;
+    }
+
+    // Uses the frequency table to calcuate the entropy distance between two indices.
+    // In the GECCO paper, calculates Equation 1
+    private int[] bits = new int[4];
+    private double EntropyDistance(int i, int j) {
+      // This ensures you are using the lower triangular part of "occurances"
+      if (i < j) {
+        int temp = i;
+        i = j;
+        j = temp;
+      }
+      var entry = occurances[i][j];
+      // extracts the occurrences of the individual bits
+      bits[0] = entry[0] + entry[2];  // i zero
+      bits[1] = entry[1] + entry[3];  // i one
+      bits[2] = entry[0] + entry[1];  // j zero
+      bits[3] = entry[2] + entry[3];  // j one
+      double total = bits[0] + bits[1];
+      // entropy of the two bits on their own
+      double separate = NegativeEntropy(bits, total);
+      // entropy of the two bits as a single unit
+      double together = NegativeEntropy(entry, total);
+      // If together there is 0 entropy, the distance is zero
+      if (together.IsAlmost(0)) {
+        return 0.0;
+      }
+      return 2 - (separate / together);
+    }
+
+
+
+    // Performs O(N^2) clustering based on the method described in:
+    // "Optimal implementations of UPGMA and other common clustering algorithms"
+    // by I. Gronau and S. Moran
+    // In the GECCO paper, Figure 2 is a simplified version of this algorithm.
+    private double[][] distances;
+    private void Rebuild() {
+      if (distances == null) {
+        distances = new double[clusters.Length * 2 - 1][];
+        for (int i = 0; i < distances.Length; i++)
+          distances[i] = new double[clusters.Length * 2 - 1];
+      }
+
+
+      // Keep track of which clusters have not been merged
+      var topLevel = new List<int>(length);
+      for (int i = 0; i < length; i++)
+        topLevel.Add(i);
+
+      bool[] useful = new bool[clusters.Length];
+      for (int i = 0; i < useful.Length; i++)
+        useful[i] = true;
+
+      // Store the distances between all clusters
+      for (int i = 1; i < length; i++) {
+        for (int j = 0; j < i; j++) {
+          distances[i][j] = EntropyDistance(clusters[i][0], clusters[j][0]);
+          // make it symmetric
+          distances[j][i] = distances[i][j];
+        }
+      }
+      // Each iteration we add some amount to the path, and remove the last
+      // two elements.  This keeps track of how much of usable is in the path.
+      int end_of_path = 0;
+
+      // build all clusters of size greater than 1
+      for (int index = length; index < clusters.Length; index++) {
+        // Shuffle everything not yet in the path
+        topLevel.ShuffleInPlace(rand, end_of_path, topLevel.Count - 1);
+
+        // if nothing in the path, just add a random usable node
+        if (end_of_path == 0) {
+          end_of_path = 1;
+        }
+        while (end_of_path < topLevel.Count) {
+          // last node in the path
+          int final = topLevel[end_of_path - 1];
+
+          // best_index stores the location of the best thing in the top level
+          int best_index = end_of_path;
+          double min_dist = distances[final][topLevel[best_index]];
+          // check all options which might be closer to "final" than "topLevel[best_index]"
+          for (int option = end_of_path + 1; option < topLevel.Count; option++) {
+            if (distances[final][topLevel[option]] < min_dist) {
+              min_dist = distances[final][topLevel[option]];
+              best_index = option;
+            }
+          }
+          // If the current last two in the path are minimally distant
+          if (end_of_path > 1 && min_dist >= distances[final][topLevel[end_of_path - 2]]) {
+            break;
+          }
+
+          // move the best to the end of the path
+          topLevel.Swap(end_of_path, best_index);
+          end_of_path++;
+        }
+        // Last two elements in the path are the clusters to join
+        int first = topLevel[end_of_path - 2];
+        int second = topLevel[end_of_path - 1];
+
+        // Only keep a cluster if the distance between the joining clusters is > zero
+        bool keep = !distances[first][second].IsAlmost(0.0);
+        useful[first] = keep;
+        useful[second] = keep;
+
+        // create the new cluster
+        clusters[index] = clusters[first].Concat(clusters[second]).ToList();
+        // Calculate distances from all clusters to the newly created cluster
+        int i = 0;
+        int end = topLevel.Count - 1;
+        while (i <= end) {
+          int x = topLevel[i];
+          // Moves 'first' and 'second' to after "end" in topLevel
+          if (x == first || x == second) {
+            topLevel.Swap(i, end);
+            end--;
+            continue;
+          }
+          // Use the previous distances to calculate the joined distance
+          double first_distance = distances[first][x];
+          first_distance *= clusters[first].Count;
+          double second_distance = distances[second][x];
+          second_distance *= clusters[second].Count;
+          distances[x][index] = ((first_distance + second_distance)
+              / (clusters[first].Count + clusters[second].Count));
+          // make it symmetric
+          distances[index][x] = distances[x][index];
+          i++;
+        }
+
+        // Remove first and second from the path
+        end_of_path -= 2;
+        topLevel.RemoveAt(topLevel.Count - 1);
+        topLevel[topLevel.Count - 1] = index;
+      }
+      // Extract the useful clusters
+      clusterOrdering.Clear();
+      // Add all useful clusters. The last one is never useful.
+      for (int i = 0; i < useful.Length - 1; i++) {
+        if (useful[i]) clusterOrdering.Add(i);
+      }
+
+      // Shuffle before sort to ensure ties are broken randomly
+      clusterOrdering.ShuffleInPlace(rand);
+      clusterOrdering = clusterOrdering.OrderBy(i => clusters[i].Count).ToList();
+    }
+
+    public IEnumerable<List<int>> Clusters {
+      get {
+        // Just in time rebuilding
+        if (rebuildRequired) Rebuild();
+        foreach (var index in clusterOrdering) {
+          // Send out the clusters in the desired order
+          yield return clusters[index];
+        }
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/ParameterlessPopulationPyramid.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/ParameterlessPopulationPyramid.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/ParameterlessPopulationPyramid.cs	(revision 11939)
@@ -0,0 +1,264 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  // This code is based off the publication
+  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
+  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
+  [Item("Parameter-less Population Pyramid", "Binary value optimization algorithm which requires no configuration.")]
+  [StorableClass]
+  [Creatable("Parameterless Population Pyramid")]
+  public class ParameterlessPopulationPyramid : BasicAlgorithm {
+    public override Type ProblemType {
+      get { return typeof(BinaryVectorProblem); }
+    }
+    public new BinaryVectorProblem Problem {
+      get { return (BinaryVectorProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    private readonly IRandom random = new MersenneTwister();
+    private List<Population> pyramid;
+    private EvaluationTracker tracker;
+
+    // Tracks all solutions in Pyramid for quick membership checks
+    private HashSet<bool[]> seen = new HashSet<bool[]>(new EnumerableBoolEqualityComparer());
+
+    #region ParameterNames
+    private const string MaximumIterationsParameterName = "Maximum Iterations";
+    private const string MaximumEvaluationsParameterName = "Maximum Evaluations";
+    private const string MaximumRuntimeParameterName = "Maximum Runtime";
+    private const string SeedParameterName = "Seed";
+    private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
+    #endregion
+
+    #region ParameterProperties
+    public IFixedValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumIterationsParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> MaximumEvaluationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumEvaluationsParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> MaximumRuntimeParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumRuntimeParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> SeedParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[SeedParameterName]; }
+    }
+    public FixedValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return (FixedValueParameter<BoolValue>)Parameters[SetSeedRandomlyParameterName]; }
+    }
+    #endregion
+
+    #region Properties
+    public int MaximumIterations {
+      get { return MaximumIterationsParameter.Value.Value; }
+      set { MaximumIterationsParameter.Value.Value = value; }
+    }
+    public int MaximumEvaluations {
+      get { return MaximumEvaluationsParameter.Value.Value; }
+      set { MaximumEvaluationsParameter.Value.Value = value; }
+    }
+    public int MaximumRuntime {
+      get { return MaximumRuntimeParameter.Value.Value; }
+      set { MaximumRuntimeParameter.Value.Value = value; }
+    }
+    public int Seed {
+      get { return SeedParameter.Value.Value; }
+      set { SeedParameter.Value.Value = value; }
+    }
+    public bool SetSeedRandomly {
+      get { return SetSeedRandomlyParameter.Value.Value; }
+      set { SetSeedRandomlyParameter.Value.Value = value; }
+    }
+    #endregion
+
+    #region ResultsProperties
+    private double ResultsBestQuality {
+      get { return ((DoubleValue)Results["Best Quality"].Value).Value; }
+      set { ((DoubleValue)Results["Best Quality"].Value).Value = value; }
+    }
+
+    private BinaryVector ResultsBestSolution {
+      get { return (BinaryVector)Results["Best Solution"].Value; }
+      set { Results["Best Solution"].Value = value; }
+    }
+
+    private int ResultsBestFoundOnEvaluation {
+      get { return ((IntValue)Results["Evaluation Best Solution Was Found"].Value).Value; }
+      set { ((IntValue)Results["Evaluation Best Solution Was Found"].Value).Value = value; }
+    }
+
+    private int ResultsEvaluations {
+      get { return ((IntValue)Results["Evaluations"].Value).Value; }
+      set { ((IntValue)Results["Evaluations"].Value).Value = value; }
+    }
+    private int ResultsIterations {
+      get { return ((IntValue)Results["Iterations"].Value).Value; }
+      set { ((IntValue)Results["Iterations"].Value).Value = value; }
+    }
+
+    private DataTable ResultsQualities {
+      get { return ((DataTable)Results["Qualities"].Value); }
+    }
+    private DataRow ResultsQualitiesBest {
+      get { return ResultsQualities.Rows["Best Quality"]; }
+    }
+
+    private DataRow ResultsQualitiesIteration {
+      get { return ResultsQualities.Rows["Iteration Quality"]; }
+    }
+
+
+    private DataRow ResultsLevels {
+      get { return ((DataTable)Results["Pyramid Levels"].Value).Rows["Levels"]; }
+    }
+
+    private DataRow ResultsSolutions {
+      get { return ((DataTable)Results["Stored Solutions"].Value).Rows["Solutions"]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ParameterlessPopulationPyramid(bool deserializing) : base(deserializing) { }
+
+    protected ParameterlessPopulationPyramid(ParameterlessPopulationPyramid original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ParameterlessPopulationPyramid(this, cloner);
+    }
+
+    public ParameterlessPopulationPyramid() {
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumIterationsParameterName, "", new IntValue(Int32.MaxValue)));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluationsParameterName, "", new IntValue(Int32.MaxValue)));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumRuntimeParameterName, "The maximum runtime in seconds after which the algorithm stops. Use -1 to specify no limit for the runtime", new IntValue(3600)));
+      Parameters.Add(new FixedValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+    }
+
+    protected override void OnExecutionTimeChanged() {
+      base.OnExecutionTimeChanged();
+      if (CancellationTokenSource == null) return;
+      if (MaximumRuntime == -1) return;
+      if (ExecutionTime.TotalSeconds > MaximumRuntime) CancellationTokenSource.Cancel();
+    }
+
+    private void AddIfUnique(bool[] solution, int level) {
+      // Don't add things you have seen
+      if (seen.Contains(solution)) return;
+      if (level == pyramid.Count) {
+        pyramid.Add(new Population(tracker.Length, random));
+      }
+      var copied = (bool[])solution.Clone();
+      pyramid[level].Add(copied);
+      seen.Add(copied);
+    }
+
+    // In the GECCO paper, Figure 1
+    private double iterate() {
+      // Create a random solution
+      bool[] solution = new bool[tracker.Length];
+      for (int i = 0; i < solution.Length; i++) {
+        solution[i] = random.Next(2) == 1;
+      }
+      double fitness = tracker.Evaluate(solution);
+      fitness = HillClimber.ImproveToLocalOptimum(tracker, solution, fitness, random);
+      AddIfUnique(solution, 0);
+
+      for (int level = 0; level < pyramid.Count; level++) {
+        var current = pyramid[level];
+        double newFitness = LinkageCrossover.ImproveUsingTree(current.Tree, current.Solutions, solution, fitness, tracker, random);
+        // add it to the next level if its a strict fitness improvement
+        if (tracker.IsBetter(newFitness, fitness)) {
+          fitness = newFitness;
+          AddIfUnique(solution, level + 1);
+        }
+      }
+      return fitness;
+    }
+
+    protected override void Run(CancellationToken cancellationToken) {
+      // Set up the algorithm
+      if (SetSeedRandomly) Seed = new System.Random().Next();
+      pyramid = new List<Population>();
+      seen.Clear();
+      random.Reset(Seed);
+      tracker = new EvaluationTracker(Problem, MaximumEvaluations);
+
+      // Set up the results display
+      Results.Add(new Result("Iterations", new IntValue(0)));
+      Results.Add(new Result("Evaluations", new IntValue(0)));
+      Results.Add(new Result("Best Solution", new BinaryVector(tracker.BestSolution)));
+      Results.Add(new Result("Best Quality", new DoubleValue(tracker.BestQuality)));
+      Results.Add(new Result("Evaluation Best Solution Was Found", new IntValue(tracker.BestFoundOnEvaluation)));
+      var table = new DataTable("Qualities");
+      table.Rows.Add(new DataRow("Best Quality"));
+      var iterationRows = new DataRow("Iteration Quality");
+      iterationRows.VisualProperties.LineStyle = DataRowVisualProperties.DataRowLineStyle.Dot;
+      table.Rows.Add(iterationRows);
+      Results.Add(new Result("Qualities", table));
+
+      table = new DataTable("Pyramid Levels");
+      table.Rows.Add(new DataRow("Levels"));
+      Results.Add(new Result("Pyramid Levels", table));
+
+      table = new DataTable("Stored Solutions");
+      table.Rows.Add(new DataRow("Solutions"));
+      Results.Add(new Result("Stored Solutions", table));
+
+      // Loop until iteration limit reached or canceled.
+      for (ResultsIterations = 0; ResultsIterations < MaximumIterations; ResultsIterations++) {
+        double fitness = double.NaN;
+
+        try {
+          fitness = iterate();
+          cancellationToken.ThrowIfCancellationRequested();
+        }
+        finally {
+          ResultsEvaluations = tracker.Evaluations;
+          ResultsBestSolution = new BinaryVector(tracker.BestSolution);
+          ResultsBestQuality = tracker.BestQuality;
+          ResultsBestFoundOnEvaluation = tracker.BestFoundOnEvaluation;
+          ResultsQualitiesBest.Values.Add(tracker.BestQuality);
+          ResultsQualitiesIteration.Values.Add(fitness);
+          ResultsLevels.Values.Add(pyramid.Count);
+          ResultsSolutions.Values.Add(seen.Count);
+        }
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Plugin.cs.frame
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Plugin.cs.frame	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Plugin.cs.frame	(revision 11939)
@@ -0,0 +1,45 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Algorithms.ParameterlessPopulationPyramid plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Algorithms.ParameterlessPopulationPyramid", "3.3.10.$WCREV$")]
+  [PluginFile("HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.BinaryVectorEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Random", "3.3")]
+  public class Plugin : PluginBase {
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Population.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Population.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Population.cs	(revision 11939)
@@ -0,0 +1,50 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  // This code is based off the publication
+  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
+  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
+  public class Population {
+    public List<bool[]> Solutions {
+      get;
+      private set;
+    }
+
+    public LinkageTree Tree {
+      get;
+      private set;
+    }
+
+    public Population(int length, IRandom rand) {
+      Solutions = new List<bool[]>();
+      Tree = new LinkageTree(length, rand);
+    }
+    public void Add(bool[] solution) {
+      Solutions.Add(solution);
+      Tree.Add(solution);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/BinaryVectorProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/BinaryVectorProblem.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/BinaryVectorProblem.cs	(revision 11939)
@@ -0,0 +1,63 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  [StorableClass]
+  public abstract class BinaryVectorProblem : Problem, IBinaryVectorProblem {
+    private const string LengthParameterName = "Length";
+
+    public IFixedValueParameter<IntValue> LengthParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[LengthParameterName]; }
+    }
+
+    public int Length {
+      get { return LengthParameter.Value.Value; }
+      set { LengthParameter.Value.Value = value; }
+    }
+
+    public abstract bool Maximization {
+      get;
+    }
+
+    [StorableConstructor]
+    protected BinaryVectorProblem(bool deserializing) : base(deserializing) { }
+    protected BinaryVectorProblem(BinaryVectorProblem original, Cloner cloner) : base(original, cloner) { }
+    public bool IsBetter(double quality, double bestQuality) {
+      return (Maximization && quality > bestQuality || !Maximization && quality < bestQuality);
+    }
+
+    public BinaryVectorProblem()
+      : base() {
+      Parameters.Add(new FixedValueParameter<IntValue>(LengthParameterName, "", new IntValue(20)));
+    }
+
+    public abstract double Evaluate(bool[] individual);
+
+
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/DeceptiveStepTrapProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/DeceptiveStepTrapProblem.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/DeceptiveStepTrapProblem.cs	(revision 11939)
@@ -0,0 +1,94 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  // This code is based off the publication
+  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
+  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
+  [Item("Deceptive Step Trap Problem", "Genome encodes completely separable blocks, where each block deceptive with fitness plateaus.")]
+  [StorableClass]
+  [Creatable("Parameterless Population Pyramid")]
+  // In the GECCO paper, Section 4.1
+  public class DeceptiveStepTrapProblem : DeceptiveTrapProblem {
+    [StorableConstructor]
+    protected DeceptiveStepTrapProblem(bool deserializing) : base(deserializing) { }
+    protected DeceptiveStepTrapProblem(DeceptiveStepTrapProblem original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterParameterEvents();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DeceptiveStepTrapProblem(this, cloner);
+    }
+
+    private const string StepSizeParameterName = "Step Size";
+
+    public IFixedValueParameter<IntValue> StepSizeParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[StepSizeParameterName]; }
+    }
+
+    public int StepSize {
+      get { return StepSizeParameter.Value.Value; }
+      set { StepSizeParameter.Value.Value = value; }
+    }
+
+    public DeceptiveStepTrapProblem()
+      : base() {
+      Parameters.Add(new FixedValueParameter<IntValue>(StepSizeParameterName, "", new IntValue(2)));
+      RegisterParameterEvents();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
+    }
+
+    private void RegisterParameterEvents() {
+      TrapSizeParameter.Value.ValueChanged += (o, e) => { offset = -1; };
+      StepSizeParameter.Value.ValueChanged += (o, e) => { offset = -1; };
+    }
+
+
+    private int offset = -1;
+    private int Offset {
+      get {
+        if (offset == -1) offset = (TrapSize - StepSize) % StepSize;
+        return offset;
+      }
+    }
+
+    protected override int TrapMaximum {
+      get { return (Offset + TrapSize) / StepSize; }
+    }
+
+    protected override int Score(bool[] individual, int trapIndex, int trapSize) {
+      int partial = base.Score(individual, trapIndex, trapSize);
+      // introduce plateaus using integer division
+      return (Offset + partial) / StepSize;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/DeceptiveTrapProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/DeceptiveTrapProblem.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/DeceptiveTrapProblem.cs	(revision 11939)
@@ -0,0 +1,97 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  // This code is based off the publication
+  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
+  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
+  [Item("Deceptive Trap Problem", "Genome encodes completely separable blocks, where each block is fully deceptive.")]
+  [StorableClass]
+  [Creatable("Parameterless Population Pyramid")]
+  public class DeceptiveTrapProblem : BinaryVectorProblem {
+    [StorableConstructor]
+    protected DeceptiveTrapProblem(bool deserializing) : base(deserializing) { }
+    protected DeceptiveTrapProblem(DeceptiveTrapProblem original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DeceptiveTrapProblem(this, cloner);
+    }
+
+    public override bool Maximization {
+      get { return true; }
+    }
+
+    private const string TrapSizeParameterName = "Trap Size";
+
+    public IFixedValueParameter<IntValue> TrapSizeParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[TrapSizeParameterName]; }
+    }
+
+    public int TrapSize {
+      get { return TrapSizeParameter.Value.Value; }
+      set { TrapSizeParameter.Value.Value = value; }
+    }
+
+    protected virtual int TrapMaximum {
+      get { return TrapSize; }
+    }
+
+    public DeceptiveTrapProblem()
+      : base() {
+      Parameters.Add(new FixedValueParameter<IntValue>(TrapSizeParameterName, "", new IntValue(7)));
+      Length = 49;
+    }
+
+    // In the GECCO paper, calculates Equation 3
+    protected virtual int Score(bool[] individual, int trapIndex, int trapSize) {
+      int result = 0;
+      // count number of bits in trap set to 1
+      for (int index = trapIndex; index < trapIndex + trapSize; index++) {
+        if (individual[index]) result++;
+      }
+
+      // Make it deceptive
+      if (result < trapSize) {
+        result = trapSize - result - 1;
+      }
+      return result;
+    }
+
+    public override double Evaluate(bool[] individual) {
+      if (individual.Length != Length) throw new ArgumentException("The individual has not the correct length.");
+      int total = 0;
+      var trapSize = TrapSize;
+      for (int i = 0; i < individual.Length; i += trapSize) {
+        total += Score(individual, i, trapSize);
+      }
+      return (double)(total * trapSize) / (TrapMaximum * individual.Length);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/EvaluationTracker.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/EvaluationTracker.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/EvaluationTracker.cs	(revision 11939)
@@ -0,0 +1,90 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  // This code is based off the publication
+  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
+  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
+  public class EvaluationTracker : IBinaryVectorProblem {
+    private readonly IBinaryVectorProblem problem;
+
+    private int maxEvaluations;
+
+    #region Properties
+    public double BestQuality {
+      get;
+      private set;
+    }
+
+    public int Evaluations {
+      get;
+      private set;
+    }
+
+    public int BestFoundOnEvaluation {
+      get;
+      private set;
+    }
+
+    public bool[] BestSolution {
+      get;
+      private set;
+    }
+    #endregion
+
+    public EvaluationTracker(IBinaryVectorProblem problem, int maxEvaluations) {
+      this.problem = problem;
+      this.maxEvaluations = maxEvaluations;
+      BestSolution = new bool[0];
+      BestQuality = double.NaN;
+      Evaluations = 0;
+      BestFoundOnEvaluation = 0;
+    }
+
+    public double Evaluate(bool[] individual) {
+      if (Evaluations >= maxEvaluations) throw new OperationCanceledException("Maximum Evaluation Limit Reached");
+      Evaluations++;
+      double fitness = problem.Evaluate(individual);
+      if (double.IsNaN(BestQuality) || problem.IsBetter(fitness, BestQuality)) {
+        BestQuality = fitness;
+        BestSolution = (bool[])individual.Clone();
+        BestFoundOnEvaluation = Evaluations;
+      }
+      return fitness;
+    }
+
+    #region ForwardedInteraface
+    public int Length {
+      get { return problem.Length; }
+    }
+    public bool Maximization {
+      get { return problem.Maximization; }
+    }
+    public bool IsBetter(double quality, double bestQuality) {
+      return problem.IsBetter(quality, bestQuality);
+    }
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/HIFFProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/HIFFProblem.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/HIFFProblem.cs	(revision 11939)
@@ -0,0 +1,92 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  // This code is based off the publication
+  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
+  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
+  [Item("Hierararchical If and only If problem", "Genome evaluated in nested subsets to see if each subset contains either all 0s or all 1s.")]
+  [StorableClass]
+  [Creatable("Parameterless Population Pyramid")]
+  public class HIFFProblem : BinaryVectorProblem {
+    [StorableConstructor]
+    protected HIFFProblem(bool deserializing) : base(deserializing) { }
+    protected HIFFProblem(HIFFProblem original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HIFFProblem(this, cloner);
+    }
+
+    public override bool Maximization {
+      get { return true; }
+    }
+
+    public HIFFProblem() : base() {
+      Length = 64;
+    }
+    // In the GECCO paper, Section 4.1
+    public override double Evaluate(bool[] individual) {
+      int[] level = new int[individual.Length];
+      int levelLength = individual.Length;
+
+      // Initialize the level to the current solution
+      for (int i = 0; i < levelLength; i++) {
+        level[i] = Convert.ToInt32(individual[i]);
+      }
+      int power = 1;
+      int nextLength = levelLength / 2;
+      int total = 0;
+      int maximum = 0;
+
+      // Keep going while the next level actual has bits in it
+      while (nextLength > 0) {
+        int[] nextLevel = new int[nextLength];
+        // Construct the next level using the current level
+        for (int i = 0; i + 1 < levelLength; i += 2) {
+          if (level[i] == level[i + 1] && level[i] != -1) {
+            // Score points for a correct setting at this level
+            total += power;
+            nextLevel[i / 2] = level[i];
+          } else {
+            nextLevel[i / 2] = -1;
+          }
+          // Keep track of the maximum possible score
+          maximum += power;
+        }
+        level = nextLevel;
+        levelLength = nextLength;
+        nextLength = levelLength / 2;
+        power *= 2;
+      }
+
+      // Convert to percentage of total
+      return (double)total / maximum;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/IBinaryVectorProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/IBinaryVectorProblem.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/IBinaryVectorProblem.cs	(revision 11939)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
+  public interface IBinaryVectorProblem {
+    int Length { get; }
+    bool Maximization { get; }
+    bool IsBetter(double quality, double bestQuality);
+    double Evaluate(bool[] individual);
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/OneMaxProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/OneMaxProblem.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Problems/OneMaxProblem.cs	(revision 11939)
@@ -0,0 +1,54 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid.Problems {
+  // This code is based off the publication
+  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
+  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
+  [Item("Test One Max Problem", "Only a test class. Should be removed in the future.")]
+  [StorableClass]
+  [Creatable("Parameterless Population Pyramid")]
+  public class OneMaxProblem : BinaryVectorProblem {
+    [StorableConstructor]
+    protected OneMaxProblem(bool deserializing) : base(deserializing) { }
+    protected OneMaxProblem(OneMaxProblem original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new OneMaxProblem(this, cloner); }
+
+    public override bool Maximization {
+      get { return true; }
+    }
+    public OneMaxProblem() : base() { }
+
+    public override double Evaluate(bool[] individual) {
+      if (individual.Length != Length) throw new ArgumentException("The individual has not the correct length.");
+      double quality = 0;
+      for (int i = 0; i < individual.Length; i++)
+        if (individual[i]) quality++;
+      return quality;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Properties/AssemblyInfo.cs.frame	(revision 11939)
+++ trunk/sources/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/Properties/AssemblyInfo.cs.frame	(revision 11939)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Core")]
+[assembly: AssemblyDescription("HeuristicLab core classes")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2014 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7d0840b8-3382-4b99-ab4e-5d1eb91fbec1")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.10.$WCREV$")]
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/EmptySymbolicExpressionTreeGrammar.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/EmptySymbolicExpressionTreeGrammar.cs	(revision 11938)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/EmptySymbolicExpressionTreeGrammar.cs	(revision 11939)
@@ -136,7 +136,7 @@
     }
     
-    #pragma warning disable 0169 //disable usage warning
+    #pragma warning disable 0067 //disable usage warning
     public event EventHandler Changed;
-    #pragma warning restore 0169
+    #pragma warning restore 0067
     #endregion
   }
Index: trunk/sources/HeuristicLab.Random/3.3/HeuristicLab.Random-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Random/3.3/HeuristicLab.Random-3.3.csproj	(revision 11938)
+++ trunk/sources/HeuristicLab.Random/3.3/HeuristicLab.Random-3.3.csproj	(revision 11939)
@@ -118,4 +118,5 @@
   <ItemGroup>
     <None Include="Plugin.cs.frame" />
+    <Compile Include="ListExtensions.cs" />
     <Compile Include="UniformDistributedRandom.cs" />
     <Compile Include="FastRandom.cs" />
Index: trunk/sources/HeuristicLab.Random/3.3/ListExtensions.cs
===================================================================
--- trunk/sources/HeuristicLab.Random/3.3/ListExtensions.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Random/3.3/ListExtensions.cs	(revision 11939)
@@ -0,0 +1,60 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Random {
+  public static class ListExtensions {
+    public static IList<T> Swap<T>(this IList<T> list, int indexA, int indexB) {
+      T tmp = list[indexA];
+      list[indexA] = list[indexB];
+      list[indexB] = tmp;
+      return list;
+    }
+
+    public static IList<T> ShuffleInPlace<T>(this IList<T> list, IRandom random) {
+      return list.ShuffleInPlace(random, 0, list.Count - 1);
+    }
+    public static IList<T> ShuffleInPlace<T>(this IList<T> list, IRandom random, int maxIndex) {
+      return list.ShuffleInPlace(random, 0, maxIndex);
+    }
+    public static IList<T> ShuffleInPlace<T>(this IList<T> list, IRandom random, int minIndex, int maxIndex) {
+      for (int i = maxIndex; i > minIndex; i--) {
+        int swapIndex = random.Next(minIndex, i + 1);
+        list.Swap(i, swapIndex);
+      }
+      return list;
+    }
+
+    public static IEnumerable<T> ShuffleList<T>(this IList<T> source, IRandom random) {
+      for (int i = source.Count - 1; i > 0; i--) {
+        // Swap element "i" with a random earlier element (including itself)
+        int swapIndex = random.Next(i + 1);
+        source.Swap(i, swapIndex);
+        yield return source[i];
+      }
+      yield return source[0];
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3/EnumerableBoolEqualityComparerTest.cs
===================================================================
--- trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3/EnumerableBoolEqualityComparerTest.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3/EnumerableBoolEqualityComparerTest.cs	(revision 11939)
@@ -0,0 +1,141 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Algorithms.ParameterlessPopulationPyramid;
+using HeuristicLab.Random;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace ParameterlessPopulationPyramid.Test {
+  [TestClass]
+  public class EnumerableBoolEqualityComparerTest {
+    private static EnumerableBoolEqualityComparer compare = new EnumerableBoolEqualityComparer();
+    MersenneTwister rand = new MersenneTwister();
+
+    private void randFill(IList<bool> data, MersenneTwister rand) {
+      for (int i = 0; i < data.Count; i++) {
+        data[i] = rand.Next(2) == 1;
+      }
+    }
+    [TestMethod]
+    [TestProperty("Time", "short")]
+    [TestCategory("Algorithms.ParameterlessPopulationPyramid")]
+    public void EnumerableBoolEqualsTest() {
+      bool[] array = new bool[10];
+      // Referencially equal
+      randFill(array, rand);
+      Assert.IsTrue(compare.Equals(array, array));
+
+      // Clones equal
+      var another = (bool[])array.Clone();
+      Assert.IsTrue(compare.Equals(array, another));
+
+      // Flipping a bit makes unequal
+      int flip = rand.Next(array.Length - 1);
+      another[flip] = !another[flip];
+      Assert.IsFalse(compare.Equals(array, another));
+
+      // Equality doesn't depend on container
+      List<bool> list = new List<bool>(array);
+      Assert.IsTrue(compare.Equals(list, array));
+      Assert.IsFalse(compare.Equals(list, another));
+    }
+
+    [TestMethod]
+    [TestProperty("Time", "short")]
+    [TestCategory("Algorithms.ParameterlessPopulationPyramid")]
+    public void EnumerableBoolHashCollisionTest() {
+      int collisions = 0;
+
+      bool[] array = new bool[100];
+      randFill(array, rand);
+      int original = compare.GetHashCode(array);
+
+      bool[] another = (bool[])array.Clone();
+      // Perform random walk around string checking for hash collisions
+      for (int i = 0; i < array.Length * array.Length; i++) {
+        int flip = rand.Next(array.Length - 1);
+        another[flip] = !another[flip];
+        int hash = compare.GetHashCode(another);
+        if (hash == original) {
+          // unequal sequences with same hash value
+          if (!array.SequenceEqual(another)) collisions++;
+        } else {
+          // unequal hash should mean unequal sequence
+          Assert.IsFalse(array.SequenceEqual(another));
+        }
+        // Keep the walk from getting too far afield
+        if (i % array.Length == 0) {
+          another = (bool[])array.Clone();
+        }
+      }
+      // A very lose upper bound, this only fails if you get more than sqrt(N) collisions per attempt 
+      Assert.IsTrue(collisions < array.Length);
+    }
+
+    [TestMethod]
+    [TestProperty("Time", "short")]
+    [TestCategory("Algorithms.ParameterlessPopulationPyramid")]
+    public void EnumerableBoolHashSetTest() {
+      HashSet<bool[]> set = new HashSet<bool[]>(compare);
+      bool[] array = new bool[40];
+      randFill(array, rand);
+      set.Add(array);
+
+      // Same object not added
+      set.Add(array);
+      Assert.AreEqual(1, set.Count);
+
+      // Copy of object not allowed
+      var another = (bool[])array.Clone();
+      set.Add(another);
+      Assert.AreEqual(1, set.Count);
+
+      // Flipping a bit makes unequal
+      int flip = rand.Next(array.Length - 1);
+      another[flip] = !another[flip];
+      set.Add(another);
+      Assert.AreEqual(2, set.Count);
+
+      // Add random solutions which are 1 bit different from array to the set
+      set.Clear();
+      List<bool[]> added = new List<bool[]>();
+      for (int i = 0; i < array.Length * 10; i++) {
+        // flip a bit at random
+        another = (bool[])array.Clone();
+        flip = rand.Next(array.Length - 1);
+        another[flip] = !another[flip];
+        bool unique = set.Add(another);
+        bool actuallyUnique = true;
+        foreach (var previous in added) {
+          if (previous.SequenceEqual(another)) {
+            actuallyUnique = false;
+          }
+        }
+        Assert.AreEqual(actuallyUnique, unique);
+        if (actuallyUnique) {
+          added.Add(another);
+        }
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3/LinkageTreeTest.cs
===================================================================
--- trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3/LinkageTreeTest.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3/LinkageTreeTest.cs	(revision 11939)
@@ -0,0 +1,109 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Algorithms.ParameterlessPopulationPyramid;
+using HeuristicLab.Random;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace ParameterlessPopulationPyramid.Test {
+  [TestClass]
+  public class LinkageTreeTest {
+    private static int Length = 9;
+    private static bool[][] solutions = new bool[][] {
+    new bool[] { true, true, false, false, false, false, false, false, false }, // 110000000
+    new bool[] { false, false, true, true, false, false, false, false, false }, // 001100000
+    new bool[] { false, false, false, false, true, true, false, false, false }, // 000011000
+    new bool[] { false, false, false, false, false, false, true, true, true },  // 000000111
+    new bool[] { true, true, true, true, false, false, false, false, false },   // 111100000
+    new bool[] { true, true, true, true, true, true, true, true, true },        // 111111111
+    };
+
+    // These are the clusters that should be built using "solutions" and the seed 123
+    private static int[][] correctClusters = new int[][] {
+      new int[] { 4, 5 },
+      new int[] { 2, 3 },
+      new int[] { 0, 1 },
+      new int[] { 6, 7, 8 },
+      new int[] { 0, 1, 2, 3},
+      new int[] { 4, 5, 6, 7, 8},
+    };
+
+    [TestMethod]
+    [TestProperty("Time", "short")]
+    [TestCategory("Algorithms.ParameterlessPopulationPyramid")]
+    public void LinkageTreeTestAdd() {
+      MersenneTwister rand = new MersenneTwister();
+      LinkageTree tree = new LinkageTree(Length, rand);
+      tree.Add(solutions[0]);
+      tree.Add(solutions[1]);
+      PrivateObject hidden = new PrivateObject(tree);
+      int[][][] result = (int[][][])hidden.GetField("occurances");
+      Assert.AreEqual(1, result[1][0][0]); // Positions 0 and 1 had value 00 exactly once
+      Assert.AreEqual(2, result[Length - 1][Length - 2][0]); // Positions 0 and 1 had value 00 exactly once
+      Assert.AreEqual(0, result[Length - 1][Length - 2][1]); // Positions 7 and 8 never had value 10
+      Assert.AreEqual(1, result[1][0][3]); // Positions 0 and 1 had value 11 exactly once
+    }
+
+    [TestMethod]
+    [TestProperty("Time", "short")]
+    [TestCategory("Algorithms.ParameterlessPopulationPyramid")]
+    public void LinkageTreeTestEntropyDistance() {
+      MersenneTwister rand = new MersenneTwister();
+      LinkageTree tree = new LinkageTree(Length, rand);
+      PrivateObject hidden = new PrivateObject(tree);
+      // No information should result in a distance of 0
+      Assert.AreEqual((double)0, hidden.Invoke("EntropyDistance", new object[] { 0, 1 }));
+      foreach (var solution in solutions) {
+        tree.Add(solution);
+      }
+      // Check that 0 and 1 are closer than 0 and 2
+      var linked = (double)hidden.Invoke("EntropyDistance", new object[] { 0, 1 });
+      var unlinked = (double)hidden.Invoke("EntropyDistance", new object[] { 0, 2 });
+      Assert.IsTrue(linked < unlinked);
+
+      // Reversing the arguments should not change the result
+      var forward = hidden.Invoke("EntropyDistance", new object[] { Length - 1, Length - 2 });
+      var backward = hidden.Invoke("EntropyDistance", new object[] { Length - 2, Length - 1 });
+      Assert.AreEqual(forward, backward);
+    }
+
+    [TestMethod]
+    [TestProperty("Time", "short")]
+    [TestCategory("Algorithms.ParameterlessPopulationPyramid")]
+    public void LinkageTreeTestRebuild() {
+      // The seed matters as equal sized clusters can appear in any order
+      MersenneTwister rand = new MersenneTwister(123);
+      LinkageTree tree = new LinkageTree(Length, rand);
+      foreach (var solution in solutions) {
+        tree.Add(solution);
+      }
+
+      // Check if the clusters created contain the expected variables.
+      var found = tree.Clusters.ToArray();
+      Assert.AreEqual(correctClusters.Length, found.Length);
+      for (int i = 0; i < found.Length; i++) {
+        found[i].Sort();
+        Assert.IsTrue(found[i].SequenceEqual(correctClusters[i]), string.Format("Failed On Cluster {0}", i));
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3/ParameterlessPopulationPyramidTest.cs
===================================================================
--- trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3/ParameterlessPopulationPyramidTest.cs	(revision 11939)
+++ trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3/ParameterlessPopulationPyramidTest.cs	(revision 11939)
@@ -0,0 +1,99 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using HeuristicLab.Algorithms.ParameterlessPopulationPyramid;
+using HeuristicLab.Common;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace ParameterlessPopulationPyramid.Test {
+  [TestClass]
+  public class ParameterlessPopulationPyramidTest {
+
+    // Utility function that sets up and executes the run, then asserts the results
+    private PrivateObject DoRun(BinaryVectorProblem problem, int maximumEvaluations, int seed, double bestQuality, int foundOn) {
+      var solver = new HeuristicLab.Algorithms.ParameterlessPopulationPyramid.ParameterlessPopulationPyramid();
+      solver.Problem = problem;
+      solver.MaximumEvaluations = maximumEvaluations;
+      solver.Seed = seed;
+      solver.SetSeedRandomly = false;
+      PrivateObject hidden = new PrivateObject(solver);
+      try {
+        hidden.Invoke("Run", new CancellationToken());
+      }
+      catch (OperationCanceledException) {
+        // Ignore
+      }
+
+      Assert.AreEqual(maximumEvaluations, hidden.GetProperty("ResultsEvaluations"), "Total Evaluations");
+      double foundQuality = (double)hidden.GetProperty("ResultsBestQuality");
+      Assert.IsTrue(foundQuality.IsAlmost(bestQuality), string.Format("Expected <{0}> Actual <{1}>", bestQuality, foundQuality));
+      Assert.AreEqual(foundOn, hidden.GetProperty("ResultsBestFoundOnEvaluation"), "Found On");
+
+      return hidden;
+    }
+
+    [TestMethod]
+    [TestProperty("Time", "medium")]
+    [TestCategory("Algorithms.ParameterlessPopulationPyramid")]
+    public void P3DeceptiveTrap() {
+      var problem = new DeceptiveTrapProblem();
+      problem.Length = 49;
+      problem.TrapSize = 7;
+      DoRun(problem, 100, 123, 0.857142857142857, 50);
+      DoRun(problem, 9876, 123, 0.918367346938776, 981);
+      DoRun(problem, 20000, 987, 1, 19977);
+      problem.Length = 700;
+      DoRun(problem, 100000, 987, 0.941428571428571, 96901);
+    }
+
+    // Unlike DeceptiveTrap, DeceptiveStepTrap likely contains neutral (fitness equal) modifications.
+    [TestMethod]
+    [TestProperty("Time", "medium")]
+    [TestCategory("Algorithms.ParameterlessPopulationPyramid")]
+    public void P3DeceptiveStepTrap() {
+      var problem = new DeceptiveStepTrapProblem();
+      problem.Length = 49;
+      problem.TrapSize = 7;
+      problem.StepSize = 2;
+      DoRun(problem, 100, 123, 0.5, 6);
+      DoRun(problem, 9876, 123, 0.785714285714286, 3489);
+      DoRun(problem, 70000, 987, 1, 68292);
+      problem.Length = 700;
+      DoRun(problem, 100000, 987, 0.76, 58711);
+    }
+
+    // Unlike the Trap tests, HIFF uses higher order linkage learning.
+    [TestMethod]
+    [TestProperty("Time", "medium")]
+    [TestCategory("Algorithms.ParameterlessPopulationPyramid")]
+    public void P3HIFF() {
+      var problem = new HIFFProblem();
+      problem.Length = 32;
+      DoRun(problem, 50, 12345, 0.375, 26);
+      DoRun(problem, 1000, 12345, 1, 976);
+      problem.Length = 512;
+      DoRun(problem, 1000, 54321, 0.17361111111111, 440);
+      DoRun(problem, 130000, 54321, 1, 126082);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Tests/HeuristicLab.Tests.csproj
===================================================================
--- trunk/sources/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 11938)
+++ trunk/sources/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 11939)
@@ -131,4 +131,9 @@
     <Reference Include="HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm-3.3">
       <HintPath>..\bin\HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\bin\HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3.dll</HintPath>
       <Private>False</Private>
     </Reference>
@@ -411,4 +416,7 @@
     <Compile Include="HeuristicLab.Algorithms.DataAnalysis-3.4\GaussianProcessFunctionsTest.cs" />
     <Compile Include="HeuristicLab.Algorithms.DataAnalysis-3.4\GaussianProcessRegressionTest.cs" />
+    <Compile Include="HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3\EnumerableBoolEqualityComparerTest.cs" />
+    <Compile Include="HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3\LinkageTreeTest.cs" />
+    <Compile Include="HeuristicLab.Algorithms.ParameterlessPopulationPyramid-3.3\ParameterlessPopulationPyramidTest.cs" />
     <Compile Include="HeuristicLab.Analysis-3.3\BonferroniHolmUnitTests.cs" />
     <Compile Include="HeuristicLab.Analysis-3.3\ConfidenceIntervalsTests.cs" />
