private List <Machine> RandomMachineHourGrouppedScheduleInitialisationWithReference(
            List <Machine> hourSchedule, List <Machine> previous, List <Group> groups, int load, out bool success)
        {
            // Current hour schedule uses reference from previous hour schedule
            List <Machine> hourClone         = StaticOperations.CloneMachineList(previous);
            double         previousTotalLoad = previous.Sum(machine => machine.CurrentOutputPower);

            // If power demand decreased
            bool currentSuccess = false;

            if (load < previousTotalLoad)
            {
                // Check if power demand is feasable with current machine setup
                double     totalMinimumPower   = CalculateMinimumAchievablePower(previous, maximumHourChanges);
                double     totalMaximumPower   = CalculateMaximumAchievablePower(previous, maximumHourChanges);
                List <int> machineGroupsToStop = null;
                if (!(totalMaximumPower > load && totalMinimumPower < load))
                {
                    List <int> stoppableMachineIndices = GetStoppableMachineGroupIndices(previous, groups);
                    if (stoppableMachineIndices.Count == 0)
                    {
                        success = false;
                        return(hourClone);
                    }
                    IEnumerable <IEnumerable <int> > permutations = GenerateAllPermutations(stoppableMachineIndices, stoppableMachineIndices.Count);
                    List <List <int> > permutationLists           = new List <List <int> >();
                    foreach (IEnumerable <int> permutation in permutations)
                    {
                        permutationLists.Add(permutation.ToList());
                    }
                    for (int i = 0; i < permutationLists.Count; i++)
                    {
                        double currentTotalMinimumPower = totalMinimumPower;
                        double currentTotalMaximumPower = totalMaximumPower;
                        machineGroupsToStop = new List <int>();
                        currentSuccess      = false;
                        for (int j = 0; j < permutationLists[i].Count; j++)
                        {
                            int chosenIndex = permutationLists[i][j];
                            machineGroupsToStop.Add(chosenIndex);
                            currentTotalMaximumPower = CalculateMaximumAchievablePower(previous, maximumHourChanges, machineGroupsToStop);
                            currentTotalMinimumPower = CalculateMinimumAchievablePower(previous, maximumHourChanges, machineGroupsToStop);
                            if (currentTotalMinimumPower < load && currentTotalMaximumPower > load)
                            {
                                currentSuccess = true;
                                break;
                            }
                        }
                        if (currentSuccess == true)
                        {
                            foreach (int stopGroup in machineGroupsToStop)
                            {
                                foreach (int stop in groups[stopGroup].grouppedMachines)
                                {
                                    hourClone[stop].CurrentOutputPower = 0;
                                }
                            }
                            totalMaximumPower = currentTotalMaximumPower;
                            totalMinimumPower = currentTotalMinimumPower;
                            break;
                        }
                    }
                    if (StaticOperations.SpecialValidation(hourClone, previous) == false)
                    {
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    currentSuccess = true;
                }
            }
            // If power demand increased
            else
            {
                // Check if power demand is feasable with current machine setup
                double     totalMinimumPower    = CalculateMinimumAchievablePower(previous, maximumHourChanges);
                double     totalMaximumPower    = CalculateMaximumAchievablePower(previous, maximumHourChanges);
                List <int> machineGroupsToStart = null;
                if (!(totalMaximumPower > load && totalMinimumPower < load))
                {
                    List <int> startableMachineIndices = GetStartableMachineGroupIndices(previous, groups);
                    if (startableMachineIndices.Count == 0)
                    {
                        success = false;
                        return(hourClone);
                    }
                    IEnumerable <IEnumerable <int> > permutations = GenerateAllPermutations(startableMachineIndices, startableMachineIndices.Count);
                    List <List <int> > permutationLists           = new List <List <int> >();
                    foreach (IEnumerable <int> permutation in permutations)
                    {
                        permutationLists.Add(permutation.ToList());
                    }
                    for (int i = 0; i < permutationLists.Count; i++)
                    {
                        double currentTotalMinimumPower = totalMinimumPower;
                        double currentTotalMaximumPower = totalMaximumPower;
                        machineGroupsToStart = new List <int>();
                        currentSuccess       = false;
                        for (int j = 0; j < permutationLists[i].Count; j++)
                        {
                            int chosenIndex = permutationLists[i][j];
                            machineGroupsToStart.Add(chosenIndex);
                            currentTotalMaximumPower += CalculateMaximumGroupPower(hourClone, groups[chosenIndex]);
                            currentTotalMinimumPower += CalculateMinimumGroupPower(hourClone, groups[chosenIndex]);
                            if (currentTotalMinimumPower < load && currentTotalMaximumPower > load)
                            {
                                currentSuccess = true;
                                break;
                            }
                        }
                        if (currentSuccess == true)
                        {
                            foreach (int startGroup in machineGroupsToStart)
                            {
                                foreach (int start in groups[startGroup].grouppedMachines)
                                {
                                    hourClone[start].CurrentOutputPower = hourClone[start].MaximumOutputPower;
                                }
                            }
                            totalMaximumPower = currentTotalMaximumPower;
                            totalMinimumPower = currentTotalMinimumPower;
                            break;
                        }
                    }
                    if (StaticOperations.SpecialValidation(hourClone, previous) == false)
                    {
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    currentSuccess = true;
                }
            }
            if (currentSuccess == false)
            {
                success = false;
                return(hourClone);
            }

            double totalLoad = hourClone.Sum(machine => machine.CurrentOutputPower);

            if (totalLoad > load)
            {
                while (totalLoad > load)
                {
                    double change = random.NextDouble() * (totalLoad - load);
                    if (totalLoad - load < 1)
                    {
                        change = totalLoad - load;
                    }
                    List <int> lowerableMachineIndices = GetLowerableMachineIndices(hourClone, previous);
                    lowerableMachineIndices.Shuffle();
                    int    index = lowerableMachineIndices[0];
                    double maximumAllowedDecrease = GetMaximumMachineDecrease(hourClone[index], previous[index], maximumHourChanges[index]);
                    change     = change > maximumAllowedDecrease ? maximumAllowedDecrease : change;
                    totalLoad -= change;
                    hourClone[index].CurrentOutputPower -= change;
                }
            }
            else
            {
                while (totalLoad < load)
                {
                    double change = random.NextDouble() * (load - totalLoad);
                    if (load - totalLoad < 1)
                    {
                        change = load - totalLoad;
                    }
                    List <int> incresableMachineIndices = GetIncreasableMachineIndices(hourClone, previous);
                    incresableMachineIndices.Shuffle();
                    int    index = incresableMachineIndices[0];
                    double maximumAllowedIncrease = GetMaximumMachineIncrease(hourClone[index], previous[index], maximumHourChanges[index]);
                    change     = change > maximumAllowedIncrease ? maximumAllowedIncrease : change;
                    totalLoad += change;
                    hourClone[index].CurrentOutputPower += change;
                }
            }

            success = totalLoad == load;
            return(hourClone);
        }