aiParts |
Free Open Source Artificial Intelligence C++ Parts |
|
Home Page Open Source Contact Us Free Downloads Releases and Credits Software Status License About rrproj assigning people and/or equipment to projects High-Hope Technique History of the AI View Source Files and how they are organized Making Programs Development Notes Using aiParts Your Application Support and Services |
aiParts Source File
//**********************************************************************
// aipReqRes.h - Requirement-Resource problems
//
// An aiprrProblem is a subclass of aipHHProblem.
// solve_rr_problem() uses the High-Hope technique.
// See aipHighHope.h
//
// A aiprrProblem has a set of decisions, each of which has a set
// of options.
//
// In this version, a Decision is associated with a Requirement-Day;
// an Option refers to a Resource that can satisfy it.
//
// Everything to do with a decision being trivial is commented out.
// It will be implemented in a later release.
//
// Copyright (c) 2008 Brian Marshall
//
// See the license at end of this file.
//
// Developers/Contributers:
// [BRM] Brian Marshall - Calgary - bmarshal@agt.net
//
// 08/01/20 [BRM] began development: split out layer from rr_solve
//
//----------------------------------------------------------------------
// The Data Model
//
// In this version, only Requirements have Decisions, which means
// that Resources always have an Option.
//
// [Problem]
// + [Requirements]
// | +
// v v
// v v
// [Decisions]<---+[Req-Days]
// v----o +
// v |
// [chosen_opts] | [Resources]
// ^ | +
// | v v
// | v v
// ----o[Options]<<--+[Res-Days]
//
// Notes:
// - Problems have Decisions, which have Options
// - Requirements and Resources may have a Decision
// - Decisions may be decided multiple times, so they have a list
// of chosen Options.
//
//----------------------------------------------------------------------
// Important Note
//
// In this file, the functions in aiprrOption:
// virtual aipG g_opt_cmp() { return g_user_constant() + m_g_dynamic; }
// virtual aipG g_opt_usr() { return g_user_constant() + m_g_dynamic; }
// override functions in the HighHope classes - g_dynamic affects
// making decisions, comparing solutions and the goodness that can
// be reported to the user.
//
// To solve a particular type of Requirement-Resource problem,
// you develop a set of sub-classes of aipReqRes classes and
// they call option.set_g_dynamic(aipG x) based on aspects of
// your particular problem.
//
//----------------------------------------------------------------------
#ifndef aipReqRes_h_guard
#define aipReqRes_h_guard
#include "aipHighHope.h"
#include "aipTime.h"
//----------------------------------------------------------------------
// Classes. Sub-classing is shown by indentation.
// class aipG is a typedef for aipGoodness
// class aipBase; ( in aipBase.h )
// class aipImportance; ( in aipImportance.h )
// class aipHHImportance; ( in aipHighHope.h )
class aiprrReqImp; // importance of a requirement
// class aipProblem; ( in aipProblem.h )
// class aipHHProblem; ( in aipHighHope.h )
class aiprrProblem; // rr-solve problem
// class aipDemon; ( in aipPandemonium.h )
// class aipDecision; ( in aipDecision.h )
// class aipHHDecision; ( in aipHighHope.h )
class aiprrDecision; // decision: for a requirement
// class aipOption; ( in aipDecision.h )
// class aipHHOption; ( in aipHighHope.h )
class aiprrOption; // option: a resource
class aiprrRequirement; // requirement to be satisfied
class aiprrReqDay; // requirement on a day
class aiprrResource; // resource to satisfy requirement
class aiprrResDay; // resource on a day
// class aipDemonItr; ( in aipPandemonium.h )
class aiprrRequirementItr; // requirement iterator
class aiprrReqDayItr; // requirement-day iterator
class aiprrResourceItr; // resource iterator
class aiprrResDayItr; // resource-day iterator
class aiprrDecisionItr; // decision iterator
// class aipMsg ( in aipBase.h )
class aiprrMsg; // message for rr-solve solving
//======================================================================
// aiprrReqImp - Importance of a position
class aiprrReqImp : public aipHHImportance {
long m_left_bhnd; // being left behind
public:
aiprrReqImp () { m_left_bhnd = 0; }
virtual ~aiprrReqImp () {}
virtual long val () const {
return aipHHImportance::val() + m_left_bhnd;
}
virtual void take_msg (aipMsg *m);
virtual void note_aiprr_decide (aiprrDecision *d, aiprrOption *o);
};
//======================================================================
// aiprrProblem - rrSolve problem - assigning resources to requirements
//
// solve_rr_problem () returns 1 (true) if a solution is found,
// zero otherwise.
//
// log_this_try() works best if decisions are stored in Req,Day order
class aiprrProblem : public aipHHProblem {
aipPandemonium * m_requirements;
aipPandemonium * m_resources;
int m_should_log_options; // 1 (true) = log to cout
protected:
virtual aipHHDecision * next_decision();
virtual aipG too_bad_to_go_on() const;
virtual void log_this_try (); // to cout
aipPandemonium * requirement_pandemonium () const { // for iterators
return m_requirements;
}
aipPandemonium * resource_pandemonium () const { // for iterators
return m_resources;
}
public:
aiprrProblem ();
virtual ~aiprrProblem ();
void set_num_try (long x) { aipHHProblem::set_num_try(x); }
void add_requirement (aiprrRequirement *x);
void add_resource (aiprrResource *x);
void add_decision (aiprrDecision *x);
void enable_log_options () { m_should_log_options = 1; }
void disable_log_options () { m_should_log_options = 0; }
int should_log_options () const { return m_should_log_options; }
aiprrRequirementItr requirement_iterator() const;
aiprrResourceItr resource_iterator() const;
aiprrDecisionItr decision_iterator() const;
virtual void take_msg (aipMsg *m);
virtual void note_decide (aipHHDecision *d, aipHHOption *o);
// aiprrReqDay * trivial_reqday () const;
virtual int solve_rr_problem (); // use this, not solve()
};
//======================================================================
// aiprrDecision - choosing a res for a reqday
//
// inherits: importance, a set of options, more
class aiprrDecision : public aipHHDecision {
aiprrReqDay * m_reqday; // reqday that needs resource-days
public:
aiprrDecision (aiprrReqDay *a_reqday, long num_to_decide =1);
virtual ~aiprrDecision();
// use this function, not add_hh_option
void add_aiprr_option (aiprrOption *x);
virtual void take_msg (aipMsg *m);
aiprrProblem * prob () const { return (aiprrProblem*)owner(); }
aiprrReqDay * reqday () const { return m_reqday; }
virtual long imp () const;
aiprrOption * aiprr_opt_cur () const {
return (aiprrOption*)opt_cur();
}
aiprrOption * aiprr_opt_bsf () const {
return (aiprrOption*)opt_bsf();
}
};
//======================================================================
// aiprrOption - a resource assigned to a requirement on a day
class aiprrOption : public aipHHOption {
aiprrResDay * m_resday; // the subject of this option
aipG m_g_dynamic; // g of situational aspects
public:
aiprrOption(aiprrResDay *a_resday, aipG g_constant);
virtual ~aiprrOption ();
virtual void take_msg (aipMsg *m);
void set_g_dynamic (aipG x);
void add_g_dynamic (aipG x);
aiprrDecision * aiprr_chooser () const {
return (aiprrDecision*)hh_opt_chooser();
}
aiprrResDay * resday () const { return m_resday; }
virtual aipG g_opt();
virtual aipG g_opt_cmp();
virtual aipG g_opt_usr();
};
//======================================================================
// aiprrRequirement - a requirement requiring resources
//
// A requirement is owned by a problem; it owns requirement-days.
class aiprrRequirement : public aipDemon {
long m_id;
aiprrProblem * m_prob;
aipPandemonium * m_reqdays;
aipHHHope * m_hope; // how well this requirement is doing
aiprrReqImp m_importance; // for choosing next decision
protected:
aipPandemonium * reqday_pandemonium () const { // for iterators
return m_reqdays;
}
public:
aiprrRequirement(long a_id, aiprrProblem *a_prob);
virtual ~aiprrRequirement();
void add_reqday (aiprrReqDay *x);
long imp () const { return m_importance.val(); }
virtual void take_msg (aipMsg *m);
virtual void note_aiprr_decide (aiprrDecision *d, aiprrOption *o);
int is_satisfied () const;
aiprrReqDay * first_unsatisfied_reqday () const;
// aiprrReqDay * trivial_reqday () const;
aiprrProblem * prob () const { return m_prob; }
long id () const { return m_id; }
aiprrReqDayItr reqday_iterator() const;
};
//======================================================================
// aiprrReqDay - a requirement on a day (requiring one or more resources)
//
// set_dcsn() must be called after the decision is created.
class aiprrReqDay : public aipDemon {
aiprrRequirement * m_req;
aipTime m_day;
aiprrDecision * m_dcsn;
aipHHHope * m_hope; // how well this reqday is doing
aipHHImportance m_importance;
public:
aiprrReqDay(aiprrRequirement *a_req, long a_yyyymmdd);
virtual ~aiprrReqDay();
void set_dcsn (aiprrDecision *a_dcsn) { m_dcsn = a_dcsn; }
long imp () const { return m_importance.val(); }
virtual void take_msg (aipMsg *m);
virtual void note_aiprr_decide (aiprrDecision *d, aiprrOption *o);
aipTime day () const { return m_day; }
aiprrRequirement * req () const { return m_req; }
aiprrDecision * dcsn () const { return m_dcsn; }
long num_decided () const { return m_dcsn->num_decided(); }
int is_satisfied () const;
int has_surplus_opts () const;
};
//======================================================================
// aiprrResource - a resource that can satisfy requirements
class aiprrResource : public aipDemon {
long m_id;
aiprrProblem * m_prob;
aipPandemonium * m_resdays;
aipHHHope * m_hope; // how well this resource is doing
int m_is_in_cur_solution;
protected:
aipPandemonium * resday_pandemonium () const { // for iterators
return m_resdays;
}
public:
aiprrResource(long a_id, aiprrProblem *a_prob);
virtual ~aiprrResource();
void add_resday (aiprrResDay *x);
virtual void take_msg (aipMsg *m);
virtual void note_aiprr_decide (aiprrDecision *d, aiprrOption *o);
aiprrProblem * prob () const { return m_prob; }
long id () const { return m_id; }
aiprrResDayItr resday_iterator() const;
};
//======================================================================
// aiprrResDay - a resource on a day
class aiprrResDay : public aipDemon {
aipTime m_day;
aiprrResource * m_res;
aipPandemonium * m_opts; // opts where this resday is the subject
aipHHHope * m_hope; // how well this resday is doing
int m_is_in_cur_solution;
protected:
aipPandemonium * opt_pandemonium () const { // for iterators
return m_opts;
}
public:
aiprrResDay(aiprrResource *a_res, long a_yyyymmdd);
virtual ~aiprrResDay();
void add_opt (aiprrOption *o) { m_opts->add(o); }
virtual void take_msg (aipMsg *m);
virtual void note_aiprr_decide (aiprrDecision *d, aiprrOption *o);
aipTime day () const { return m_day; }
aiprrResource * res () const { return m_res; }
};
//======================================================================
// aiprrRequirementItr - Iterator for Requirements in a Problem
class aiprrRequirementItr : public aipDemonItr {
public:
aiprrRequirementItr (aipPandemonium *p) {
set_demon_itr(p,0);
}
aiprrRequirementItr (const aiprrRequirementItr& x) {
set_demon_itr (x.pandemonium(), x.current());
}
virtual ~aiprrRequirementItr () {}
aiprrRequirementItr& operator = (const aiprrRequirementItr& x) {
set_demon_itr(x.pandemonium(), x.current());
return *this;
}
aiprrRequirement * first () {
return (aiprrRequirement*)aipDemonItr::first();
}
aiprrRequirement * next () {
return (aiprrRequirement*)aipDemonItr::next();
}
};
//======================================================================
// aiprrReqDayItr - Iterator for ReqDays of a Requirement
class aiprrReqDayItr : public aipDemonItr {
public:
aiprrReqDayItr (aipPandemonium *p) {
set_demon_itr(p,0);
}
aiprrReqDayItr (const aiprrReqDayItr& x) {
set_demon_itr (x.pandemonium(), x.current());
}
virtual ~aiprrReqDayItr () {}
aiprrReqDayItr& operator = (const aiprrReqDayItr& x) {
set_demon_itr(x.pandemonium(), x.current());
return *this;
}
aiprrReqDay * first () {
return (aiprrReqDay*)aipDemonItr::first();
}
aiprrReqDay * next () {
return (aiprrReqDay*)aipDemonItr::next();
}
};
//======================================================================
// aiprrResourceItr - Iterator for Resources in a Problem
class aiprrResourceItr : public aipDemonItr {
public:
aiprrResourceItr (aipPandemonium *p) {
set_demon_itr(p,0);
}
aiprrResourceItr (const aiprrResourceItr& x) {
set_demon_itr (x.pandemonium(), x.current());
}
virtual ~aiprrResourceItr () {}
aiprrResourceItr& operator = (const aiprrResourceItr& x) {
set_demon_itr(x.pandemonium(), x.current());
return *this;
}
aiprrResource * first () {
return (aiprrResource*)aipDemonItr::first();
}
aiprrResource * next () {
return (aiprrResource*)aipDemonItr::next();
}
};
//======================================================================
// aiprrResDayItr - Iterator for ResDays of a Resource
class aiprrResDayItr : public aipDemonItr {
public:
aiprrResDayItr (aipPandemonium *p) {
set_demon_itr(p,0);
}
aiprrResDayItr (const aiprrResDayItr& x) {
set_demon_itr (x.pandemonium(), x.current());
}
virtual ~aiprrResDayItr () {}
aiprrResDayItr& operator = (const aiprrResDayItr& x) {
set_demon_itr(x.pandemonium(), x.current());
return *this;
}
aiprrResDay * first () {
return (aiprrResDay*)aipDemonItr::first();
}
aiprrResDay * next () {
return (aiprrResDay*)aipDemonItr::next();
}
};
//======================================================================
// aiprrDecisionItr - Iterator for Decisions in a Problem
class aiprrDecisionItr : public aipDemonItr {
public:
aiprrDecisionItr (aipPandemonium *p) {
set_demon_itr(p,0);
}
aiprrDecisionItr (const aiprrDecisionItr& x) {
set_demon_itr (x.pandemonium(), x.current());
}
virtual ~aiprrDecisionItr () {}
aiprrDecisionItr& operator = (const aiprrDecisionItr& x) {
set_demon_itr(x.pandemonium(), x.current());
return *this;
}
aiprrDecision * first () {
return (aiprrDecision*)aipDemonItr::first();
}
aiprrDecision * next () {
return (aiprrDecision*)aipDemonItr::next();
}
};
//======================================================================
// aiprrMsg - message for StaffWhen problem-solving
class aiprrMsg : public aipHHMsg {
public:
aiprrMsg (aiprrProblem *p, short typ) : aipHHMsg(p,typ) {}
~aiprrMsg() {}
};
//======================================================================
#endif
//======================================================================
// 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.
//
//======================================================================
|