Home Page Downloads Contact Us

Free Open Source Artificial Intelligence C++ Parts

aiParts Open Source Project  

Home Page
Open Source
Contact
Free Downloads
Releases and Credits
Software Status
License
v0.9.3 README File
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.
//
//======================================================================