Index: branches/2825-NSGA3/HeuristicLab.Algorithms.NSGA3/3.3/NSGA3.cs
===================================================================
--- branches/2825-NSGA3/HeuristicLab.Algorithms.NSGA3/3.3/NSGA3.cs	(revision 17700)
+++ branches/2825-NSGA3/HeuristicLab.Algorithms.NSGA3/3.3/NSGA3.cs	(revision 17701)
@@ -83,4 +83,7 @@
         private const string GenerationalDistanceResultName = "Generational Distance";
         private const string InvertedGenerationalDistanceResultName = "Inverted Generational Distance";
+        private const string HypervolumeResultName = "Hypervolume";
+        private const string BestKnownHypervolumeResultName = "Best known hypervolume";
+        private const string DifferenceToBestKnownHypervolumeResultName = "Absolute Distance to BestKnownHypervolume";
         private const string ScatterPlotResultName = "Scatter Plot";
         private const string CurrentFrontResultName = "Pareto Front"; // Do not touch this
@@ -171,4 +174,22 @@
             get { return (DoubleValue)Results[InvertedGenerationalDistanceResultName].Value; }
             set { Results[InvertedGenerationalDistanceResultName].Value = value; }
+        }
+
+        public DoubleValue ResultsHypervolume
+        {
+            get { return (DoubleValue)Results[HypervolumeResultName].Value; }
+            set { Results[HypervolumeResultName].Value = value; }
+        }
+
+        public DoubleValue ResultsBestKnownHypervolume
+        {
+            get { return (DoubleValue)Results[BestKnownHypervolumeResultName].Value; }
+            set { Results[BestKnownHypervolumeResultName].Value = value; }
+        }
+
+        public DoubleValue ResultsDifferenceToBestKnownHypervolume
+        {
+            get { return (DoubleValue)Results[DifferenceToBestKnownHypervolumeResultName].Value; }
+            set { Results[DifferenceToBestKnownHypervolumeResultName].Value = value; }
         }
 
@@ -250,4 +271,7 @@
             Results.Add(new Result(GenerationalDistanceResultName, "The generational distance to an optimal pareto front defined in the Problem", new DoubleValue(double.NaN)));
             Results.Add(new Result(InvertedGenerationalDistanceResultName, "The inverted generational distance to an optimal pareto front defined in the Problem", new DoubleValue(double.NaN)));
+            Results.Add(new Result(HypervolumeResultName, "The hypervolume of the current front considering the Reference point defined in the Problem", new DoubleValue(double.NaN)));
+            Results.Add(new Result(BestKnownHypervolumeResultName, "The best known hypervolume considering the Reference point defined in the Problem", new DoubleValue(double.NaN)));
+            Results.Add(new Result(DifferenceToBestKnownHypervolumeResultName, "The difference between the current and the best known hypervolume", new DoubleValue(double.NaN)));
             Results.Add(new Result(ScatterPlotResultName, "A scatterplot displaying the evaluated solutions and (if available) the analytically optimal front", new ParetoFrontScatterPlot()));
             Results.Add(new Result(CurrentFrontResultName, "The Pareto Front", new DoubleMatrix()));
@@ -256,4 +280,5 @@
             // todo: add BestKnownFront parameter
             ResultsScatterPlot = new ParetoFrontScatterPlot(new double[0][], new double[0][], problem.BestKnownFront.ToJaggedArray(), problem.Objectives, problem.ProblemSize);
+            ResultsBestKnownHypervolume = new DoubleValue(Hypervolume.Calculate(problem.BestKnownFront.ToJaggedArray(), problem.ReferencePoint.CloneAsArray(), problem.Maximization));
         }
 
@@ -262,10 +287,4 @@
             random = new MersenneTwister();
             solutions = GetInitialPopulation();
-            InitReferencePoints();
-        }
-
-        private void InitReferencePoints()
-        {
-            // Generate reference points and add them to results
             referencePoints = ReferencePoint.GenerateReferencePoints(random, NumberOfObjectives);
             ResultsGeneratedReferencePoints = Utility.ConvertToDoubleMatrix(referencePoints);
@@ -348,6 +367,12 @@
             if (!(Problem is MultiObjectiveTestFunctionProblem problem)) return;
 
+            // Indicators
             ResultsGenerationalDistance = new DoubleValue(problem.BestKnownFront != null ? GenerationalDistance.Calculate(solutions.Select(s => s.Fitness), problem.BestKnownFront.ToJaggedArray(), 1) : double.NaN);
             ResultsInvertedGenerationalDistance = new DoubleValue(problem.BestKnownFront != null ? InvertedGenerationalDistance.Calculate(solutions.Select(s => s.Fitness), problem.BestKnownFront.ToJaggedArray(), 1) : double.NaN);
+
+            var front = NonDominatedSelect.GetDominatingVectors(solutions.Select(x => x.Fitness), problem.ReferencePoint.CloneAsArray(), Problem.Maximization, true).ToArray();
+            if (front.Length == 0) return;
+            ResultsHypervolume = new DoubleValue(Hypervolume.Calculate(front, problem.ReferencePoint.CloneAsArray(), problem.Maximization));
+            ResultsDifferenceToBestKnownHypervolume = new DoubleValue(ResultsBestKnownHypervolume.Value - ResultsHypervolume.Value);
 
             Problem.Analyze(
