📄 aiphighhope.cpp
字号:
ss->m_g_cmp_bsf = ss->m_g_cmp_cur;
ss->m_g_usr_bsf = ss->m_g_usr_cur;
ss->m_num_tries_to_best = ss->m_i_try + 1;
take_msg(&msg_this_is_bsf);
ss->m_tries_since_bsf_count = 0;
} else {
ss->m_tries_since_bsf_count++;
if (ss->m_tries_since_bsf_count > many_tries_since_bsf()) {
take_msg(&msg_no_recent_bsf);
ss->m_tries_since_bsf_count = 0;
ss->m_tries_since_change_count = 0; // reset this count
ss->m_tries_since_improve_count = 0; // reset this count
ss->m_is_many_since_new_best = 1;
}
}
if (ss->try_is_improvement()) {
ss->m_tries_since_improve_count = 0;
} else {
ss->m_tries_since_improve_count++;
if (ss->m_tries_since_improve_count >
many_tries_since_improve()) {
take_msg(&msg_no_recent_improve);
ss->m_tries_since_improve_count = 0;
ss->m_tries_since_change_count = 0; // reset this count
ss->m_tries_since_bsf_count = 0; // reset this count
ss->m_is_many_since_improve = 1;
}
}
if (ss->try_is_a_change() || !ss->try_is_a_success()) {
ss->m_tries_since_change_count = 0;
} else {
ss->m_tries_since_change_count++;
if (ss->m_tries_since_change_count >
many_tries_since_change()) {
take_msg(&msg_no_recent_change);
ss->m_tries_since_change_count = 0; // reset only this count
ss->m_is_many_since_change = 1;
}
}
if (should_log_tries()) log_this_try();
} // try loop end
take_msg(&msg_solve_has_ended);
return ss->m_g_usr_bsf; // best-so-far: goodness or miles, etc.
}
//----------------------------------------------------------------------
// try_to_find_solution - try to find a solution
void aipHHProblem::try_to_find_solution () {
aipHHSolveStat * ss = solve_stat();
ss->m_g_usr_cur = aipNeutral; // goodness or dollars or something
ss->m_is_too_bad = 0;
ss->m_is_many_since_new_best = 0;
ss->m_is_many_since_improve = 0;
ss->m_is_many_since_change = 0;
aipHHDecision *decision;
while ( 1 ) {
decision = next_decision();
if (!decision) break;
aipHHOption *opt = decision->hh_decide();
note_decide (decision, opt);
if (!opt) {
ss->m_failed_decision = decision;
break;
}
ss->m_g_cmp_cur += opt->g_opt_cmp();
ss->m_g_usr_cur += opt->g_opt_usr();
if ( ss->m_g_cmp_cur.is_forbidden() ) break;
if ( ss->m_g_cmp_cur < too_bad_to_go_on() ) {
ss->m_is_too_bad = 1;
break;
}
ss->m_num_decisions_made++;
if ( !opt->g_opt_cmp().is_forbidden() &&
opt->g_opt_cmp() < ss->m_worst_decision_g_cmp ) {
ss->m_worst_decision = decision;
ss->m_worst_decision_g_cmp = opt->g_opt_cmp();
}
if ( solution_is_complete() ) break;
} // end of loop through decisions
if (ss->m_problem && ss->m_problem->worst_is_extra_bad() &&
!ss->m_worst_decision_g_cmp.is_forbidden() ) {
ss->m_g_cmp_cur += (ss->m_worst_decision_g_cmp +
ss->m_worst_decision_g_cmp);
}
if ( solution_is_complete() ) {
ss->m_solution_is_complete = 1;
ss->m_solution_is_new_best = ss->m_g_cmp_cur > ss->m_g_cmp_bsf;
} else {
ss->m_solution_is_complete = 0;
ss->m_solution_is_new_best = 0;
ss->m_g_cmp_cur = ss->m_g_usr_cur = aipForbidden;
}
ss->m_try_result = 0;
if (ss->try_is_new_best()) {
ss->m_try_result = HH_Try_Is_New_Best;
} else if (ss->try_is_a_best()) {
ss->m_try_result = HH_Try_Is_A_Best;
} else if (ss->try_is_improvement()) {
ss->m_try_result = HH_Try_Is_Improved;
} else if (!ss->try_is_a_success()) {
ss->m_try_result = HH_Try_Has_Failed;
} else if (ss->try_is_a_change()) {
ss->m_try_result = HH_Try_Is_Changed;
} else {
ss->m_try_result = HH_Try_Is_Complete;
}
}
//----------------------------------------------------------------------
// next_decision - the next decision to be decided (or zero)
//
// Return zero if there are no unmade decisions with hope better
// than aipForbidden. Otherwise, choose the unmade decision with
// the highest importance.
aipHHDecision * aipHHProblem::next_decision() {
aipHHDecision *dnext = 0;
long imp_max = -9999999;
aipHHDecisionItr itr = hh_decision_iterator();
for ( aipHHDecision *d = itr.first(); d; d = itr.next() ) {
if ( d && !(d->is_decided()) ) {
if (!dnext || dnext->imp() > imp_max) {
dnext = d;
imp_max = dnext->imp();
}
}
}
return dnext;
}
//----------------------------------------------------------------------
// solution_is_complete - true if solution is complete
//
// By default, a solution is complete when all decisions have
// been decided; subclasses may override this.
int aipHHProblem::solution_is_complete () const {
int done = m_solve_stat->m_num_decisions_made >= num_decisions();
return done;
}
//======================================================================
// aipHHDecision
//
//----------------------------------------------------------------------
// Constructor
aipHHDecision::aipHHDecision (long the_num_to_decide) {
m_hope = new aipHHHope;
m_opt_cur = m_opt_bsf = 0;
m_num_to_decide = the_num_to_decide;
m_num_decided = 0;
m_chsn_opts_cur = m_chsn_opts_bsf = 0;
}
//----------------------------------------------------------------------
// Destructor
aipHHDecision::~aipHHDecision () {
if (m_hope) delete m_hope;
if (m_chsn_opts_cur) delete m_chsn_opts_cur;
if (m_chsn_opts_bsf) delete m_chsn_opts_bsf;
}
//----------------------------------------------------------------------
// add_hh_option
void aipHHDecision::add_hh_option(aipHHOption *x) {
aipDecision::add_option(x);
if ( num_to_decide() > 1 ) x->set_is_shared();
}
//----------------------------------------------------------------------
// take_msg - take and react to a message
void aipHHDecision::take_msg (aipMsg *mm) {
aipHHMsg *m = (aipHHMsg *)mm;
if (m->typ() == HH_Starting_New_Try) {
m_opt_cur = 0;
m_num_decided = 0;
if (m_chsn_opts_cur) delete m_chsn_opts_cur;
m_chsn_opts_cur = new aipPandemonium;
} else if (m->typ() == HH_Try_Has_Ended) {
int dcsn_in_cur_solution = opt_cur() ? 1 : 0;
m->set_is_in_cur_solution(dcsn_in_cur_solution);
aipHHSolveStat *ss = m->prob() ? m->prob()->solve_stat() : 0;
int is_the_failure = ss ? ss->failed_dcsn() == this : 0;
m->set_is_the_failure(is_the_failure);
} else if (m->typ() == HH_This_Is_Best_So_Far) {
if (is_decided()) { // ie. dcsn is in the solution
m_opt_bsf = m_opt_cur;
if (m_chsn_opts_bsf) delete m_chsn_opts_bsf;
m_chsn_opts_bsf = m_chsn_opts_cur;
m_chsn_opts_cur = 0; // so bsf does not get deleted
}
}
m_importance.take_msg(mm);
if (m_hope) m_hope->take_msg(mm);
aipDecision::take_msg(mm); // decision gives message to options
}
//----------------------------------------------------------------------
// hh_option_iterator
aipHHOptionItr aipHHDecision::hh_option_iterator () const {
aipHHOptionItr i(option_pandemonium());
return i;
}
//----------------------------------------------------------------------
// current-option iterator
aipHHOptionItr aipHHDecision::cur_opt_iterator () const {
aipHHOptionItr i(m_chsn_opts_cur);
return i;
}
//----------------------------------------------------------------------
// best-so-far-option iterator
aipHHOptionItr aipHHDecision::bsf_opt_iterator () const {
aipHHOptionItr i(m_chsn_opts_bsf);
return i;
}
//----------------------------------------------------------------------
// g_hope
aipG aipHHDecision::g_hope () const {
return (m_hope ? m_hope->g() : aipNeutral);
}
//----------------------------------------------------------------------
// is_decided
int aipHHDecision::is_decided () const {
return (m_num_decided >= m_num_to_decide) ? 1 : 0;
}
//----------------------------------------------------------------------
// Return the number of unchosen, unforbidden options
long aipHHDecision::num_opt_remaining () const {
long num = 0;
aipHHOptionItr itr = hh_option_iterator();
for ( aipHHOption * opt = itr.first(); opt; opt = itr.next() ) {
if ( !(opt->is_chosen()) &&
!(opt->g_opt_cmp().is_forbidden()) ) num++;
}
return num;
}
//----------------------------------------------------------------------
// decide
aipHHOption * aipHHDecision::hh_decide() {
m_opt_cur = (aipHHOption*)decide();
if (m_opt_cur) {
if (m_chsn_opts_cur) m_chsn_opts_cur->add(m_opt_cur);
m_num_decided++;
}
return m_opt_cur;
}
//======================================================================
// aipHHOption - an option with an aipHHHope emotion
//
//----------------------------------------------------------------------
// Constructor
aipHHOption::aipHHOption (aipG g_user_const) {
m_g_user_constant = m_g_constant = g_user_const;
m_bsf_chooser = 0;
m_hope = new aipHHHope;
}
//----------------------------------------------------------------------
// Destructor
aipHHOption::~aipHHOption () {
if (m_hope) delete m_hope;
}
//----------------------------------------------------------------------
// take_msg - take and react to a message
void aipHHOption::take_msg (aipMsg *mm) {
aipHHMsg *m = (aipHHMsg *)mm;
int opt_in_cur_solution = hh_opt_chooser() != 0;
m->set_is_in_cur_solution(opt_in_cur_solution);
if (m_hope) m_hope->take_msg(mm);
if (m->typ() == HH_Starting_New_Try) {
reset_chooser();
} else if (m->typ() == HH_This_Is_Best_So_Far) {
m_bsf_chooser = hh_opt_chooser();
}
aipOption::take_msg(mm);
}
//----------------------------------------------------------------------
// g_hope
aipG aipHHOption::g_hope () const {
return (m_hope ? m_hope->g() : aipNeutral);
}
//----------------------------------------------------------------------
// g_opt
aipG aipHHOption::g_opt() {
return (g_constant() + g_hope() + random_num(-2,2));
}
//======================================================================
// aipHHDecisionItr - aipHHDecision iterator
//
// All function bodies are in the header file
//
//======================================================================
// aipHHOptionItr - aipHHOption iterator
//
// All function bodies are in the header file
//
//======================================================================
// aipHHSolveStat - solve() status and statistics
//
//----------------------------------------------------------------------
// Constructor
aipHHSolveStat::aipHHSolveStat (aipHHProblem *p) {
m_problem = p;
if (!p) return;
m_should_log_tries = p->should_log_tries();
m_g_cmp_cur = m_g_cmp_bsf = m_g_cmp_prev = aipForbidden;
m_g_usr_cur = m_g_usr_bsf = aipForbidden;
m_i_try = 0;
// The following assignments are not necessary, but just
// in case someone looks at this before calling solve()...
m_solution_is_complete = m_solution_is_new_best = 0;
m_num_decisions_made = m_num_decisions_prev = 0;
m_num_tries_to_best = 0;
m_failed_decision = 0;
m_worst_decision = 0;
m_worst_decision_g_cmp = aipForbidden;
m_tries_since_bsf_count = 0;
m_tries_since_improve_count = 0;
m_tries_since_change_count = 0;
m_is_too_bad = 0;
m_is_many_since_new_best = 0;
m_is_many_since_improve = m_is_many_since_change = 0;
}
//======================================================================
// aipHHMsg - High-Hope problem-solving message
//
//----------------------------------------------------------------------
// Constructor
aipHHMsg::aipHHMsg (aipHHProblem *p, short typ)
: aipMsg(typ) {
m_prob = p;
m_is_in_cur_solution = m_is_the_failure = 0;
}
//======================================================================
// License
//
// Permission is hereby granted, free of charge, to any
// person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to
// whom the Software is furnished to do so, subject to the
// following conditions:
//
// The copyright notice and this license shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
//
//**********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -