important speed optimization of candidate action evaluation loop...

...ending candidate action evaluation loop if current score is
greater-or-equal than the upper bound of score for remaining candidate
actions
This commit is contained in:
Iurii Chernyi 2009-11-11 12:12:10 +00:00
parent b765c7308e
commit 58a415ec83
5 changed files with 69 additions and 15 deletions

View File

@ -19,54 +19,64 @@
[stage] [stage]
engine=cpp engine=cpp
name=testing_ai_default::candidate_action_evaluation_loop name=testing_ai_default::candidate_action_evaluation_loop
# [candidate_action] [candidate_action]
# engine=cpp engine=cpp
# name=testing_ai_default::goto_phase name=testing_ai_default::goto_phase
# score=200 max_score=200
# [/candidate_action] score=200
[/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::aspect_recruitment_phase name=testing_ai_default::aspect_recruitment_phase
max_score=100
score=100 score=100
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::move_leader_to_goals_phase name=testing_ai_default::move_leader_to_goals_phase
max_score=80
score=80 score=80
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::move_leader_to_keep_phase name=testing_ai_default::move_leader_to_keep_phase
max_score=70
score=70 score=70
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::combat_phase name=testing_ai_default::combat_phase
max_score=40
score=40 score=40
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::get_healing_phase name=testing_ai_default::get_healing_phase
max_score=30
score=30 score=30
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::get_villages_phase name=testing_ai_default::get_villages_phase
max_score=25
score=25 score=25
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::retreat_phase name=testing_ai_default::retreat_phase
max_score=20
score=20 score=20
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::default_move_to_targets_phase name=testing_ai_default::default_move_to_targets_phase
max_score=15
score=15 score=15
[/candidate_action] [/candidate_action]
# [candidate_action] # [candidate_action]
# engine=cpp # engine=cpp
# name=testing_ai_default::leader_control_phase # name=testing_ai_default::leader_control_phase
# max_score=0
# score=0 # score=0
# [/candidate_action] # [/candidate_action]
[/stage] [/stage]

View File

@ -21,54 +21,64 @@
[stage] [stage]
engine=cpp engine=cpp
name=testing_ai_default::candidate_action_evaluation_loop name=testing_ai_default::candidate_action_evaluation_loop
# [candidate_action] [candidate_action]
# engine=cpp engine=cpp
# name=testing_ai_default::goto_phase name=testing_ai_default::goto_phase
# score=200 max_score=200
# [/candidate_action] score=200
[/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::aspect_recruitment_phase name=testing_ai_default::aspect_recruitment_phase
max_score=100
score=100 score=100
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::move_leader_to_goals_phase name=testing_ai_default::move_leader_to_goals_phase
max_score=80
score=80 score=80
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::move_leader_to_keep_phase name=testing_ai_default::move_leader_to_keep_phase
max_score=70
score=70 score=70
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::combat_phase name=testing_ai_default::combat_phase
max_score=40
score=40 score=40
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::get_healing_phase name=testing_ai_default::get_healing_phase
max_score=30
score=30 score=30
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::get_villages_phase name=testing_ai_default::get_villages_phase
max_score=25
score=25 score=25
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::retreat_phase name=testing_ai_default::retreat_phase
max_score=20
score=20 score=20
[/candidate_action] [/candidate_action]
[candidate_action] [candidate_action]
engine=cpp engine=cpp
name=testing_ai_default::testing_move_to_targets_phase name=testing_ai_default::testing_move_to_targets_phase
max_score=15
score=15 score=15
[/candidate_action] [/candidate_action]
# [candidate_action] # [candidate_action]
# engine=cpp # engine=cpp
# name=testing_ai_default::leader_control_phase # name=testing_ai_default::leader_control_phase
# max_score=0
# score=0 # score=0
# [/candidate_action] # [/candidate_action]
[/stage] [/stage]

View File

@ -31,9 +31,10 @@ static lg::log_domain log_ai_composite_rca("ai/composite/rca");
#define ERR_AI_COMPOSITE_RCA LOG_STREAM(err, log_ai_composite_rca) #define ERR_AI_COMPOSITE_RCA LOG_STREAM(err, log_ai_composite_rca)
const double candidate_action::BAD_SCORE = 0; const double candidate_action::BAD_SCORE = 0;
const double candidate_action::HIGH_SCORE = 100000;
candidate_action::candidate_action(rca_context &context, const config &cfg) candidate_action::candidate_action(rca_context &context, const config &cfg)
: recursion_counter_(context.get_recursion_count()), enabled_(utils::string_bool(cfg["enabled"],true)), engine_(cfg["engine"]), score_(lexical_cast_default<double>(cfg["score"],BAD_SCORE)),name_(cfg["name"]),type_(cfg["type"]) : recursion_counter_(context.get_recursion_count()), enabled_(utils::string_bool(cfg["enabled"],true)), engine_(cfg["engine"]), score_(lexical_cast_default<double>(cfg["score"],BAD_SCORE)),max_score_(lexical_cast_default<double>(cfg["max_score"],HIGH_SCORE)),name_(cfg["name"]),type_(cfg["type"])
{ {
init_rca_context_proxy(context); init_rca_context_proxy(context);
} }
@ -71,6 +72,12 @@ double candidate_action::get_score() const
} }
double candidate_action::get_max_score() const
{
return max_score_;
}
const std::string& candidate_action::get_name() const const std::string& candidate_action::get_name() const
{ {
return name_; return name_;
@ -90,6 +97,7 @@ config candidate_action::to_config() const
cfg["engine"] = engine_; cfg["engine"] = engine_;
cfg["name"] = name_; cfg["name"] = name_;
cfg["score"] = lexical_cast<std::string>(score_); cfg["score"] = lexical_cast<std::string>(score_);
cfg["max_score"] = lexical_cast<std::string>(max_score_);
cfg["type"] = type_; cfg["type"] = type_;
return cfg; return cfg;
} }

