private void simulateAndShowResults(ComputingSystem.DistributionType distrType) { textBox_output.Text = ""; ComputingSystem cs = new ComputingSystem(); var stats = cs.Simulate(delegate(double done) { progressBar1.Value = (int)Math.Round(done); }, distrType); stats.AnalizeSnapShots(); string output = ""; foreach (var programmsProb in stats.ProgrammsCountProbability) { if (programmsProb.Key == 0) { output += $"{programmsProb.Value} - вероятность того, что ВС не загружена" + Environment.NewLine; } else if (programmsProb.Key < Constants.ServersCount) { output += $"{programmsProb.Value} - вероятность того, что загружено: {programmsProb.Key} \\ {Constants.ServersCount} серверов" + Environment.NewLine; } else if (programmsProb.Key == Constants.ServersCount) { output += $"{programmsProb.Value} - вероятность того, что загружено: {Constants.ServersCount} \\ {Constants.ServersCount} серверов. Буфер свободен" + Environment.NewLine; } else if (programmsProb.Key > Constants.ServersCount) { var inBufferCount = programmsProb.Key - Constants.ServersCount; output += $"{programmsProb.Value} - вероятность того, что в буфере {inBufferCount} программа(ы)" + Environment.NewLine; } } var executedPercentage = countPercents(stats.TotalProgrammsAdded, stats.ExecutedProgrammsCount); output += $"{executedPercentage}% - Q (относит. пропускная способность- процент программ, обработанных ВС)" + Environment.NewLine; var programmsExecutedPerSecond = Math.Round((double)stats.ExecutedProgrammsCount / (double)Constants.SimulationTime, 2); output += $"{programmsExecutedPerSecond} - S (среднее число программ, обработанных в секунду)" + Environment.NewLine; var discardProbability = ComputingSystemStatistics.CountProbability(stats.DiscardedProgrammsCount, stats.TotalProgrammsAdded); output += $"{discardProbability} - Pоткл (вероятность отказа, т.е. того, что программа будет не обработанной)" + Environment.NewLine; var totalServersBusy = 0; int totalProgrammsInSystem = 0; int totalProgrammsInBuffer = 0; foreach (var snapshot in stats.SnapShots) { totalProgrammsInSystem += snapshot.ExecutingCount + snapshot.BufferItemsCount; totalProgrammsInBuffer += snapshot.BufferItemsCount; int serversBusy = snapshot.ExecutingCount; if (serversBusy > Constants.ServersCount) { serversBusy = Constants.ServersCount; } totalServersBusy += serversBusy; } double avgServersBusy = Math.Round((double)totalServersBusy / (double)stats.SnapShots.Count, 2); output += $"{avgServersBusy} - K (среднее число занятых серверов)" + Environment.NewLine; double avgProgrammsInSystem = Math.Round((double)totalProgrammsInSystem / (double)stats.SnapShots.Count, 2); output += $"{avgProgrammsInSystem} - K (среднее число программ в ВС)" + Environment.NewLine; var spentTimeTotal = 0.0; var spentTimeInBuffer = 0.0; foreach (var programm in stats.programms) { spentTimeTotal += programm.ExecutionAwaitingTime + programm.ExecutionTime; spentTimeInBuffer += programm.ExecutionAwaitingTime; } var averageTimeInSystem = Math.Round(spentTimeTotal / (double)stats.programms.Count, 2); output += $"{averageTimeInSystem} сек - Tпрог (среднее время нахождения программы в ВС)" + Environment.NewLine; double avgProgrammsInBuffer = Math.Round((double)totalProgrammsInBuffer / (double)stats.SnapShots.Count, 2); output += $"{avgProgrammsInBuffer} - Nбуф (среднее число программ в буфере)" + Environment.NewLine; var averageTimeInBuffer = Math.Round(spentTimeInBuffer / (double)stats.programms.Count, 2); output += $"{averageTimeInBuffer} сек - Tбуф (среднее время нахождения программы в буфере)" + Environment.NewLine; textBox_output.Text = output; }
public ComputingSystemStatistics Simulate(simulationProcessCallback callcack, DistributionType distributionType = DistributionType.Liniar) { //сброс переменных bufferItems = 0; programms = new List <ServerProgramm>(); finishedProgramms = new List <ServerProgramm>(); ComputingSystemStatistics statistic = new ComputingSystemStatistics(); double timeTillNextProgrammLinear = 0; var popupProbabilityExp = GetExpProbability(Constants.ProgrammPopupTime.ExpLambda, Constants.SimulationStep); double elapsedExp = 0; for (double i = 0; i <= Constants.SimulationTime; i += Constants.SimulationStep) { if ((int)i % 10 == 0) { callcack(i / (Constants.SimulationTime / 100.0)); } programms.ForEach(x => x.Update(Constants.SimulationStep)); //поступление новых программ if (distributionType == DistributionType.Liniar) { if (timeTillNextProgrammLinear <= 0) { var serverProgramm = new ServerProgramm(DistributionType.Liniar, GetRandomNumber(Constants.ProgrammExecutionTime.LinearMinTime, Constants.ProgrammExecutionTime.LinearMaxTime)); programms.Add(serverProgramm); timeTillNextProgrammLinear = GetRandomNumber(Constants.ProgrammPopupTime.LinearMinTime, Constants.ProgrammPopupTime.LinearMaxTime); statistic.TotalProgrammsAdded++; } timeTillNextProgrammLinear -= Constants.SimulationStep; } else if (distributionType == DistributionType.Exponential) { if (popupProbabilityExp > GetRandomNumber(0, 1)) { var serverProgramm = new ServerProgramm(DistributionType.Exponential, GetRandomNumber(Constants.ProgrammExecutionTime.LinearMinTime, Constants.ProgrammExecutionTime.LinearMaxTime)); programms.Add(serverProgramm); statistic.TotalProgrammsAdded++; } } //перевод программ из ожидания в выполнение int freeServersCount = Constants.ServersCount - programms.Count(x => x.Status == ServerProgramm.ProgrammStatus.Executing); programms.Where(x => x.Status == ServerProgramm.ProgrammStatus.AwaitingExecution).Take(freeServersCount).ToList() .ForEach(x => x.Status = ServerProgramm.ProgrammStatus.Executing); //считаем переполняющие буфер программы невыполненными var overflowCount = programms.Count(x => x.Status == ServerProgramm.ProgrammStatus.AwaitingExecution) - Constants.BufferSize; if (overflowCount > 0) { programms.Where(x => x.Status == ServerProgramm.ProgrammStatus.AwaitingExecution).Take(overflowCount).ToList() .ForEach(x => x.Status = ServerProgramm.ProgrammStatus.Discarded); } //сбор статистики statistic.SnapShots.Add(new SnapShot() { BufferItemsCount = programms.Count(x => x.Status == ServerProgramm.ProgrammStatus.AwaitingExecution), ExecutingCount = programms.Count(x => x.Status == ServerProgramm.ProgrammStatus.Executing) }); //удаляем из листа программ не обработанные и выполненные программы для оптимизации скорости поиска по листу в следующих итерациях var hist = programms.Where(x => x.Status == ServerProgramm.ProgrammStatus.Discarded || x.Status == ServerProgramm.ProgrammStatus.Executed).ToList(); foreach (var programm in hist) { if (programm.Status == ServerProgramm.ProgrammStatus.Executed) { statistic.ExecutedProgrammsCount++; } if (programm.Status == ServerProgramm.ProgrammStatus.Discarded) { statistic.DiscardedProgrammsCount++; } programms.Remove(programm); finishedProgramms.Add(programm); } } //сбор всех программ в один лист для статистики finishedProgramms.AddRange(programms); statistic.programms = finishedProgramms; return(statistic); }