diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp
index d86107386..beda7ed2e 100644
--- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp
+++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp
@@ -356,7 +356,12 @@ namespace storm {
         template<typename ValueType>
         bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsOptimisticValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const {
 
+            // TODO: Differentiate between relative and absolute precision
+            // TODO: Updating solver status when iterations exceed
+
             uint64_t overallIterations = 0;
+            uint64_t lastValueIterationIterations = 0;
+            uint64_t currentVerificationIterations = 0;
             uint64_t valueIterationInvocations = 0;
 
             if (!this->multiplierA) {
@@ -369,12 +374,16 @@ namespace storm {
 
             // By default, we can not provide any guarantee
             SolverGuarantee guarantee = SolverGuarantee::None;
-
             // Get handle to multiplier.
             storm::solver::Multiplier<ValueType> const &multiplier = *this->multiplierA;
+            // Allow aliased multiplications.
+            storm::solver::MultiplicationStyle multiplicationStyle = env.solver().minMax().getMultiplicationStyle();
+            bool useGaussSeidelMultiplication = multiplicationStyle == storm::solver::MultiplicationStyle::GaussSeidel;
 
             std::vector<ValueType> *newX = auxiliaryRowGroupVector.get();
             std::vector<ValueType> *currentX = &x;
+            std::vector<ValueType> newUpperBound;
+            std::vector<ValueType> currentUpperBound;
             std::vector<ValueType> ubDiffV(newX->size());
             std::vector<ValueType> boundsDiffV(currentX->size());
 
@@ -384,77 +393,81 @@ namespace storm {
             SolverStatus status = SolverStatus::InProgress;
             this->startMeasureProgress();
 
-            while (status == SolverStatus::InProgress &&
-                   overallIterations < env.solver().minMax().getMaximalNumberOfIterations()) {
-
-                storm::solver::MultiplicationStyle multiplicationStyle = env.solver().minMax().getMultiplicationStyle();
+            while (status == SolverStatus::InProgress && overallIterations < env.solver().minMax().getMaximalNumberOfIterations()) {
 
                 // Perform value iteration until convergence
                 ++valueIterationInvocations;
-                ValueIterationResult result = performValueIteration(env, dir, currentX, newX, b, iterationPrecision,
-                                                                    env.solver().minMax().getRelativeTerminationCriterion(),
-                                                                    guarantee, overallIterations,
-                                                                    env.solver().minMax().getMaximalNumberOfIterations(),
-                                                                    multiplicationStyle);
+                ValueIterationResult result = performValueIteration(env, dir, currentX, newX, b, iterationPrecision, env.solver().minMax().getRelativeTerminationCriterion(), guarantee, overallIterations, env.solver().minMax().getMaximalNumberOfIterations(), multiplicationStyle);
 
+                lastValueIterationIterations = result.iterations;
                 overallIterations += result.iterations;
 
                 if (result.status != SolverStatus::Converged) {
                     status = result.status;
                 } else {
-                    std::vector<ValueType> upperBound = guessUpperBound(env, *currentX, precision);
-                    std::vector<ValueType> newUpperBound;
-                    while (status == SolverStatus::InProgress &&
-                           overallIterations < env.solver().minMax().getMaximalNumberOfIterations()) {
-                        // Perform value iteration stepwise for lower bound and guessed upper bound
+                    currentVerificationIterations = 0;
 
-                        // Allow aliased multiplications.
-                        bool useGaussSeidelMultiplication = multiplicationStyle == storm::solver::MultiplicationStyle::GaussSeidel;
+                    currentUpperBound = guessUpperBound(env, *currentX, precision);
+                    newUpperBound = currentUpperBound;
+
+                    // TODO: More efficient check for verification iterations
+                    while (status == SolverStatus::InProgress && overallIterations < env.solver().minMax().getMaximalNumberOfIterations() && (currentVerificationIterations / 10) < lastValueIterationIterations) {
+                        // Perform value iteration stepwise for lower bound and guessed upper bound
 
                         // Lower and upper bound iteration
                         // Compute x' = min/max(A*x + b).
                         if (useGaussSeidelMultiplication) {
                             // Copy over the current vectors so we can modify them in-place.
                             *newX = *currentX;
-                            newUpperBound = upperBound;
+                            newUpperBound = currentUpperBound;
                             // Do the calculation
                             multiplier.multiplyAndReduceGaussSeidel(env, dir, *newX, &b);
                             multiplier.multiplyAndReduceGaussSeidel(env, dir, newUpperBound, &b);
                         } else {
                             multiplier.multiplyAndReduce(env, dir, *currentX, &b, *newX);
-                            multiplier.multiplyAndReduce(env, dir, upperBound, &b, newUpperBound);
+                            multiplier.multiplyAndReduce(env, dir, currentUpperBound, &b, newUpperBound);
                         }
 
                         // Set iteration precision beforehand
                         // Calculate the maximum difference between the old and new iteration
-                        // This method adapts utility::vector::equalModuloPrecision from performValueIteration()
                         iterationPrecision = computeMaxAbsDiff(*newX, *currentX, this->getRelevantValues());
 
-                        bool up, down = true;
-                        bool cross = false;
-
+                        // Calculate difference vector of upper bound and x
+                        storm::utility::vector::subtractVectors<ValueType>(newUpperBound, *newX, boundsDiffV);
                         // Calculate difference vector of new and old upper bound
-                        storm::utility::vector::subtractVectors<ValueType>(upperBound, newUpperBound, ubDiffV);
+                        storm::utility::vector::subtractVectors<ValueType>(currentUpperBound, newUpperBound, ubDiffV);
+                        // Update current upper bound
+                        std::swap(newUpperBound, currentUpperBound);
+
                         if (storm::utility::vector::hasPositiveEntry(ubDiffV)) {
-                            // up = false (Not all values moved up)
-                            // TODO: Optimisation (if(this->hasUniqueSolution()) ?)
-                            up = false;
+                            // Not all values moved up or stayed the same
+                            // If we have a single fixed point, we can safely set the new lower bound, to the wrongly guessed upper bound
+                            if (this->hasUniqueSolution()) {
+                                *currentX = currentUpperBound;
+                            }
                             break;
                         }
-                        if (storm::utility::vector::hasNegativeEntry(ubDiffV)) {
-                            down = false;
-                        }
 
-                        // Calculate difference vector of upper bound and x
-                        storm::utility::vector::subtractVectors<ValueType>(newUpperBound, *newX, boundsDiffV);
                         if (storm::utility::vector::hasNegativeEntry(boundsDiffV)) {
-                            cross = true;
+                            // Values crossed
                             break;
                         }
 
-                        // TODO: else if down und s_i precision okay, calculate middle of both vectors
+                        // All values moved down or stayed the same and we have a maximum difference of twice the requested precision
+                        // We can safely use twice the requested precision, as we calculate the center of both vectors
+                        if (!storm::utility::vector::hasNegativeEntry(ubDiffV) && storm::utility::vector::max_if(boundsDiffV, this->getRelevantValues()) < storm::utility::convertNumber<ValueType>(2.0) * precision) {
+                            // Calculate the center of both vectors and store it in currentX
+                            // TODO: Do calculations in-place on currentX
+                            // center = (1 / 2) * u + v
+                            std::vector<ValueType> centerV = *currentX;
+                            storm::utility::vector::addVectors(*currentX, currentUpperBound, centerV);
+                            storm::utility::vector::scaleVectorInPlace(centerV, storm::utility::convertNumber<ValueType>(0.5));
+                            std::swap(centerV, *currentX);
+                            status = SolverStatus::Converged;
+                        }
 
                         ++overallIterations;
+                        ++currentVerificationIterations;
                     }
                 }