Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 18192)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 18193)
@@ -465,9 +465,4 @@
     </ProjectReference>
   </ItemGroup>
-  <ItemGroup>
-    <PackageReference Include="OneOf">
-      <Version>3.0.205</Version>
-    </PackageReference>
-  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Mutators/SegmentOptimization/SamplingSegmentOptimizationManipulator.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Mutators/SegmentOptimization/SamplingSegmentOptimizationManipulator.cs	(revision 18192)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Mutators/SegmentOptimization/SamplingSegmentOptimizationManipulator.cs	(revision 18193)
@@ -36,14 +36,17 @@
   public class SamplingSegmentOptimizationManipulator : SegmentOptimizationMutator {
 
+    [StorableType("65B2E870-7EED-4DD0-918E-94A346671784")]
     protected enum DimensionType {
       All,
       Single
     }
+    [StorableType("C73064F2-4E2F-473F-8DBA-DD47881726D4")]
     protected enum SearchRangeType {
+      None, // Fixed on current value
       Full,
-      None,
-      Left,
-      Right
+      RandomDirection,
+      RandomRange
     }
+    [StorableType("A9EBE01E-53DE-4EB7-94B3-26C624034A08")]
     protected enum SamplingType {
       Exhaustive,
@@ -52,8 +55,18 @@
     }
 
+    [StorableType("4EBF0DFE-90A1-4DFE-8CC7-D358EF8AF96B")]
+    [Flags]
+    protected enum SamplingPointsType {
+      None = 0,
+      BeforeCombinations = 1,
+      AfterCombinations = 2
+    }
+
     protected ValueParameter<EnumValue<DimensionType>> Dimension => (ValueParameter<EnumValue<DimensionType>>)Parameters["Dimension"];
     protected ValueParameter<EnumValue<SearchRangeType>> SearchRange => (ValueParameter<EnumValue<SearchRangeType>>)Parameters["SearchRange"];
     protected ValueParameter<EnumValue<SamplingType>> Sampling => (ValueParameter<EnumValue<SamplingType>>)Parameters["Sampling"];
     protected ValueParameter<IntValue> SampleCount => (ValueParameter<IntValue>)Parameters["SampleCount"];
+    protected ValueParameter<EnumValue<SamplingPointsType>> SamplingPoints => (ValueParameter<EnumValue<SamplingPointsType>>)Parameters["SamplingPoints"];
+    
 
     public SamplingSegmentOptimizationManipulator() {
@@ -62,4 +75,5 @@
       Parameters.Add(new ValueParameter<EnumValue<SamplingType>>("Sampling", new EnumValue<SamplingType>(SamplingType.Exhaustive)));
       Parameters.Add(new ValueParameter<IntValue>("SampleCount")); // only used when sampling != Exhaustive
+      Parameters.Add(new ValueParameter<EnumValue<SamplingPointsType>>("SamplingPoints", new EnumValue<SamplingPointsType>(SamplingPointsType.BeforeCombinations | SamplingPointsType.AfterCombinations))); 
     }
     public SamplingSegmentOptimizationManipulator(SamplingSegmentOptimizationManipulator original, Cloner cloner)
@@ -73,8 +87,17 @@
     protected override void ManipulateBounded(IRandom random, IntegerVector integerVector, IntMatrix bounds) {
       var indices = CreateIndices(random, integerVector, bounds, Dimension.Value.Value, SearchRange.Value.Value);
-      var solutions = CreateCombinations(indices);
-      solutions = SampleIndices(solutions, Sampling.Value.Value, random, SampleCount.Value.Value);
+
+      if (SamplingPoints.Value.Value.HasFlag(SamplingPointsType.BeforeCombinations))
+        indices = indices.Select(i => SampleIndices(i, Sampling.Value.Value, random, SampleCount.Value.Value).ToList()).ToArray();
+
+      var solutions = CreateCombinations(indices[0], indices[1]);
+
+      if (SamplingPoints.Value.Value.HasFlag(SamplingPointsType.AfterCombinations))
+        solutions = SampleIndices(solutions, Sampling.Value.Value, random, SampleCount.Value.Value);
+
       var best = FindBest(solutions);
-      CopyTo(best.Item1, integerVector);
+      if (best != null) {
+        CopyTo(best.Item1, integerVector);
+      }
     }
     
@@ -84,10 +107,14 @@
       for (int i = 0; i < indices.Length; i++) {
         var searchRange = dimension == DimensionType.All || targetIndex == i ? indexRange : SearchRangeType.None;
-        indices[i] = CreateSingleIndices(bounds[i % bounds.Rows, 1], integerVector[i], searchRange);
+        indices[i] = CreateSingleIndices(bounds[i % bounds.Rows, 1], integerVector[i], searchRange, random).ToList();
+        if (!indices[i].Any()) {
+          throw new InvalidOperationException("no indices!");
+          //indices[i] = new[] { integerVector[i] };
+        }
       }
       return indices;
     }
 
-    protected static IEnumerable<int> CreateSingleIndices(int length, int currentIndex, SearchRangeType searchRange) {
+    protected static IEnumerable<int> CreateSingleIndices(int length, int currentIndex, SearchRangeType searchRange, IRandom random) {
       switch (searchRange) {
         case SearchRangeType.Full:
@@ -95,8 +122,9 @@
         case SearchRangeType.None:
           return new[] { currentIndex };
-        case SearchRangeType.Left:
-          return Enumerable.Range(0, currentIndex);
-        case SearchRangeType.Right:
-          return Enumerable.Range(currentIndex, length - currentIndex);
+        case SearchRangeType.RandomDirection:
+          return random.Next(2) == 0 ? Enumerable.Range(0, currentIndex) : Enumerable.Range(currentIndex, length - currentIndex);
+        case SearchRangeType.RandomRange:
+          int start = random.Next(0, length - 1), end = random.Next(start + 1, length);
+          return Enumerable.Range(start, end - start);
         default:
           throw new ArgumentOutOfRangeException(nameof(searchRange), searchRange, null);
@@ -105,8 +133,9 @@
 
     protected static IEnumerable<IntegerVector> CreateCombinations(IEnumerable<int> startIndices, IEnumerable<int> endIndices) {
-      return CreateCombinations(new[] { startIndices, endIndices });
-    }
-    protected static IEnumerable<IntegerVector> CreateCombinations(IEnumerable<IEnumerable<int>> indices) {
-      return indices.CartesianProduct().Select(seq => new IntegerVector(seq.ToArray()));
+      return 
+        from s in startIndices
+        from e in endIndices
+        where s < e
+        select new IntegerVector(new [] { s, e });
     }
 
@@ -116,5 +145,5 @@
           return indices;
         case SamplingType.RandomSampling:
-          return indices.SampleRandom(random, count);
+          return indices.SampleRandomWithoutRepetition(random, count);
         case SamplingType.LinearSelection:
           var indicesList = indices.ToList();
@@ -130,5 +159,5 @@
     protected Tuple<IntegerVector, double> FindBest(IEnumerable<IntegerVector> solutions) {
       var evaluatedSolutions = solutions.Select(s => Tuple.Create(s, Evaluate(s)));
-      var best = evaluatedSolutions.OrderBy(t => t.Item2).First();
+      var best = evaluatedSolutions.OrderBy(t => t.Item2).FirstOrDefault();
       return best;
     }
