/
onequ1z
/
JavaCoursePaperTulSU
Обзор
Документация
Войти
/
onequ1z
/
JavaCoursePaperTulSU
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/test/java/ru/dmitry/montecarlo/service/ExperimentRunnerTest.java
230 строк
9 KB
tayno
Добавил подробные модульные тесты для геометрии и метода Монте-Карло
04 дек 2025, 22:27
04 дек 2025, 22:27
95bfd7e
Код
Авторство
О чём код?
package ru.dmitry.montecarlo.service; import org.junit.jupiter.api.Test; import ru.dmitry.montecarlo.model.ExperimentResult; import ru.dmitry.montecarlo.model.Figure; import ru.dmitry.montecarlo.model.MonteCarloResult; import ru.dmitry.montecarlo.model.Point; import ru.dmitry.montecarlo.model.Rectangle; import java.util.Random; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; class ExperimentRunnerTest { /** * Простая детерминированная заглушка MonteCarlo для тестирования агрегации. */ private static class StubMonteCarlo extends MonteCarlo { private int counter = 0; @Override public MonteCarloResult estimateArea(Figure figure, Rectangle rectangle, long n, Random rng) { counter++; // Конструируем предсказуемые данные double estimatedArea = n + counter; // растёт с каждым вызовом double relError = counter * 1.0; // 1,2,3,... long duration = counter * 10L; // 10,20,30,... long hits = counter; // просто счётчик return new MonteCarloResult(n, hits, estimatedArea, relError, duration); } } @Test void testRunExperimentsAggregatesResultsPerN() { // Фигура и прямоугольник можно сделать простыми, они не используются в StubMonteCarlo Point a = new Point(0.0, 0.0); Point b = new Point(10.0, 0.0); Point c = new Point(10.0, 10.0); Point d = new Point(0.0, 10.0); Rectangle rectangle = new Rectangle(a, b, c, d); Figure dummyFigure = new Figure() { @Override public boolean contains(ru.dmitry.montecarlo.model.Point p) { return true; } @Override public double exactArea() { return 1.0; } }; // фигура, всегда "содержит" точку long[] nValues = new long[]{100L, 200L}; int repeats = 3; StubMonteCarlo stub = new StubMonteCarlo(); ExperimentRunner runner = new ExperimentRunner(stub); ExperimentResult result = runner.runExperiments( dummyFigure, rectangle, nValues, repeats, new Random(1L) ); assertNotNull(result); ExperimentResult.NStats[] statsPerN = result.getStatsPerN(); assertEquals(2, statsPerN.length); for (int i = 0; i < nValues.length; i++) { ExperimentResult.NStats stats = statsPerN[i]; assertEquals(nValues[i], stats.getSamples()); MonteCarloResult[] runs = stats.getRuns(); assertNotNull(runs); assertEquals(repeats, runs.length); // Проверяем, что средние и стандартные отклонения имеют разумные значения assertTrue(stats.getAvgEstimatedArea() > 0.0); assertTrue(stats.getAvgRelativeErrorPercent() > 0.0); assertTrue(stats.getAvgDurationMillis() > 0.0); assertTrue(stats.getStdDevEstimatedArea() >= 0.0); assertTrue(stats.getStdDevRelativeErrorPercent() >= 0.0); } } @Test void testSummaryStatsCalculation() { // Тест правильности вычисления статистики Point a = new Point(0.0, 0.0); Point b = new Point(10.0, 0.0); Point c = new Point(10.0, 10.0); Point d = new Point(0.0, 10.0); Rectangle rectangle = new Rectangle(a, b, c, d); Point g = new Point(0.0, 0.0); Point e = new Point(5.0, 0.0); Point f = new Point(0.0, 5.0); ru.dmitry.montecarlo.model.TriangleGEF triangle = new ru.dmitry.montecarlo.model.TriangleGEF(g, e, f); long[] nValues = new long[]{100L}; int repeats = 4; long seed = 999L; MonteCarlo monteCarlo = new MonteCarlo(); ExperimentRunner runner = new ExperimentRunner(monteCarlo); ExperimentResult result = runner.runExperiments( triangle, rectangle, nValues, repeats, new Random(seed) ); assertNotNull(result); ExperimentResult.NStats[] statsPerN = result.getStatsPerN(); assertEquals(1, statsPerN.length); ExperimentResult.NStats stats = statsPerN[0]; assertEquals(100L, stats.getSamples()); assertEquals(repeats, stats.getRuns().length); // Проверяем, что среднее значение вычислено правильно // (сумма всех значений / количество) double sumArea = 0.0; double sumError = 0.0; for (MonteCarloResult run : stats.getRuns()) { sumArea += run.getEstimatedArea(); sumError += run.getRelativeErrorPercent(); } double expectedAvgArea = sumArea / repeats; double expectedAvgError = sumError / repeats; assertEquals(expectedAvgArea, stats.getAvgEstimatedArea(), 0.0001, "Среднее значение площади должно быть вычислено правильно"); assertEquals(expectedAvgError, stats.getAvgRelativeErrorPercent(), 0.0001, "Среднее значение ошибки должно быть вычислено правильно"); // Проверяем стандартное отклонение (должно быть >= 0) assertTrue(stats.getStdDevEstimatedArea() >= 0.0, "Стандартное отклонение площади должно быть неотрицательным"); assertTrue(stats.getStdDevRelativeErrorPercent() >= 0.0, "Стандартное отклонение ошибки должно быть неотрицательным"); } @Test void testSummaryStatsWithSingleRun() { // Тест статистики с одним запуском (стандартное отклонение должно быть 0) Point a = new Point(0.0, 0.0); Point b = new Point(1.0, 0.0); Point c = new Point(1.0, 1.0); Point d = new Point(0.0, 1.0); Rectangle rectangle = new Rectangle(a, b, c, d); ru.dmitry.montecarlo.model.TriangleGEF triangle = new ru.dmitry.montecarlo.model.TriangleGEF(a, b, c); long[] nValues = new long[]{50L}; int repeats = 1; // Только один запуск MonteCarlo monteCarlo = new MonteCarlo(); ExperimentRunner runner = new ExperimentRunner(monteCarlo); ExperimentResult result = runner.runExperiments( triangle, rectangle, nValues, repeats, new Random(1L) ); ExperimentResult.NStats stats = result.getStatsPerN()[0]; // При одном запуске стандартное отклонение должно быть 0 assertEquals(0.0, stats.getStdDevEstimatedArea(), 0.0001, "При одном запуске стандартное отклонение должно быть 0"); assertEquals(0.0, stats.getStdDevRelativeErrorPercent(), 0.0001, "При одном запуске стандартное отклонение ошибки должно быть 0"); } @Test void testSummaryStatsWithMultipleNValues() { // Тест статистики для нескольких значений N Point a = new Point(0.0, 0.0); Point b = new Point(10.0, 0.0); Point c = new Point(10.0, 10.0); Point d = new Point(0.0, 10.0); Rectangle rectangle = new Rectangle(a, b, c, d); Point g = new Point(0.0, 0.0); Point e = new Point(5.0, 0.0); Point f = new Point(0.0, 5.0); ru.dmitry.montecarlo.model.TriangleGEF triangle = new ru.dmitry.montecarlo.model.TriangleGEF(g, e, f); long[] nValues = new long[]{100L, 500L, 1000L}; int repeats = 3; MonteCarlo monteCarlo = new MonteCarlo(); ExperimentRunner runner = new ExperimentRunner(monteCarlo); ExperimentResult result = runner.runExperiments( triangle, rectangle, nValues, repeats, new Random(777L) ); assertNotNull(result); ExperimentResult.NStats[] statsPerN = result.getStatsPerN(); assertEquals(3, statsPerN.length); // Проверяем, что для каждого N статистика вычислена for (int i = 0; i < nValues.length; i++) { ExperimentResult.NStats stats = statsPerN[i]; assertEquals(nValues[i], stats.getSamples()); assertEquals(repeats, stats.getRuns().length); assertTrue(stats.getAvgEstimatedArea() > 0.0); assertTrue(stats.getStdDevEstimatedArea() >= 0.0); } } }