diff options
-rw-r--r-- | SA_POP/ChangeLog | 28 | ||||
-rw-r--r-- | SA_POP/LogFileOut.cpp | 163 | ||||
-rw-r--r-- | SA_POP/SANet/SANet.cpp | 58 | ||||
-rw-r--r-- | SA_POP/SANet/SANet.h | 32 | ||||
-rw-r--r-- | SA_POP/experiments/EU_Performance/Exp_Core/Exp_EU_Planner.cpp | 372 | ||||
-rw-r--r-- | SA_POP/experiments/EU_Performance/Exp_Core/Exp_EU_Planner.h | 105 | ||||
-rw-r--r-- | SA_POP/experiments/EU_Performance/SAPOP_Exp_EU.cpp | 273 |
7 files changed, 849 insertions, 182 deletions
diff --git a/SA_POP/ChangeLog b/SA_POP/ChangeLog index 616ce86f485..a946cea9650 100644 --- a/SA_POP/ChangeLog +++ b/SA_POP/ChangeLog @@ -1,3 +1,25 @@ +Fri Jan 15 23:37:01 UTC 2010 John S. Kinnebrew <john.s.kinnebrew@vanderbilt.edu> + + * LogFileOut.cpp: + + Minor update to plan output info & formatting. + + * SANet/SANet.h: + * SANet/SANet.cpp: + + Added methods to get all conditions/tasks, get number of conditions/tasks, & set (init) value of multiple conditions. + + * experiments/EU_Performance/Exp_Core/Exp_EU_Planner.h: + * experiments/EU_Performance/Exp_Core/Exp_EU_Planner.cpp: + + Added random network initialization (true initial conditions and goal conditions). + Updated trial/run statistics gathering & output. + + * experiments/EU_Performance/SAPOP_Exp_EU.cpp: + + Updated interface to allow running experiment on a network using random network initialization and statistics logging. + + Fri Jan 15 06:40:02 UTC 2010 Ben Podgursky <bpodgursky@gmail.com> * SA_POP_Types.h: @@ -7,9 +29,9 @@ Fri Jan 15 06:40:02 UTC 2010 Ben Podgursky <bpodgursky@gmail.com> * utils/SANetGenerator/Net_Complete.py: - --Script generates task map - --No task limiter - --Uses choose task once strategy + --Script generates task map + --No task limiter + --Uses choose task once strategy Thu Jan 14 23:23:05 UTC 2010 John S. Kinnebrew <john.s.kinnebrew@vanderbilt.edu> diff --git a/SA_POP/LogFileOut.cpp b/SA_POP/LogFileOut.cpp index ab1af922a16..04cf745c08c 100644 --- a/SA_POP/LogFileOut.cpp +++ b/SA_POP/LogFileOut.cpp @@ -63,108 +63,125 @@ void LogFileOut::notify_plan (SA_POP::Planner *planner) time_t cur_time = time(0); this->outfile_ << std::endl; - this->outfile_ << "Plan (" << plan.name << ") Changed at " << std::endl; - this->outfile_ << ctime (&cur_time) << std::endl; + this->outfile_ << "Plan (" << plan.name << ")" << " changed at " << ctime (&cur_time); this->outfile_ << "ID: " << plan.plan_id << std::endl; - + this->outfile_ << "Goal Condition(s):"; + for (GoalMap::iterator goal_iter = plan.goal.goal_conds.begin (); + goal_iter != plan.goal.goal_conds.end (); goal_iter++) + { + this->outfile_ << " " << planner->get_cond_name (goal_iter->first); + if (goal_iter->second >= 0) + this->outfile_ << " (TRUE) = " << goal_iter->second; + else + this->outfile_ << " (FALSE) = " << (-1.0 * goal_iter->second); + } + this->outfile_ << std::endl; this->outfile_ << "Start Window: [" << plan.start_window.first << ", "; this->outfile_ << plan.start_window.second << "]" << std::endl; - this->outfile_ << "End Window: [" << plan.end_window.first << ", "; this->outfile_ << plan.end_window.second << "]" << std::endl; - + this->outfile_ << "Expected Utility: " << planner->calc_plan_eu (plan) << std::endl << std::endl; + + + this->outfile_ << "ALL Task Instances:" << std::endl; for (PlanInstSet::iterator inst_iter = plan.task_insts.begin (); inst_iter != plan.task_insts.end (); inst_iter++) { PlanTaskInst inst = *inst_iter; - this->outfile_ << "Task Instance (" << inst.name << "):" << std::endl; + this->outfile_ << " Task Instance (" << inst.name << "):" << std::endl; - this->outfile_ << " ID: " << inst.inst_id << std::endl; + this->outfile_ << " ID: " << inst.inst_id << std::endl; - this->outfile_ << " Start Window: [" << inst.start_window.first << ", "; + this->outfile_ << " Start Window: [" << inst.start_window.first << ", "; this->outfile_ << inst.start_window.second << "]" << std::endl; - this->outfile_ << " End Window: [" << inst.end_window.first << ", "; + this->outfile_ << " End Window: [" << inst.end_window.first << ", "; this->outfile_ << inst.end_window.second << "]" << std::endl; - this->outfile_ << " Task ID: " << inst.task_id << std::endl; + this->outfile_ << " Task ID: " << inst.task_id << std::endl; - this->outfile_ << " Task Type: " << inst.type_id << std::endl; + this->outfile_ << " Task Type: " << inst.type_id << std::endl; - this->outfile_ << " Suggested Implementation: "; + this->outfile_ << " Suggested Implementation: "; this->outfile_ << inst.suggested_impl << std::endl; } - this->outfile_ << std::endl; - for (PlanConnSet::iterator conn_iter = plan.connections.begin (); - conn_iter != plan.connections.end (); - conn_iter++) - { - PlanConnection conn = *conn_iter; - this->outfile_ << "Data Connection:" << std::endl; - this->outfile_ << " " << conn.first_task_inst << " ("; - this->outfile_ << planner->get_task_name ( - planner->get_task_from_inst (conn.first_task_inst)) << "--"; - this->outfile_ << conn.first_port << ") -"; - this->outfile_ << "(" << planner->get_cond_name (conn.cond) << ")-> "; - this->outfile_ << conn.second_task_inst << " ("; - this->outfile_ << planner->get_task_name ( - planner->get_task_from_inst (conn.second_task_inst)) << "--"; - this->outfile_ << conn.second_port << ")" << std::endl; + if (plan.connections.size () > 0) { + this->outfile_ << "ALL Data Connections:" << std::endl; + for (PlanConnSet::iterator conn_iter = plan.connections.begin (); + conn_iter != plan.connections.end (); + conn_iter++) + { + PlanConnection conn = *conn_iter; + this->outfile_ << " Data Connection:" << std::endl; + this->outfile_ << " " << conn.first_task_inst << " ("; + this->outfile_ << planner->get_task_name ( + planner->get_task_from_inst (conn.first_task_inst)) << "--"; + this->outfile_ << conn.first_port << ") -"; + this->outfile_ << "(" << planner->get_cond_name (conn.cond) << ")-> "; + this->outfile_ << conn.second_task_inst << " ("; + this->outfile_ << planner->get_task_name ( + planner->get_task_from_inst (conn.second_task_inst)) << "--"; + this->outfile_ << conn.second_port << ")" << std::endl; + } + this->outfile_ << std::endl; } - this->outfile_ << std::endl; - for (CLSet::iterator cl_iter = plan.causal_links.begin (); - cl_iter != plan.causal_links.end (); - cl_iter++) - { - CausalLink clink = *cl_iter; - this->outfile_ << "Causal Link:" << std::endl; - this->outfile_ << " " << clink.first << " ("; - this->outfile_ << planner->get_task_name ( - planner->get_task_from_inst (clink.first)) << ") -"; - this->outfile_ << "(" << planner->get_cond_name (clink.cond.id) << ")-> "; - this->outfile_ << clink.second << " ("; - this->outfile_ << planner->get_task_name ( - planner->get_task_from_inst (clink.second)) << ")" << std::endl; + if (plan.causal_links.size () > 0) { + this->outfile_ << "ALL Causal Links:" << std::endl; + for (CLSet::iterator cl_iter = plan.causal_links.begin (); + cl_iter != plan.causal_links.end (); + cl_iter++) + { + CausalLink clink = *cl_iter; + this->outfile_ << " " << clink.first << " ("; + this->outfile_ << planner->get_task_name ( + planner->get_task_from_inst (clink.first)) << ") -"; + this->outfile_ << "(" << planner->get_cond_name (clink.cond.id) << ")-> "; + this->outfile_ << clink.second << " ("; + this->outfile_ << planner->get_task_name ( + planner->get_task_from_inst (clink.second)) << ")" << std::endl; + } + this->outfile_ << std::endl; } - this->outfile_ << std::endl; - - for (SchedLinkSet::iterator sched_iter = plan.sched_links.begin (); - sched_iter != plan.sched_links.end (); - sched_iter++) - { - SchedLink sched_link = (*sched_iter); - this->outfile_ << "Scheduling Link:" << std::endl; - this->outfile_ << " " << sched_link.first << " ("; - this->outfile_ << planner->get_task_name ( - planner->get_task_from_inst (sched_link.first)) << ") -> "; - this->outfile_ << sched_link.second << " ("; - this->outfile_ << planner->get_task_name ( - planner->get_task_from_inst (sched_link.second)) << ")" << std::endl; + if (plan.sched_links.size () > 0) { + this->outfile_ << "ALL Scheduling Links:" << std::endl; + for (SchedLinkSet::iterator sched_iter = plan.sched_links.begin (); + sched_iter != plan.sched_links.end (); + sched_iter++) + { + SchedLink sched_link = (*sched_iter); + this->outfile_ << " " << sched_link.first << " ("; + this->outfile_ << planner->get_task_name ( + planner->get_task_from_inst (sched_link.first)) << ") -> "; + this->outfile_ << sched_link.second << " ("; + this->outfile_ << planner->get_task_name ( + planner->get_task_from_inst (sched_link.second)) << ")" << std::endl; + + } + this->outfile_ << std::endl; } - this->outfile_ << std::endl; - - for (ThreatLinkSet::iterator threat_iter = plan.threat_links.begin (); - threat_iter != plan.threat_links.end (); - threat_iter++) - { - ThreatLink threat_link = (*threat_iter); - this->outfile_ << "Threat Link:" << std::endl; - this->outfile_ << " " << threat_link.first << " ("; - this->outfile_ << planner->get_task_name ( - planner->get_task_from_inst (threat_link.first)) << ") -> "; - this->outfile_ << threat_link.second << " ("; - this->outfile_ << planner->get_task_name ( - planner->get_task_from_inst (threat_link.second)) << ")" << std::endl; - + if (plan.threat_links.size () > 0) { + this->outfile_ << "ALL Threat Links:" << std::endl; + for (ThreatLinkSet::iterator threat_iter = plan.threat_links.begin (); + threat_iter != plan.threat_links.end (); + threat_iter++) + { + ThreatLink threat_link = (*threat_iter); + this->outfile_ << " " << threat_link.first << " ("; + this->outfile_ << planner->get_task_name ( + planner->get_task_from_inst (threat_link.first)) << ") -> "; + this->outfile_ << threat_link.second << " ("; + this->outfile_ << planner->get_task_name ( + planner->get_task_from_inst (threat_link.second)) << ")" << std::endl; + + } + this->outfile_ << std::endl; } - - this->outfile_ << std::endl; }; diff --git a/SA_POP/SANet/SANet.cpp b/SA_POP/SANet/SANet.cpp index ffa09d5f29a..e68cd6692a0 100644 --- a/SA_POP/SANet/SANet.cpp +++ b/SA_POP/SANet/SANet.cpp @@ -564,6 +564,15 @@ void SANet::Network::update_cond_val (CondID cond_id, Probability true_prob) iter->second->set_init_prob (true_prob); }; +// Update a set of conditions' current (init) value (probability of being true). +void SANet::Network::update_conds_val (CondSet conds) +{ + for (CondSet::iterator cond_iter = conds.begin (); cond_iter != conds.end (); cond_iter++) { + this->update_cond_val ((*cond_iter).id, (*cond_iter).value); + } +}; + + // Update a condition's (goal) utility. void SANet::Network::update_cond_util (CondID cond_id, Utility utility) { @@ -630,6 +639,55 @@ const GoalMap& SANet::Network::get_goals (void) return this->goals_; }; +// Get the number of conditions in the network. +size_t SANet::Network::get_num_conds (void) +{ + return this->cond_nodes_.size (); +}; + +// Get all conditions in the network. +CondSet SANet::Network::get_all_conds (void) +{ + CondSet conds; + conds.clear (); + + // Create set of all condition nodes. + for (CondNodeMap::iterator node_iter = cond_nodes_.begin (); + node_iter != cond_nodes_.end (); node_iter++) + { + Condition cur_cond; + cur_cond.id = node_iter->second->get_ID (); + cur_cond.kind = node_iter->second->get_cond_kind (); + cur_cond.value = node_iter->second->get_init_prob (); + + conds.insert (cur_cond); + } + + return conds; +}; + +// Get the number of tasks in the network. +size_t SANet::Network::get_num_tasks (void) +{ + return this->task_nodes_.size (); +}; + +// Get all tasks in the network. +TaskSet SANet::Network::get_all_tasks (void) +{ + TaskSet tasks; + tasks.clear (); + + // Create set of all taskition nodes. + for (TaskNodeMap::iterator node_iter = task_nodes_.begin (); + node_iter != task_nodes_.end (); node_iter++) + { + tasks.insert (node_iter->second->get_ID ()); + } + + return tasks; +}; + // Get a task's name. std::string SANet::Network::get_task_name (TaskID task_id) { diff --git a/SA_POP/SANet/SANet.h b/SA_POP/SANet/SANet.h index d0bbc5fe4aa..130b6806fc9 100644 --- a/SA_POP/SANet/SANet.h +++ b/SA_POP/SANet/SANet.h @@ -198,7 +198,7 @@ namespace SANet { /// changed after construction. virtual void reset_sa (void); - /// Update a condition's current value (probability of being true). + /// Update a condition's current (init) value (probability of being true). /** * @param cond_id The condition id. * @@ -206,6 +206,12 @@ namespace SANet { */ virtual void update_cond_val (CondID cond_id, Probability true_prob); + /// Update a set of conditions' current (init) value (probability of being true). + /** + * @param true_prob Set of conditions with each including the value to set for current/init value. + */ + virtual void update_conds_val (CondSet conds); + /// Update a condition's (goal) utility. /** * @param cond_id The condition id. @@ -273,6 +279,30 @@ namespace SANet { // General task/condition accessor methods. // ************************************************************************ + /// Get the number of conditions in the network. + /** + * @return Number of conditions in the network. + */ + virtual size_t get_num_conds (void); + + /// Get all conditions in the network. + /** + * @return Set of all conditions in the network. + */ + virtual CondSet get_all_conds (void); + + /// Get the number of tasks in the network. + /** + * @return Number of tasks in the network. + */ + virtual size_t get_num_tasks (void); + + /// Get all tasks in the network. + /** + * @return Set of all tasks (as IDs) in the network. + */ + virtual TaskSet get_all_tasks (void); + /// Get a task's name. /** * @param task_id The task id. diff --git a/SA_POP/experiments/EU_Performance/Exp_Core/Exp_EU_Planner.cpp b/SA_POP/experiments/EU_Performance/Exp_Core/Exp_EU_Planner.cpp index 5ed043c55b8..13849e831b1 100644 --- a/SA_POP/experiments/EU_Performance/Exp_Core/Exp_EU_Planner.cpp +++ b/SA_POP/experiments/EU_Performance/Exp_Core/Exp_EU_Planner.cpp @@ -21,6 +21,13 @@ #include <fstream> #include <sstream> +#include "boost/random.hpp" +#include <boost/accumulators/accumulators.hpp> +#include <boost/accumulators/statistics/stats.hpp> +#include <boost/accumulators/statistics/mean.hpp> +#include <boost/accumulators/statistics/variance.hpp> + + #include "SA_POP_Types.h" #include "Exp_EU_Planner.h" @@ -38,19 +45,57 @@ using namespace SA_POP; Exp_EU_Planner::Exp_EU_Planner (void) :do_pause_ (false), input_ (0), - ques_ (0) + ques_ (0), + do_stats_out_ (false), + trial_num_plans_ (0), + run_num_trial_attempts_ (0), + run_num_init_plans_ (0), + run_num_pref_plans_ (0), + run_num_alt_plans_ (0), + pref_plan_eu_ (0.0), + max_plan_eu_ (0.0) { - // All initialization handled by Planner base class constructor. +// std::ofstream log_trials_out_; +// std::ofstream log_runs_out_; + + // All other initialization handled by Planner base class constructor. }; /// Destructor. Exp_EU_Planner::~Exp_EU_Planner (void) { + // Close output files, if necessary. + if (this->log_trials_out_ != 0){ + if (this->log_trials_out_.is_open ()) + this->log_trials_out_.close (); + } + if (this->log_runs_out_ != 0){ + if (this->log_runs_out_.is_open ()) + this->log_runs_out_.close (); + } + // All deletion handled by Planner base class destructor. -} +}; +// Reset all planning statistics for an individual trial. +void Exp_EU_Planner::reset_trial_stats (void) +{ + this->trial_num_plans_ = 0; + this->pref_plan_eu_ = 0.0; + this->max_plan_eu_ = 0.0; +}; + +// Reset all planning statistics for an individual experimental run. +void Exp_EU_Planner::reset_run_stats (void) +{ + this->run_num_trial_attempts_ = 0; + this->run_num_init_plans_ = 0; + this->run_num_pref_plans_ = 0; + this->run_num_alt_plans_ = 0; +}; + // Set to pause and ask user whether to continue after each plan is generated. void Exp_EU_Planner::set_pause (UserInterface::InputCL *input_cl, UserInterface::QuestionBool *ques) { @@ -65,26 +110,102 @@ void Exp_EU_Planner::unset_pause (void) this->do_pause_ = false; }; +// Run experiment planning. +void Exp_EU_Planner::exp_run (size_t sa_max_steps, std::string log_trials_filename, std::string log_runs_filename, size_t num_goal_conds, double percent_init_true, size_t util_min, size_t util_max, size_t max_trial_attempts, size_t num_trials, bool do_log_headers) +{ + // Set flag to output statistics to file. + this->do_stats_out_ = true; + + // Open/create trials output file if not already open. + if (this->log_trials_out_ != 0){ + if (!this->log_trials_out_.is_open ()) + this->log_trials_out_.open (log_trials_filename.c_str (), std::ios_base::out | std::ios_base::app); + } + if (this->log_trials_out_ == 0){ + std::string msg = "SA-POP ERROR: in Exp_EU_Planner::plan_exp(): Unable to open experiment trials log file ("; + msg += log_trials_filename; + msg += ") for writing (append)."; + std::cerr << msg; + throw msg; + } + + // Open/create runs output file if not already open. + if (this->log_runs_out_ != 0){ + if (!this->log_runs_out_.is_open ()) + this->log_runs_out_.open (log_runs_filename.c_str (), std::ios_base::out | std::ios_base::app); + } + if (this->log_runs_out_ == 0){ + std::string msg = "SA-POP ERROR: in Exp_EU_Planner::plan_exp(): Unable to open experiment runs log file ("; + msg += log_runs_filename; + msg += ") for writing (append)."; + std::cerr << msg; + throw msg; + } + + // Log headers if flag set. + if (do_log_headers) { + this->log_run_header (); + this->log_trial_header (); + } + + // Do experimental runs. + for (size_t trial_num = 0; trial_num < num_trials; trial_num++) { + // If maximum number of trial attempts have been reached, + // stop running trials. + if (this->run_num_trial_attempts_ >= max_trial_attempts) + break; + + // Initialize trial statistics. + this->reset_trial_stats (); + + // Initialize conditions and goal. + SA_POP::Goal goal = this->exp_init (num_goal_conds, percent_init_true, util_min, util_max); + + // Perform experimental run. + this->plan (sa_max_steps, goal); + + // Increment trial attempts counter. + this->run_num_trial_attempts_++; + + // Trial only valid if at least one alternate plan was generated. + if (this->trial_num_plans_ >= 3) { + // Log trial statistics to output file. + this->log_trial_stats (); + } else { + // For invalid trial, decrement trial counter. + trial_num--; + } + + } + + // Log run statistics to output file. + this->log_run_stats (); + + // Close output files. + this->log_trials_out_.close (); +}; + // Satisfy scheduling constraints in fully instantiated plan (no // recursive call backs). bool Exp_EU_Planner::full_sched () { if (this->sched_strat_->satisfy_full_sched ()) { + // Track statistics for the generated plan. this->plan_ = this->working_plan_->get_plan (); - this->notify_plan_changed (); - Utility plan_eu = this->calc_plan_eu (this->plan_); + this->track_stats (this->plan_); -// std::ostringstream eu_str; -// eu_str << "Plan EU: " << plan_eu << std::endl << std::endl; -// SA_POP_DEBUG_STR(SA_POP_DEBUG_QUIET, eu_str.str ()); + // Notify output adapters. + this->notify_plan_changed (); - // If pausing to ask user whether to continue, ask question - // and return true (so the current plan will be returned instead - // of continuing planning) if user replies "No" to continuation + // If pausing to ask user whether to continue, ask continuation // question. if (this->do_pause_) { this->input_->ask ((*this->ques_)); + + // Return true (so the current plan will be returned instead + // of continuing planning) only if user replies "No" to + // continuation question. if (!this->ques_->get_answer_bool ()) return true; } @@ -93,3 +214,232 @@ bool Exp_EU_Planner::full_sched () return false; }; +// Add plan to tracking statistics. +void Exp_EU_Planner::track_stats (SA_POP::Plan plan) +{ + // Update number of plans generated. + this->trial_num_plans_++; + + // Ignore first plan. + if (this->trial_num_plans_ <= 1) { + // First plan. + this->trial_num_plans_ = 1; + + // Increment counter of trials with initial plan. + this->run_num_init_plans_++; + + // Nothing else to do for first plan. + return; + } + + // Get plan EU. + SA_POP::Utility plan_eu = this->calc_plan_eu (plan); + + // Second plan is SA-POP preferred plan. + if (this->trial_num_plans_ == 2) { + // Current maximum plan EU is this (preferred) plan's EU. + this->pref_plan_eu_ = this->max_plan_eu_ = plan_eu; + + // Increment counter of trials with preferred plan. + this->run_num_pref_plans_++; + + // Nothing else to do for first plan. + return; + } + + // Third or more is an alternate plan. + + // If this is the first alternate plan (third plan generated), + // increment counter of trials with at least one alternate plan. + if (this->trial_num_plans_ == 3) { + this->run_num_alt_plans_++; + } + + // If this plan has a higher EU than current max, update max. + if (plan_eu > this->max_plan_eu_) + this->max_plan_eu_ = plan_eu; +}; + +// Initialize experiment (set values for initial conditions and create goal). +SA_POP::Goal Exp_EU_Planner::exp_init (size_t num_goal_conds, double percent_init_true, size_t util_min, size_t util_max) +{ + // Check goal utility min & max for consistency. + if (util_min > util_max) { + std::cerr << "SA-POP ERROR in Exp_EU_Planner::exp_init (): goal utility min is >= goal utility max"; + throw "SA-POP ERROR in Exp_EU_Planner::exp_init (): goal utility min is >= goal utility max"; + } + + + SA_POP::Goal goal; + goal.goal_id = "ExperimentGoalID"; + goal.name = "Experiment generated goal"; + goal.abs_times.clear (); + goal.rel_times.clear (); + goal.goal_conds.clear (); + goal.start_window = std::make_pair (0, 0); + + // Get all conditions. + SA_POP::CondSet conds = this->sanet_->get_all_conds (); + + // Check number of goal conditions for consistency. + if (num_goal_conds > conds.size ()) { + std::cerr << "SA-POP ERROR in Exp_EU_Planner::exp_init (): more goal conditions than number of goals"; + throw "SA-POP ERROR in Exp_EU_Planner::exp_init (): more goal conditions than number of goals"; + } + + // Initialize random number generators. + boost::uniform_int<> goal_choice_dist(0, conds.size () - 1); + boost::variate_generator<boost::mt19937&, boost::uniform_int<> > gen_goal_choice(this->rand_gen_, goal_choice_dist); + boost::uniform_int<> goal_util_dist(util_min, util_max); + boost::variate_generator<boost::mt19937&, boost::uniform_int<> > gen_goal_util(this->rand_gen_, goal_util_dist); + boost::uniform_real<> cond_init_dist(0.0, 1.0); + boost::variate_generator<boost::mt19937&, boost::uniform_real<> > gen_cond_init(this->rand_gen_, cond_init_dist); + + // Set goals. + std::set<SA_POP::CondID> goal_ids; + goal_ids.clear (); + for (size_t goal_ctr = 0; goal_ctr < num_goal_conds; goal_ctr++) { + // Choose goal condition number. + size_t goal_choice = gen_goal_choice (); + + // Get goal condition. + SA_POP::Condition goal_cond; + goal_cond.id = SA_POP::NULL_COND_ID; + size_t cond_count = 0; + for (SA_POP::CondSet::iterator cond_iter = conds.begin (); cond_iter != conds.end (); cond_iter++) { + if (cond_count == goal_choice) { + goal_cond = (*cond_iter); + break; + } + cond_count++; + } + + SA_POP::CondID goal_id = goal_cond.id; + + // Try again if this condition is already a goal condition. + if (goal_ids.find (goal_id) != goal_ids.end ()) { + goal_ctr--; + continue; + } + + // Choose goal utility. + SA_POP::Utility goal_util = gen_goal_util (); + + // Add goal condition. + goal.goal_conds.insert (std::make_pair (goal_id, goal_util)); + } + + // Reset all conditions to false. + for (CondSet::iterator cond_iter = conds.begin (); cond_iter != conds.end (); cond_iter++) { + cond_iter->value = 0.0; + } + this->sanet_->update_conds_val (conds); + + // Set initial conditions. + for (SA_POP::CondSet::iterator cond_iter = conds.begin (); cond_iter != conds.end (); cond_iter++) { + // Skip goal conditions. + if (goal_ids.find ((*cond_iter).id) != goal_ids.end ()) + continue; + + // Randomly determine whether to set condition to true. + double init_check = gen_cond_init (); + if (init_check <= percent_init_true) { + this->sanet_->update_cond_val ((*cond_iter).id, true); + } + } + + + return goal; +}; + +// Output trial header to log. +void Exp_EU_Planner::log_trial_header (void) +{ + // Only log header if flag is set. + if (!this->do_stats_out_) + return; + + // Throw error if log filestream is null or log file is not open. + if (this->log_trials_out_ == 0 || !this->log_trials_out_.is_open ()) { + std::string msg = "SA-POP ERROR: in Exp_EU_Planner::log_trial_header(): Experimental trials log file is not open."; + std::cerr << msg; + throw msg; + } + + // Output trial header to file. + this->log_trials_out_ << "Preferred plan EU" << "\t"; + this->log_trials_out_ << "Maximum plan EU" << "\t"; + this->log_trials_out_ << "Number of alternate plans"; + this->log_trials_out_ << std::endl; + +}; + +// Output trial statistics to log. +void Exp_EU_Planner::log_trial_stats (void) +{ + // Only log statistics if flag is set. + if (!this->do_stats_out_) + return; + + // Throw error if log filestream is null or log file is not open. + if (this->log_trials_out_ == 0 || !this->log_trials_out_.is_open ()) { + std::string msg = "SA-POP ERROR: in Exp_EU_Planner::log_trial_stats(): Experimental trials log file is not open."; + std::cerr << msg; + throw msg; + } + + // Output trial statistics to file. + this->log_trials_out_ << this->pref_plan_eu_ << "\t"; + this->log_trials_out_ << this->max_plan_eu_ << "\t"; + this->log_trials_out_ << (this->trial_num_plans_ - 2); + this->log_trials_out_ << std::endl; + +}; + +// Output run header to log. +void Exp_EU_Planner::log_run_header (void) +{ + // Only log statistics if flag is set. + if (!this->do_stats_out_) + return; + + // Throw error if log filestream is null or log file is not open. + if (this->log_runs_out_ == 0 || !this->log_runs_out_.is_open ()) { + std::string msg = "SA-POP ERROR: in Exp_EU_Planner::log_run_header(): Experimental runs log file is not open."; + std::cerr << msg; + throw msg; + } + + // Output run header to file. + this->log_runs_out_ << "Trial attempts" << "\t"; + this->log_runs_out_ << "Trials w/ initial plan" << "\t"; + this->log_runs_out_ << "Trials w/ preferred plan" << "\t"; + this->log_runs_out_ << "Trials w/ alternate plan(s)"; + this->log_runs_out_ << std::endl; +}; + +// Output run statistics to log. +void Exp_EU_Planner::log_run_stats (void) +{ + // Only log statistics if flag is set. + if (!this->do_stats_out_) + return; + + // Throw error if log filestream is null or log file is not open. + if (this->log_runs_out_ == 0 || !this->log_runs_out_.is_open ()) { + std::string msg = "SA-POP ERROR: in Exp_EU_Planner::log_run_stats(): Experimental runs log file is not open."; + std::cerr << msg; + throw msg; + } + + // Output run statistics to file. + this->log_runs_out_ << this->run_num_trial_attempts_ << "\t"; + this->log_runs_out_ << this->run_num_init_plans_ << "\t"; + this->log_runs_out_ << this->run_num_pref_plans_ << "\t"; + this->log_runs_out_ << this->run_num_alt_plans_; + this->log_runs_out_ << std::endl; +}; + + + + diff --git a/SA_POP/experiments/EU_Performance/Exp_Core/Exp_EU_Planner.h b/SA_POP/experiments/EU_Performance/Exp_Core/Exp_EU_Planner.h index 3e6e3d5b06a..b935983b95d 100644 --- a/SA_POP/experiments/EU_Performance/Exp_Core/Exp_EU_Planner.h +++ b/SA_POP/experiments/EU_Performance/Exp_Core/Exp_EU_Planner.h @@ -21,11 +21,12 @@ #include <string> #include <set> #include <map> +#include <fstream> -#include "SA_POP_Types.h" +#include <boost/random.hpp> +#include "SA_POP_Types.h" #include "Planner.h" - #include "InputCL.h" //#include "PlanStrategy.h" @@ -70,18 +71,32 @@ namespace SA_POP { // Planning/re-planning methods. // ************************************************************************ - /// Run experiment planning. + /// Perform experimental trial(s). /** * @param sa_max_steps Maximum steps to run spreading activation. * - * @param goal Goal for which to plan. + * @param log_trials_filename Name of file to output trial statistics to. + * + * @param log_runs_filename Name of file to output cumulative statistics from run to. + * + * @param num_goal_conds Number of goal conditions to generate. * - * @param pause True to pause after next plan is generated or - * false to find all remaining plans. + * @param percent_init_true Percentage of conditions to set initial value to true. * - * @return True if plan generated, false otherwise. + * @param util_min Minimum goal utility (uniform random choice in range [util_min, util_max]). + * + * @param util_max Maximum goal utility (uniform random choice in range [util_min, util_max]). + * + * @param max_trial_attempts Maximum number of trial attempts to execute in order to reach assigned number of valid trials. + * + * @param num_trials Number of valid trials to attempt to achieve (each with randomly chosen initial conditions and goal). + * + * @param do_log_headers Flag to output header lines to log files (if true). */ -// virtual bool plan_exp (size_t sa_max_steps, SA_POP::Goal goal, bool pause = false); + virtual void exp_run (size_t sa_max_steps, std::string log_trials_filename, + std::string log_runs_filename, size_t num_goal_conds, double percent_init_true, + size_t util_min, size_t util_max, size_t max_trial_attempts, + size_t num_trials = 1, bool do_log_headers = false); // ************************************************************************ @@ -96,6 +111,9 @@ namespace SA_POP { virtual bool full_sched (); protected: + // Random number generator. + boost::mt19937 rand_gen_; + /// Flag for whether to pause for user input after each plan is generated. bool do_pause_; @@ -104,6 +122,77 @@ namespace SA_POP { /// Question to ask user whether to continue after each plan is generated. UserInterface::QuestionBool *ques_; + + /// Flag for whether to output statistics to files. + bool do_stats_out_; + + /// Output file stream for logging trial statistics. + std::ofstream log_trials_out_; + + /// Output file stream for logging trial statistics. + std::ofstream log_runs_out_; + + /// Trial counter for number of plans generated. + size_t trial_num_plans_; + + /// Run counter for number of trial attempts. + size_t run_num_trial_attempts_; + + /// Run counter for number of trials with initial plan generated. + size_t run_num_init_plans_; + + /// Run counter for number of trials with preferred plan generated. + size_t run_num_pref_plans_; + + /// Run counter for number of trials with at least one alternate plan generated. + size_t run_num_alt_plans_; + + /// Expected utility of SA-POP preferred plan. + SA_POP::Utility pref_plan_eu_; + + /// Highest expected utility of any (schedulable/valid) plan (including preferred plan). + SA_POP::Utility max_plan_eu_; + + + // ************************************************************************ + // Internal helper methods. + // ************************************************************************ + + /// Reset all planning statistics for an individual trial. + virtual void reset_trial_stats (void); + + /// Reset all planning statistics for an individual experimental run. + virtual void reset_run_stats (void); + + /// Add plan to tracking statistics. + virtual void track_stats (SA_POP::Plan plan); + + /// Output trial header to log. + virtual void log_trial_header (void); + + /// Output trial statistics to log. + virtual void log_trial_stats (void); + + /// Output run statistics to log. + virtual void log_run_stats (void); + + /// Output run header to log. + virtual void log_run_header (void); + + /// Initialize experiment (set values for initial conditions and + /// create goal). + /** + * @param num_goal_conds Number of goal conditions to generate. + * + * @param percent_init_true Percentage of conditions to set initial value to true. + * + * @param util_min Minimum goal utility (uniform random choice in range [util_min, util_max]). + * + * @param util_max Maximum goal utility (uniform random choice in range [util_min, util_max]). + * + * @return Goal to use in current experimental run. + */ + virtual SA_POP::Goal exp_init (size_t num_goal_conds, double percent_init_true, size_t util_min, size_t util_max); }; }; /* SA_POP namespace */ diff --git a/SA_POP/experiments/EU_Performance/SAPOP_Exp_EU.cpp b/SA_POP/experiments/EU_Performance/SAPOP_Exp_EU.cpp index 099d2b9480f..f18f9c908a0 100644 --- a/SA_POP/experiments/EU_Performance/SAPOP_Exp_EU.cpp +++ b/SA_POP/experiments/EU_Performance/SAPOP_Exp_EU.cpp @@ -46,6 +46,14 @@ namespace SA_POP { const size_t NumGoalsMax = 10; const size_t NumKnownCondsMin = 0; const size_t NumKnownCondsMax = 100; + const size_t NumTrialsMin = 1; + const size_t NumTrialsMax = 1000; + + // Default percentage of initial conditions to set as true (valid values: [0, 100]). + const size_t NumPercentCondsInit = 30; + + // Multiplier to determine max trial attempts from number of trials to achieve. + const size_t TrialAttemptsMult = 10; }; /* SA_POP::Default namespace */ }; /* SA_POP namespace */ @@ -135,6 +143,7 @@ int main (int argc, char* argv[]) SA_POP::TaskMapFileIn tm_in; SA_POP::Exp_EU_Planner *planner = 0; SA_POP::LogGraphOut graph_out (std::cout, false); + SA_POP::LogScreenOut screen_out (std::cout); UserInterface::InputCL user_input; std::string sanet_filename = ""; @@ -172,110 +181,202 @@ int main (int argc, char* argv[]) std::cerr << "UNKNOWN ERROR while building task network and task map from files." << std::endl; } - // Create empty goal. - SA_POP::Goal goal; - goal.goal_id = "UserSpecifiedGoal ID"; - goal.name = "User specified goal"; - goal.abs_times.clear (); - goal.rel_times.clear (); - goal.goal_conds.clear (); - goal.start_window = std::make_pair (0, 0); - - - // Get number of goal conditions. - size_t num_goals = 0; - UserInterface::QuestionInt num_goals_ques ("Number of goal conditions:", SA_POP::Default::NumGoalsMin, SA_POP::Default::NumGoalsMax); - if (user_input.ask (num_goals_ques)) - num_goals = num_goals_ques.get_answer_int (); - else { - std::cerr << "Invalid number of goals provided." << std::endl; - throw "Invalid number of goals provided."; - } + // Get SA-POP Planner. + planner = builder.get_exp_eu_planner (); - // Get condition ID and utility for each goal condition. - for(size_t g = 0; g < num_goals; g++) - { - SA_POP::CondID goal_id = 0; - SA_POP::Utility goal_util = 0; - UserInterface::QuestionInt goal_id_ques ("Goal condition ID:", SA_POP::Default::CondIDMin, SA_POP::Default::CondIDMax); - if (user_input.ask (goal_id_ques)) - goal_id = goal_id_ques.get_answer_int (); - else { - std::cerr << "No valid goal condition ID provided." << std::endl; - throw "No valid goal condition ID provided."; - } - UserInterface::QuestionInt goal_util_ques ("Goal utility:", SA_POP::Default::GoalUtilMin, SA_POP::Default::GoalUtilMax); - if (user_input.ask (goal_util_ques)) - goal_util = goal_util_ques.get_answer_int (); - else { - std::cerr << "No valid goal condition utility provided." << std::endl; - throw "No valid goal condition utility provided."; + // Run manual or automatic trial based on user input. + UserInterface::QuestionBool auto_trials_ques ("Automatic goal & initial condition generation? [(Y)es or (N)o]:", false); + user_input.ask (auto_trials_ques); + if (auto_trials_ques.get_answer_bool ()) { + // Get trial log filename. + std::string log_trials_filename = "default_trials_filename.log"; + UserInterface::Question log_trials_filename_ques ("Filename for trial log:"); + if (user_input.ask (log_trials_filename_ques)) + log_trials_filename = log_trials_filename_ques.get_answer (); + + // Get run log filename. + std::string log_runs_filename = "default_runs_filename.log"; + UserInterface::Question log_runs_filename_ques ("Filename for run log:"); + if (user_input.ask (log_runs_filename_ques)) + log_runs_filename = log_runs_filename_ques.get_answer (); + + // Get number of experimental trials to perform. + size_t num_trials = 1; + UserInterface::QuestionInt num_trials_ques ("Number of trials to run:", SA_POP::Default::NumTrialsMin, SA_POP::Default::NumTrialsMax); + if (user_input.ask (num_trials_ques)) + num_trials = num_trials_ques.get_answer_int (); + + // Get number of goal conditions. + size_t num_goals = 1; + UserInterface::QuestionInt num_goals_ques ("Number of goal conditions:", SA_POP::Default::NumGoalsMin, SA_POP::Default::NumGoalsMax); + if (user_input.ask (num_goals_ques)) + num_goals = num_goals_ques.get_answer_int (); + + // Get percent of initial conditions true. + size_t num_percent_conds_init = SA_POP::Default::NumPercentCondsInit; + UserInterface::QuestionInt conds_init_ques ("Percentage of initial conditions true [0 to 100]:", 0, 100); + if (user_input.ask (conds_init_ques)) + num_percent_conds_init = conds_init_ques.get_answer_int (); + double percent_conds_init = (double) num_percent_conds_init / 100.0; + + // Get min goal utility. + size_t min_util = 100; + UserInterface::QuestionInt min_util_ques ("Minimum goal utility:", SA_POP::Default::GoalUtilMin, SA_POP::Default::GoalUtilMax); + if (user_input.ask (min_util_ques)) + min_util = min_util_ques.get_answer_int (); + + // Get max goal utility. + size_t max_util = min_util; + UserInterface::QuestionInt max_util_ques ("Maximum goal utility:", min_util, SA_POP::Default::GoalUtilMax); + if (user_input.ask (max_util_ques)) + max_util = max_util_ques.get_answer_int (); + + // Get maximum steps of spreading activation from user. + UserInterface::QuestionInt steps_ques("Max steps to run spreading activation (10000 step limit): ", 0, 10000); + if (user_input.ask (steps_ques)) + max_steps = steps_ques.get_answer_int (); + + // Get whether to output log headers. + bool do_log_headers = false; + UserInterface::QuestionBool log_headers_ques ("Output headers in log files? [(Y)es or (N)o]:", false); + user_input.ask (log_headers_ques); + do_log_headers = log_headers_ques.get_answer_bool (); + + // Output plans to screen if user wishes. + UserInterface::QuestionBool screenout_ques ("Output plans to screen? [(Y)es or (N)o]:", false); + user_input.ask (screenout_ques); + if (screenout_ques.get_answer_bool ()) + planner->add_out_adapter (&screen_out); + + // Pause between plans if user wishes. + UserInterface::QuestionBool ques_cont_plan ("Continue planning to find next plan? [(Y)es or (N)o]:", false); + UserInterface::QuestionBool pause_ques ("Pause between plans? [(Y)es or (N)o]:", false); + user_input.ask (pause_ques); + if (pause_ques.get_answer_bool ()) { + // Set planner to ask whether continue after each plan is generated. + planner->set_pause (&user_input, &ques_cont_plan); + + // Output graphical plans if user wishes. + UserInterface::QuestionBool graphout_ques ("Output graphical plans? [(Y)es or (N)o]:", false); + user_input.ask (graphout_ques); + if (graphout_ques.get_answer_bool ()) + planner->add_out_adapter (&graph_out); } - goal.goal_conds.insert (std::make_pair (goal_id, goal_util)); - } - - // Get SA-POP Planner. - planner = builder.get_exp_eu_planner (); - // Get number of initial conditions to set (different from probability value in initial network from XML). - size_t num_known_conds = 0; - UserInterface::QuestionInt num_known_conds_ques ("Number of intial conditions to set:", SA_POP::Default::NumKnownCondsMin, SA_POP::Default::NumKnownCondsMax); - if (user_input.ask (num_known_conds_ques)) - num_known_conds = num_known_conds_ques.get_answer_int (); +//****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP + std::cout << "Experimental parameters:" << std::endl; + std::cout << " Max SA steps: " << max_steps << std::endl; + std::cout << " Num goals: " << num_goals << std::endl; + std::cout << " Percent init conds true: " << percent_conds_init << std::endl; + std::cout << " Goal min utility: " << min_util << std::endl; + std::cout << " Goal max utility: " << max_util << std::endl; +//****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP - // Set initial conditions. - for(size_t k = 0; k < num_known_conds; k++) - { - SA_POP::CondID cond_id = 0; - SA_POP::Probability cond_prob = 0; + // Run trials. + planner->exp_run (max_steps, log_trials_filename, log_runs_filename, num_goals, percent_conds_init, min_util, max_util, num_trials * SA_POP::Default::TrialAttemptsMult, num_trials, do_log_headers); + } else { + + // Create empty goal. + SA_POP::Goal goal; + goal.goal_id = "UserSpecifiedGoal ID"; + goal.name = "User specified goal"; + goal.abs_times.clear (); + goal.rel_times.clear (); + goal.goal_conds.clear (); + goal.start_window = std::make_pair (0, 0); + + + // Get number of goal conditions. + size_t num_goals = 0; + UserInterface::QuestionInt num_goals_ques ("Number of goal conditions:", SA_POP::Default::NumGoalsMin, SA_POP::Default::NumGoalsMax); + if (user_input.ask (num_goals_ques)) + num_goals = num_goals_ques.get_answer_int (); + else { + std::cerr << "Invalid number of goals provided." << std::endl; + throw "Invalid number of goals provided."; + } - UserInterface::QuestionInt cond_id_ques ("Initial condition ID:", SA_POP::Default::CondIDMin, SA_POP::Default::CondIDMax); - if (user_input.ask (cond_id_ques)) - cond_id = cond_id_ques.get_answer_int (); - else - break; + // Get condition ID and utility for each goal condition. + for(size_t g = 0; g < num_goals; g++) + { + SA_POP::CondID goal_id = 0; + SA_POP::Utility goal_util = 0; + UserInterface::QuestionInt goal_id_ques ("Goal condition ID:", SA_POP::Default::CondIDMin, SA_POP::Default::CondIDMax); + if (user_input.ask (goal_id_ques)) + goal_id = goal_id_ques.get_answer_int (); + else { + std::cerr << "No valid goal condition ID provided." << std::endl; + throw "No valid goal condition ID provided."; + } + UserInterface::QuestionInt goal_util_ques ("Goal utility:", SA_POP::Default::GoalUtilMin, SA_POP::Default::GoalUtilMax); + if (user_input.ask (goal_util_ques)) + goal_util = goal_util_ques.get_answer_int (); + else { + std::cerr << "No valid goal condition utility provided." << std::endl; + throw "No valid goal condition utility provided."; + } + goal.goal_conds.insert (std::make_pair (goal_id, goal_util)); + } + + + // Get number of initial conditions to set (different from probability value in initial network from XML). + size_t num_known_conds = 0; + UserInterface::QuestionInt num_known_conds_ques ("Number of intial conditions to set:", SA_POP::Default::NumKnownCondsMin, SA_POP::Default::NumKnownCondsMax); + if (user_input.ask (num_known_conds_ques)) + num_known_conds = num_known_conds_ques.get_answer_int (); + + // Set initial conditions. + for(size_t k = 0; k < num_known_conds; k++) + { + SA_POP::CondID cond_id = 0; + SA_POP::Probability cond_prob = 0; + + UserInterface::QuestionInt cond_id_ques ("Initial condition ID:", SA_POP::Default::CondIDMin, SA_POP::Default::CondIDMax); + if (user_input.ask (cond_id_ques)) + cond_id = cond_id_ques.get_answer_int (); + else + break; //****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP // TO DO: CREATE QuestionRange template class to replace QuestionInt and use one with a type of double for condition probability. - UserInterface::QuestionInt cond_prob_ques ("Initial condition probability (of true):", SA_POP::Default::CondProbMin, SA_POP::Default::CondProbMin); - if (user_input.ask (cond_prob_ques)) - cond_prob = cond_prob_ques.get_answer_int (); - else - break; + UserInterface::QuestionInt cond_prob_ques ("Initial condition probability (of true):", SA_POP::Default::CondProbMin, SA_POP::Default::CondProbMin); + if (user_input.ask (cond_prob_ques)) + cond_prob = cond_prob_ques.get_answer_int (); + else + break; //****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP****TEMP - // Update condition to provided value. - planner->update_cond_val (cond_id, cond_prob); + // Update condition to provided value. + planner->update_cond_val (cond_id, cond_prob); - // Add condition to known conditions list. - kconds.push_back(cond_id); - } + // Add condition to known conditions list. + kconds.push_back(cond_id); + } - // Get maximum steps of spreading activation from user. - UserInterface::QuestionInt steps_ques("Max steps to run (10000 step limit): ", 0, 10000); - if (user_input.ask (steps_ques)) - max_steps = steps_ques.get_answer_int (); + // Get maximum steps of spreading activation from user. + UserInterface::QuestionInt steps_ques("Max steps to run spreading activation (10000 step limit): ", 0, 10000); + if (user_input.ask (steps_ques)) + max_steps = steps_ques.get_answer_int (); - - //Configure the OutAdapters to use - SA_POP::LogScreenOut screen_out (std::cout); - planner->add_out_adapter (&screen_out); - planner->add_out_adapter (&graph_out); - //SA_POP::SchemaOut s_out (std::cout, kconds); - //planner->add_out_adapter (&s_out); + // Configure and add OutAdapters. + planner->add_out_adapter (&screen_out); + planner->add_out_adapter (&graph_out); + //SA_POP::SchemaOut s_out (std::cout, kconds); + //planner->add_out_adapter (&s_out); - // Set planner to ask whether continue after each plan is generated. - UserInterface::QuestionBool ques_cont_plan ("Continue planning to find next plan? [(Y)es or (N)o]:", false); - planner->set_pause (&user_input, &ques_cont_plan); + // Set planner to ask whether continue after each plan is generated. + UserInterface::QuestionBool ques_cont_plan ("Continue planning to find next plan? [(Y)es or (N)o]:", false); + planner->set_pause (&user_input, &ques_cont_plan); - // Run experiment. - planner->plan (max_steps, goal); + // Run experiment. + planner->plan (max_steps, goal); -// SA_POP::Plan plan = planner->get_plan (); -// SA_POP::Utility plan_eu = planner->calc_plan_eu (plan); -// std::cout << "Expected utility of generated plan: " << plan_eu << std::endl; +// SA_POP::Plan plan = planner->get_plan (); +// SA_POP::Utility plan_eu = planner->calc_plan_eu (plan); +// std::cout << "Expected utility of generated plan: " << plan_eu << std::endl; + } delete planner; |