Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs	(revision 15149)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs	(revision 15150)
@@ -33,4 +33,5 @@
 using HeuristicLab.Problems.DataAnalysis;
 using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Random;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
@@ -39,4 +40,7 @@
   [StorableClass]
   public sealed class CrossValidation : ParameterizedNamedItem, IAlgorithm, IStorableContent {
+    [Storable]
+    private int seed;
+
     public CrossValidation()
       : base() {
@@ -56,4 +60,5 @@
       samplesStart = new IntValue(0);
       samplesEnd = new IntValue(0);
+      shuffleSamples = new BoolValue(false);
       storeAlgorithmInEachRun = false;
 
@@ -71,4 +76,9 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (shuffleSamples == null) shuffleSamples = new BoolValue(false);
+      #endregion
+
       RegisterEvents();
       if (Algorithm != null) RegisterAlgorithmEvents();
@@ -89,4 +99,7 @@
       samplesStart = cloner.Clone(original.samplesStart);
       samplesEnd = cloner.Clone(original.samplesEnd);
+      shuffleSamples = cloner.Clone(original.shuffleSamples);
+      seed = original.seed;
+
       RegisterEvents();
       if (Algorithm != null) RegisterAlgorithmEvents();
@@ -170,5 +183,9 @@
       get { return results; }
     }
-
+    [Storable]
+    private BoolValue shuffleSamples;
+    public BoolValue ShuffleSamples {
+      get { return shuffleSamples; }
+    }
     [Storable]
     private IntValue folds;
@@ -270,11 +287,21 @@
         throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
 
+      seed = new FastRandom().NextInt();
+
       if (Algorithm != null) {
         //create cloned algorithms
         if (clonedAlgorithms.Count == 0) {
           int testSamplesCount = (SamplesEnd.Value - SamplesStart.Value) / Folds.Value;
-
+          IDataset shuffledDataset = null;
           for (int i = 0; i < Folds.Value; i++) {
-            IAlgorithm clonedAlgorithm = (IAlgorithm)algorithm.Clone();
+            var cloner = new Cloner();
+            if (ShuffleSamples.Value) {
+              var random = new FastRandom(seed);
+              var dataAnalysisProblem = (IDataAnalysisProblem)algorithm.Problem;
+              var dataset = (Dataset)dataAnalysisProblem.ProblemData.Dataset;
+              shuffledDataset = shuffledDataset ?? dataset.Shuffle(random);
+              cloner.RegisterClonedObject(dataset, shuffledDataset);
+            }
+            IAlgorithm clonedAlgorithm = cloner.Clone(Algorithm);
             clonedAlgorithm.Name = algorithm.Name + " Fold " + i;
             IDataAnalysisProblem problem = clonedAlgorithm.Problem as IDataAnalysisProblem;
@@ -422,4 +449,10 @@
         // clone manually to correctly clone references between cloned root objects 
         Cloner cloner = new Cloner();
+        if (ShuffleSamples.Value) {
+          var dataset = (Dataset)Problem.ProblemData.Dataset;
+          var random = new FastRandom(seed);
+          var shuffledDataset = dataset.Shuffle(random);
+          cloner.RegisterClonedObject(dataset, shuffledDataset);
+        }
         var problemDataClone = (IRegressionProblemData)cloner.Clone(Problem.ProblemData);
         // set partitions of problem data clone correctly
@@ -453,6 +486,10 @@
         // at least one algorithm (GBT with logistic regression loss) produces a classification solution even though the original problem is a regression problem.
         var targetVariable = solutions.Value.First().ProblemData.TargetVariable;
-        var problemDataClone = new ClassificationProblemData(Problem.ProblemData.Dataset,
-          Problem.ProblemData.AllowedInputVariables, targetVariable);
+        var dataset = (Dataset)Problem.ProblemData.Dataset;
+        if (ShuffleSamples.Value) {
+          var random = new FastRandom(seed);
+          dataset = dataset.Shuffle(random);
+        }
+        var problemDataClone = new ClassificationProblemData(dataset, Problem.ProblemData.AllowedInputVariables, targetVariable);
         // set partitions of problem data clone correctly
         problemDataClone.TrainingPartition.Start = SamplesStart.Value; problemDataClone.TrainingPartition.End = SamplesEnd.Value;
@@ -537,10 +574,14 @@
       algorithm.ProblemChanged += new EventHandler(Algorithm_ProblemChanged);
       algorithm.ExecutionStateChanged += new EventHandler(Algorithm_ExecutionStateChanged);
-      if (Problem != null) Problem.Reset += new EventHandler(Problem_Reset);
+      if (Problem != null) {
+        Problem.Reset += new EventHandler(Problem_Reset);
+      }
     }
     private void DeregisterAlgorithmEvents() {
       algorithm.ProblemChanged -= new EventHandler(Algorithm_ProblemChanged);
       algorithm.ExecutionStateChanged -= new EventHandler(Algorithm_ExecutionStateChanged);
-      if (Problem != null) Problem.Reset -= new EventHandler(Problem_Reset);
+      if (Problem != null) {
+        Problem.Reset -= new EventHandler(Problem_Reset);
+      }
     }
     private void Algorithm_ProblemChanged(object sender, EventArgs e) {
@@ -560,9 +601,7 @@
       ConfigureProblem();
     }
-
     private void Problem_Reset(object sender, EventArgs e) {
       ConfigureProblem();
     }
-
     private void ConfigureProblem() {
       SamplesStart.Value = 0;
@@ -590,9 +629,11 @@
     private void Algorithm_ExecutionStateChanged(object sender, EventArgs e) {
       switch (Algorithm.ExecutionState) {
-        case ExecutionState.Prepared: OnPrepared();
+        case ExecutionState.Prepared:
+          OnPrepared();
           break;
         case ExecutionState.Started: throw new InvalidOperationException("Algorithm template can not be started.");
         case ExecutionState.Paused: throw new InvalidOperationException("Algorithm template can not be paused.");
-        case ExecutionState.Stopped: OnStopped();
+        case ExecutionState.Stopped:
+          OnStopped();
           break;
       }
@@ -724,4 +765,5 @@
       AggregateResultValues(collectedResults);
       results.AddRange(collectedResults.Select(x => new Result(x.Key, x.Value)).Cast<IResult>().ToArray());
+      clonedAlgorithms.Clear();
       runsCounter++;
       runs.Add(new Run(string.Format("{0} Run {1}", Name, runsCounter), this));