View File

@ -44,6 +44,9 @@ public:
//this is a score guaranteed to be <=0, thus candidate action with this score will not be selected for execution //this is a score guaranteed to be <=0, thus candidate action with this score will not be selected for execution
static const double BAD_SCORE; static const double BAD_SCORE;
//this is a score guaranteed to be very high, higher than any 'normal' candidate action score
static const double HIGH_SCORE;
/** /**
* Constructor * Constructor
* @param ai context of the candidate action * @param ai context of the candidate action
@ -87,10 +90,16 @@ public:
void disable(); void disable();
/** /**
* Get the last score of the candidate action without re-evaluation * Get the usual score of the candidate action without re-evaluation
*/ */
double get_score() const; double get_score() const;
/**
* Get the upper bound of the score of the candidate action without re-evaluation
*/
double get_max_score() const;
/** /**
* Get the name of the candidate action (useful for debug purposes) * Get the name of the candidate action (useful for debug purposes)
*/ */
@ -120,6 +129,8 @@ private:
double score_; double score_;
double max_score_;
std::string name_; std::string name_;
std::string type_; std::string type_;

View File

@ -56,15 +56,26 @@ config candidate_action_evaluation_loop::to_config() const
return cfg; return cfg;
} }
class desc_sorter_of_candidate_actions {
public:
bool operator()(const candidate_action_ptr &a, const candidate_action_ptr &b)
{
return a->get_max_score() > b->get_max_score();
}
};
bool candidate_action_evaluation_loop::do_play_stage() bool candidate_action_evaluation_loop::do_play_stage()
{ {
LOG_AI_TESTING_RCA_DEFAULT << "Starting candidate action evaluation loop for side "<< get_side() << std::endl; LOG_AI_TESTING_RCA_DEFAULT << "Starting candidate action evaluation loop for side "<< get_side() << std::endl;
const static double STOP_VALUE = 0;
foreach(candidate_action_ptr ca, candidate_actions_){ foreach(candidate_action_ptr ca, candidate_actions_){
ca->enable(); ca->enable();
} }
//sort candidate actions by max_score DESC
std::sort(candidate_actions_.begin(),candidate_actions_.end(),desc_sorter_of_candidate_actions());
bool executed = false; bool executed = false;
bool gamestate_changed = false; bool gamestate_changed = false;
do { do {
@ -79,9 +90,13 @@ bool candidate_action_evaluation_loop::do_play_stage()
continue; continue;
} }
double score = STOP_VALUE; if (ca_ptr->get_max_score()<=best_score) {
DBG_AI_TESTING_RCA_DEFAULT << "Ending candidate action evaluation loop because current score "<<best_score<<" is greater than the upper bound of score for remaining candidate actions "<< ca_ptr->get_max_score()<< std::endl;
break;
}
DBG_AI_TESTING_RCA_DEFAULT << "Evaluating candidate action: "<< *ca_ptr << std::endl; DBG_AI_TESTING_RCA_DEFAULT << "Evaluating candidate action: "<< *ca_ptr << std::endl;
score = ca_ptr->evaluate(); double score = ca_ptr->evaluate();
DBG_AI_TESTING_RCA_DEFAULT << "Evaluated candidate action to score "<< score << " : " << *ca_ptr << std::endl; DBG_AI_TESTING_RCA_DEFAULT << "Evaluated candidate action to score "<< score << " : " << *ca_ptr << std::endl;
if (score>best_score) { if (score>best_score) {