📄 aipreqres.cpp
字号:
//**********************************************************************
// aipReqRes.cpp - function bodies for aipReqRes.h
//
// Copyright (c) 2008 Brian Marshall
//
// See the license at end of this file.
//
// Developers/Contributers:
// [BRM] Brian Marshall - Calgary - bmarshal@agt.net
//
// 08/01/21 [BRM] began development: split out layer from rr_solve
//
//----------------------------------------------------------------------
#include "aipReqRes.h"
#include <string.h>
#include <iostream>
using namespace std;
//======================================================================
// aiprrReqImp - importance of a requirement
//
//----------------------------------------------------------------------
// take_msg - take and react to a message
void aiprrReqImp::take_msg (aipMsg *mm) {
aipHHImportance::take_msg(mm);
aiprrMsg *m = (aiprrMsg *)mm;
if (m->typ() == HH_Starting_New_Try) {
m_left_bhnd = 0;
}
}
//----------------------------------------------------------------------
// Note that a decision for this requirement has been decided.
void aiprrReqImp::note_aiprr_decide (aiprrDecision *d, aiprrOption *o) {
// o (ptr to an option) may be null
if (d && o) {
m_left_bhnd -= 1;
}
}
//======================================================================
// aiprrProblem
//
//----------------------------------------------------------------------
// Constructor
aiprrProblem::aiprrProblem () {
m_requirements = new aipPandemonium;
m_resources = new aipPandemonium;
m_should_log_options = 0;
}
//----------------------------------------------------------------------
// Destructor
aiprrProblem::~aiprrProblem () {
if (m_requirements) delete m_requirements;
if (m_resources) delete m_resources;
}
//----------------------------------------------------------------------
// add_requirement
void aiprrProblem::add_requirement (aiprrRequirement *x) {
if (!x) return;
m_requirements->add (x);
}
//----------------------------------------------------------------------
// add_resource
void aiprrProblem::add_resource (aiprrResource *x) {
if (!x) return;
m_resources->add (x);
}
//----------------------------------------------------------------------
// add_decision
void aiprrProblem::add_decision (aiprrDecision *x) {
add_hh_decision(x);
}
//----------------------------------------------------------------------
// In a try, choose the next decision to decide.
aipHHDecision * aiprrProblem::next_decision() {
aiprrReqDay *rd;
// <<<<< can make dcsn trivial (I think) but have to call hh decide function
// rd = trivial_reqday();
//cout << "** found a trivial reqday - forced exit\n"; ?????
//exit(1);
// if (rd) return rd->dcsn();
aiprrDecision * best_dcsn = 0;
long best_dcsn_imp = -999999999;
aiprrRequirementItr itr = requirement_iterator();
for ( aiprrRequirement * req = itr.first(); req; req = itr.next() ) {
rd = req->first_unsatisfied_reqday();
if (rd) {
aiprrDecision *dcsn = rd->dcsn();
if (dcsn) {
long dcsn_imp = dcsn->imp();
if (!best_dcsn || dcsn_imp > best_dcsn_imp) {
best_dcsn = dcsn;
best_dcsn_imp = dcsn_imp;
}
}
}
}
return best_dcsn;
}
//----------------------------------------------------------------------
// requirement_iterator - return an iterator: requirements in the problem
aiprrRequirementItr aiprrProblem::requirement_iterator() const {
aiprrRequirementItr i(m_requirements);
return i;
}
//----------------------------------------------------------------------
// resource_iterator - return an iterator: resources in the problem
aiprrResourceItr aiprrProblem::resource_iterator() const {
aiprrResourceItr i(m_resources);
return i;
}
//----------------------------------------------------------------------
// decision_iterator - return an iterator: decisions in the problem
aiprrDecisionItr aiprrProblem::decision_iterator() const {
aiprrDecisionItr i(decision_pandemonium());
return i;
}
//----------------------------------------------------------------------
// too_bad_to_go_on
aipG aiprrProblem::too_bad_to_go_on() const {
// aipHHSolveStat *ss = solve_stat();
// return ss->g_cmp_bsf().calc_fraction(3,2); from samp_a_to_b
return aipForbidden; // default from aipHHProblem
}
//----------------------------------------------------------------------
// log_this_try - to cout - for debugging or watching the thing work
//
// This works best if decisions are stored in Req,Day order
void aiprrProblem::log_this_try () {
aipHHSolveStat *ss = solve_stat();
cout << "\n===== Try " << ss->i_try()+1 << "...\n";
aiprrRequirement *req_prev = 0;
aipTime day_prev = aipTime(19010101);
aiprrDecisionItr itr = decision_iterator();
for ( aiprrDecision * dcsn = itr.first(); dcsn; dcsn = itr.next() ) {
aiprrReqDay *reqday = dcsn->reqday();
aiprrRequirement *req = reqday->req();
aipTime day = reqday->day();
aiprrOption *opt = dcsn->aiprr_opt_cur();
aiprrResource *res = opt ? opt->resday()->res() : 0;
if (req != req_prev) {
cout << "\nReq: " << req->id();
req_prev = req;
}
if (day != day_prev) {
char cday[21];
day.dd_mon_yyyy(cday);
cout << " Day: " << cday;
day_prev = day;
}
if (res) cout << " " << res->id();
}
cout << "\n";
cout << "-- Goodness of this try: "
<< ss->g_usr_cur().numeric_value()
<< " ";
if (ss->try_result() == HH_Try_Has_Failed) {
if (ss->is_too_bad()) cout << "(quit)";
} else if (ss->try_result() == HH_Try_Is_New_Best) {
cout << "(New Best)";
} else if (ss->try_result() == HH_Try_Is_A_Best) {
cout << "(a best)";
} else if (ss->try_result() == HH_Try_Is_Improved) {
cout << "(improved)";
} else if (ss->try_result() == HH_Try_Is_Changed) {
cout << "(changed)";
}
cout << "\n";
if (ss->is_many_since_new_best()) {
cout << " ... many tries since new best ...\n";
}
if (ss->is_many_since_improve()) {
cout << " ... many tries since improve ...\n";
}
if (ss->is_many_since_change()) {
cout << " ... many tries since change ...\n";
}
}
//----------------------------------------------------------------------
// take_msg
void aiprrProblem::take_msg (aipMsg *mm) {
aipHHProblem::take_msg(mm); // pass message to parent class
m_requirements->take_msg(mm);
m_resources->take_msg(mm);
}
//----------------------------------------------------------------------
// Note that a decision has been decided
void aiprrProblem::note_decide (aipHHDecision *dd, aipHHOption *oo) {
if (!dd) return;
aipHHProblem::note_decide (dd, oo);
aiprrDecision *d = (aiprrDecision*)dd;
aiprrOption *o = (aiprrOption*)oo;
aiprrReqDay *reqd = d->reqday();
if (!reqd) return;
aiprrRequirement *req = reqd->req();
if (!req) return;
req->note_aiprr_decide (d, o);
reqd->note_aiprr_decide (d, o);
if (o) { // if an option was chosen
aiprrResDay *resd = o->resday();
if (!resd) return;
aiprrResource *res = resd->res();
if (!res) return;
res->note_aiprr_decide (d, o);
resd->note_aiprr_decide (d, o);
}
}
//----------------------------------------------------------------------
// Return a requirement-day that has just enough options left, so we
// can decide the decisions the remaining number of times and
// for each decide, take the first available option.
//aiprrReqDay * aiprrProblem::trivial_reqday () const {
// aiprrReqDay *rd;
// aiprrRequirementItr itr = requirement_iterator();
// for ( aiprrRequirement *req = itr.first(); req; req = itr.next() ) {
// rd = req->trivial_reqday();
// if (rd) return rd;
// }
// return 0;
//}
//----------------------------------------------------------------------
// solve_rr_problem - solve a staffwhen staff scheduling problem
//
// return 1 (true) if a schedule is found, zero otherwise
int aiprrProblem::solve_rr_problem () {
aipG g = solve(); // high-hope solve
if (g.is_forbidden()) return 0;
return 1;
}
//======================================================================
// aiprrDecision
//
//----------------------------------------------------------------------
// Constructor
aiprrDecision::aiprrDecision (aiprrReqDay *a_reqday, long num_to_decide)
: aipHHDecision(num_to_decide) {
m_reqday = a_reqday;
}
//----------------------------------------------------------------------
// Destructor
aiprrDecision::~aiprrDecision () {}
//----------------------------------------------------------------------
// add_aiprr_option
void aiprrDecision::add_aiprr_option (aiprrOption *o) {
add_hh_option(o);
if ( o && o->resday() ) o->resday()->add_opt(o);
}
//----------------------------------------------------------------------
// Return the importance of this decision
long aiprrDecision::imp () const {
if (!m_reqday) return -999999;
aiprrRequirement *req = m_reqday->req();
if (!req) return -999999;
return aipHHDecision::imp() + req->imp() + m_reqday->imp();
}
//----------------------------------------------------------------------
// take_msg - take and react to a message
void aiprrDecision::take_msg (aipMsg *mm) {
aipHHDecision::take_msg(mm); // pass message to parent class
// aiprrMsg *m = (aiprrMsg *)mm;
// if (m->typ() == HH_Starting_New_Try) {
// reset_is_trivial();
// }
}
//======================================================================
// aiprrOption - an resource working a requirement on a day
//
//----------------------------------------------------------------------
// Constructor
aiprrOption::aiprrOption(aiprrResDay *a_resday, aipG g_static)
: aipHHOption(g_static) {
m_resday = a_resday;
m_g_dynamic = aipNeutral;
}
//----------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -