Skip to content

Commit a10e748

Browse files
committed
add MINIMUM_ACTIVE_SIMULATIONS = 3 default setting
1 parent 2fbd3d8 commit a10e748

5 files changed

Lines changed: 84 additions & 10 deletions

File tree

settings.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ MAXIMUM_TIME = 0
3232
INTERIM_OUTPUT_INTERVAL = 240
3333
# minimum number of simulations to do (0 is exactly 1 simulation per scenario)
3434
MINIMUM_SIMULATIONS = 10
35+
# minimum number of simulations where any spread occurs to do (0 is exactly 1 simulation per scenario)
36+
MINIMUM_ACTIVE_SIMULATIONS = 3
3537
# maximum number of simulations to do (0 is exactly 1 simulation per scenario)
3638
MAXIMUM_SIMULATIONS = 10000
3739
# maximum percent change in statistics between runs before results are consider stable [0 - 1]

src/cpp/fs/Model.cpp

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ Model::Model(
2929
: output_directory_(output_directory), start_time_(start_time), running_since_(Clock::now()),
3030
time_limit_(Settings::maximumTimeSeconds()), no_interim_save_since_(Clock::now()),
3131
interim_save_interval_(Settings::interimOutputIntervalSeconds()), env_(env),
32-
latitude_(start_point.latitude()), longitude_(start_point.longitude())
32+
latitude_(start_point.latitude()), longitude_(start_point.longitude()),
33+
active_simulations_still_required_(Settings::minimumActiveSimulationCount())
3334
{
3435
logging::debug("Calculating for (%f, %f)", start_point.latitude(), start_point.longitude());
3536
const auto nd_for_point = calculate_nd_ref_for_point(env->elevation(), start_point);
@@ -475,6 +476,10 @@ bool Model::shouldStop() const noexcept
475476
}
476477
bool Model::isOutOfTime() const noexcept { return is_out_of_time_; }
477478
bool Model::isUnderSimulationCountMinimum() const noexcept { return is_under_simulation_minimum_; }
479+
size_t Model::activeSimulationsStillRequired() const noexcept
480+
{
481+
return active_simulations_still_required_;
482+
}
478483
bool Model::isOverSimulationCountMaximum() const noexcept { return is_over_simulation_count_; }
479484
shared_ptr<ProbabilityMap> Model::makeProbabilityMap(
480485
const DurationSize time,
@@ -552,6 +557,29 @@ bool Model::add_statistics(
552557
{
553558
return true;
554559
}
560+
active_simulations_still_required_ = [&]() {
561+
size_t num_left = Settings::minimumActiveSimulationCount();
562+
for (const auto s : *all_sizes)
563+
{
564+
if (s > initial_size())
565+
{
566+
--num_left;
567+
}
568+
if (0 == num_left)
569+
{
570+
logging::note("Found enough active simulations to meet minimum");
571+
return num_left;
572+
}
573+
}
574+
logging::note(
575+
"Not enough active simulations out of %ld results to meet minimum", all_sizes->size()
576+
);
577+
return num_left;
578+
}();
579+
if (0 < activeSimulationsStillRequired())
580+
{
581+
return true;
582+
}
555583
is_over_simulation_count_ = all_sizes->size() >= Settings::maximumSimulationCount();
556584
if (isOverSimulationCountMaximum())
557585
{
@@ -597,15 +625,6 @@ size_t runs_required(
597625
logging::note("Stopping after iteration %ld because running in deterministic mode", i);
598626
return 0;
599627
}
600-
if (model.isUnderSimulationCountMinimum())
601-
{
602-
logging::debug(
603-
"Continuing after %d iterations. Simulation minimum of %d simulations has not been reached.",
604-
i,
605-
Settings::minimumSimulationCount()
606-
);
607-
return Settings::minimumSimulationCount() - i;
608-
}
609628
if (model.isOverSimulationCountMaximum())
610629
{
611630
logging::note(
@@ -624,6 +643,27 @@ size_t runs_required(
624643
);
625644
return 0;
626645
}
646+
const auto max_sims_left = Settings::maximumSimulationCount() - i;
647+
if (model.isUnderSimulationCountMinimum())
648+
{
649+
logging::debug(
650+
"Continuing after %d iterations. Simulation minimum of %d simulations has not been reached.",
651+
i,
652+
Settings::minimumSimulationCount()
653+
);
654+
return min(max_sims_left, Settings::minimumSimulationCount() - i);
655+
}
656+
const auto active_still_required = model.activeSimulationsStillRequired();
657+
if (0 < active_still_required)
658+
{
659+
logging::debug(
660+
"Continuing after %d iterations. Active simulation minimum of %d simulations has not been reached.",
661+
i,
662+
Settings::minimumActiveSimulationCount()
663+
);
664+
// HACK: if we have n active sims so far then expect that many per i simulations?
665+
return min(max_sims_left, i * active_still_required);
666+
}
627667
// HACK: statistics don't work if only one value, so need at least 2
628668
const auto min_values = min(min(all_sizes->size(), means->size()), pct->size());
629669
if (1 >= min_values)

src/cpp/fs/Model.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "FireWeather.h"
77
#include "Iteration.h"
88
#include "Perimeter.h"
9+
#include "unstable.h"
910
namespace fs
1011
{
1112
class StartPoint;
@@ -207,6 +208,11 @@ class Model
207208
* \return Whether or not simulation is under min simulation count
208209
*/
209210
[[nodiscard]] bool isUnderSimulationCountMinimum() const noexcept;
211+
/**
212+
* \brief How many active simulations are still needed
213+
* \return How many active simulations are still needed
214+
*/
215+
[[nodiscard]] size_t activeSimulationsStillRequired() const noexcept;
210216
/**
211217
* \brief Whether or not simulation is over max simulation count
212218
* \return Whether or not simulation is over max simulation count
@@ -478,6 +484,10 @@ class Model
478484
* \brief If simulation is undex min simulation count
479485
*/
480486
bool is_under_simulation_minimum_{true};
487+
/**
488+
* \brief Number of active simulations still required
489+
*/
490+
size_t active_simulations_still_required_{};
481491
/**
482492
* \brief If simulation is over max simulation count
483493
*/

src/cpp/fs/Settings.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,14 @@ class SettingsImplementation
253253
{
254254
return minimum_simulation_count_;
255255
}
256+
/**
257+
* \brief Minimum number of simulations that must run before stopping
258+
* \return Minimum number of simulations that must run before stopping
259+
*/
260+
[[nodiscard]] constexpr size_t minimumActiveSimulationCount() noexcept
261+
{
262+
return minimum_active_simulation_count_;
263+
}
256264
/**
257265
* \brief Maximum number of simulations before stopping and whatever results it has are used
258266
* \return Maximum number of simulations before stopping and whatever results it has are used
@@ -383,6 +391,10 @@ class SettingsImplementation
383391
* \brief Minimum number of simulations that must run before stopping
384392
*/
385393
size_t minimum_simulation_count_;
394+
/**
395+
* \brief Minimum number of simulations with any spread that must run before stopping
396+
*/
397+
size_t minimum_active_simulation_count_;
386398
/**
387399
* \brief Maximum number of simulations before stopping and whatever results it has are used
388400
*/
@@ -581,6 +593,7 @@ void SettingsImplementation::setRoot(const char* dirname) noexcept
581593
maximum_time_seconds_ = stol(get_value(settings, "MAXIMUM_TIME"));
582594
interim_output_interval_seconds_ = stol(get_value(settings, "INTERIM_OUTPUT_INTERVAL"));
583595
minimum_simulation_count_ = stol(get_value(settings, "MINIMUM_SIMULATIONS"));
596+
minimum_active_simulation_count_ = stol(get_value(settings, "MINIMUM_ACTIVE_SIMULATIONS"));
584597
maximum_simulation_count_ = stol(get_value(settings, "MAXIMUM_SIMULATIONS"));
585598
threshold_scenario_weight_ = stod(get_value(settings, "THRESHOLD_SCENARIO_WEIGHT"));
586599
threshold_daily_weight_ = stod(get_value(settings, "THRESHOLD_DAILY_WEIGHT"));
@@ -803,6 +816,10 @@ size_t Settings::minimumSimulationCount() noexcept
803816
{
804817
return SettingsImplementation::instance().minimumSimulationCount();
805818
}
819+
size_t Settings::minimumActiveSimulationCount() noexcept
820+
{
821+
return SettingsImplementation::instance().minimumActiveSimulationCount();
822+
}
806823
size_t Settings::maximumSimulationCount() noexcept
807824
{
808825
return SettingsImplementation::instance().maximumSimulationCount();

src/cpp/fs/Settings.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,11 @@ class Settings
304304
* \return Minimum number of simulations that must run before stopping
305305
*/
306306
[[nodiscard]] static size_t minimumSimulationCount() noexcept;
307+
/**
308+
* \brief Minimum number of simulations that must run before stopping
309+
* \return Minimum number of simulations that must run before stopping
310+
*/
311+
[[nodiscard]] static size_t minimumActiveSimulationCount() noexcept;
307312
/**
308313
* \brief Maximum number of simulations before stopping and whatever results it has are used
309314
* \return Maximum number of simulations before stopping and whatever results it has are used

0 commit comments

Comments
 (0)