⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rrproj_solv.h

📁 aiParts is a set of C++ classes that can be used to develop artificial intelligence for multi-decisi
💻 H
📖 第 1 页 / 共 2 页
字号:
//**********************************************************************
//  rrproj_solv.h  -  Find a solution to an rrproj problem.
//
//  An application should not directly include this file; 
//  an application should include:  rrproj_prob.h
//
//  Copyright (c)  2008  Brian Marshall
//
//  See the license at end of this file.
//
//  An rrproj problem is the problem of assigning staff 
//  and/or equipment to projects.
//
//  Developers/Contributers:
//    [BRM] Brian Marshall - Calgary - bmarshal@agt.net
//
//  07/11/21  [BRM] began development
//
//----------------------------------------------------------------------
//  About some of the classes...
//
//  An rpsProblem is a subclass of aiprrProblem - it is a 
//  specialization of assigning resources to requirements:
//     -  a  Position is a Requirement; a PosDay is a ReqDay
//     -  an Employee is a Resource;   an EmpDay is a ResDay
//  aiprrProblem is a subclass of aipHHProblem, and as such, 
//  knows how to solve itself using the High-Hope technique.  
//  See aipReqRes.h and aipHighHope.h
//
//  A rpsProblem has a set of decisions, each of which has a set of 
//  options.  A Decision is associated with a Position-Day.  
//  An Option refers to an Employee that can work the Position-Day.
//
//----------------------------------------------------------------------
//  About the status...
//
//  This is a very early version.  The existing techniques can be
//  improved - mostly by improving how messages and calls to
//  problem.note_decide are handled.
//
//  This software is currently very slow.  It does loops within
//  loops where a match-merge techinique would be much faster.
//  This software will be made faster after enough alpha testing
//  has been done.
//
//----------------------------------------------------------------------
//  A Note
//
//  The program will frequently find the same solution a number of
//  times, one after another.  This is a normal.  Each try affects 
//  object attributes provided by the aiParts artificial intelligence
//  software.
//
//----------------------------------------------------------------------
//  Future Development
//
//    If required...
//  repalce  rpsEmployee.set_start_last_work ()  with a class of
//  stats about the current state of the employee
//
//----------------------------------------------------------------------
//  Data Model
//
//  Note that, except for the Problem,  all the objects in the diagram
//  below are pandemoniums (ie. lists of objects).
//
//  The Problem-owning-Decisions-owning-Options is implemented in
//  the Open Source aiParts software.  See aipHighHope.h/cpp for
//  the general technique and aipReqRes.h/cpp which implements the
//  high-hope technique for requirement-resource problems.
//  The pandemonium of decisions in a problem is in aipProblem.h/cpp.
//  The pandemonium of options in a decision is in aipDecision.h/cpp.
//
//  The objects in pandemoniums in this file do not have keys,
//  although they are ordered when created by rrproj_fctry.h/cpp.
//  The reason for this approach is that the pandemoniums of options
//  and decisions are defined in great-grandparent classes.
//
//  A PosDay is associated with a Decision.  If the PosDay requires 
//  multiple employees, the Decision will be decided multiple times.  
//
//        [Employee]<<---[Problem]--->>[Position]
//             |             |             |
//             |             v             v
//             |             v             v
//             |        [Decision]<-----[PosDay]<<---{Project}
//             |             |
//             v             v
//             v             v
//         [EmpDay]----->>[Option]
//
//  {Project} is only in the logical model - there is no project 
//  object; we use proj_id as an optional attribute of Position.
//
//----------------------------------------------------------------------

#ifndef rrproj_solv_h_guard
#define rrproj_solv_h_guard

#include "aipReqRes.h"

//----------------------------------------------------------------------
//  Classes.  Sub-classing is shown by indentation.

//  class  aipG  is a typedef for  aipGoodness

// class aipBase;                        ( in aipBase.h )
//   class aipProblem;                   ( in aipProblem.h )
//     class aipHHProblem;               ( in aipHighHope.h )
//       class aiprrProblem;             ( in aipReqRes.h )
           class rpsProblem;       // rrproj solver problem
//   class aipDemon;                     ( in aipPandemonium.h )
//     class aipDecision;                ( in aipDecision.h )
//       class aipHHDecision;            ( in aipHighHope.h )
//         class aiprrDecision;          ( in aipReqRes.h )
             class rpsDecision;    // decision: emp to work position-day
//     class aipOption;                  ( in aipDecision.h )
//       class aipHHOption;              ( in aipHighHope.h )
//         class aiprrOption;            ( in aipReqRes.h )
             class rpsOption;      // option: an emp on a day
//     class aiprrRequirement;           ( in aipReqRes.h )
         class rpsPosition;        // position requiring employees
//     class aiprrReqDay;                ( in aipReqRes.h )
         class rpsPosDay;          // position on a day
//     class aiprrResource;              ( in aipReqRes.h )
         class rpsEmployee;        // employee that can work positions
//     class aiprrResDay;                ( in aipReqRes.h )
         class rpsEmpDay;          // employee on a day
// class aipDemonItr;                    ( in aipPandemonium.h )
     class rpsPositionItr;         // position iterator
     class rpsPosDayItr;           // posday iterator
     class rpsEmployeeItr;         // employee iterator
     class rpsEmpDayItr;           // empday iterator
     class rpsDecisionItr;         // decision iterator
     class rpsOptItr;              // opt iterator for empday
// class aipMsg                          ( in aipBase.h )
//   class aiprrMsg;                     ( in aipReqRes.h )
       class rpsMsg;               // message for rrproj solving

//======================================================================
//  rpsProblem  -  rrproj solver problem that can solve itself
//
//  Parent classes provide: decisions
//
//  solve_rr_problem () returns 1 (true) if a solution is found,
//  zero otherwise.
//
//  aiprrProblem provides:
//     void set_num_try (long x);
//     int should_log_options () const;
//     void add_decision (aiprrDecision *x);
//
//  m_start_day and m_end_day are set by the factory to 
//  the range of days of the set of positions.

class rpsProblem : public aiprrProblem {

  aipTime    m_start_day;
  aipTime    m_end_day;

protected:

  virtual void apply_emp_aspects (rpsDecision *d, rpsOption *o);
  virtual void log_decide (rpsDecision *d, rpsOption *o);
  virtual void log_this_try ();

public:

  rpsProblem ();
  virtual ~rpsProblem ();

  void add_position  (rpsPosition *x);
  void add_employee  (rpsEmployee *x);

  void set_day_range (long start_yyyymmdd, long end_yyyymmdd);

  aipTime start_day () const { return m_start_day; }
  aipTime end_day   () const { return m_end_day;   }

  rpsPositionItr  position_iterator() const;
  rpsEmployeeItr  employee_iterator() const;
  rpsDecisionItr  decision_iterator() const;

  virtual void take_msg (aipMsg *m);
  virtual void note_decide (aipHHDecision *d, aipHHOption *o);

  virtual int solve_rr_problem () { 
    return aiprrProblem::solve_rr_problem(); // 1 on success
  }

};


//======================================================================
//  rpsDecision  -  choosing an emp for a posday
//
//  Parent classes provide: options, hope, importance

class rpsDecision : public aiprrDecision {

public:

  rpsDecision (rpsPosDay *a_posday, long num_to_decide =1);
  virtual ~rpsDecision();

  void add_rps_option (rpsOption *x);

  virtual void take_msg (aipMsg *m);

  rpsProblem * prob   () const { return (rpsProblem*)owner(); }
  rpsPosDay  * posday () const { return (rpsPosDay*)reqday(); }

  rpsOption * rps_opt_cur () const { 
    return (rpsOption*)aiprr_opt_cur();  
  }

  rpsOption * rps_opt_bsf () const { 
    return (rpsOption*)aiprr_opt_bsf();
  }

};

//======================================================================
//  rpsOption  - an employee working a position on a day
//
//  Parent classes provide: hope, importance, goodness variables 

class rpsOption : public aiprrOption {

public:

  rpsOption(rpsEmpDay *a_empday, aipG g_constant);
  virtual ~rpsOption ();

  rpsDecision * rps_chooser () const { 
    return (rpsDecision*)aiprr_chooser(); 
  }

  virtual void take_msg (aipMsg *m);

  rpsEmpDay  * empday () const { return (rpsEmpDay*)resday(); }

  rpsPosDay  * posday () const {
       // we use owner instead of chooser, so an opt is always
       // for a posday.  This depends on, in this file,  options
       // are not shared between decisions.
    rpsDecision *d = (rpsDecision*)(hh_opt_owner());
    return d ? d->posday() : 0;
  }

  rpsPosDay  * bsf_posday () const {
    rpsDecision *d = (rpsDecision*)(aipHHOption::hh_bsf_chooser());
    return d ? d->posday() : 0;
  }

  rpsEmployee * emp () const;
  rpsPosition * pos () const;
  aipTime       day () const;

  virtual aipG g_opt();         // for making decisions
  virtual aipG g_opt_cmp();     // for comparing solutions
  virtual aipG g_opt_usr();     // for reporting to the user

};

//======================================================================
//  rpsPosition  -  a position requiring employees
//
//  A position is owned by a problem; it owns position-days.
//
//  Parent classes provide: id()
//
//  A position is identified by: pos_id()

class rpsPosition : public aiprrRequirement {

public:

  rpsPosition(long a_pos_id, rpsProblem *a_prob);
  virtual ~rpsPosition() {}

  virtual long num_keys (void) const { return 1; }
  virtual long     key1 (void) const { return aiprrRequirement::id(); }

  void add_posday (rpsPosDay *x);

  virtual void take_msg (aipMsg *m);
  // virtual void note_rps_decide (rpsDecision *d, rpsOption *o);

  rpsProblem * prob () const { 
    return (rpsProblem*)(aiprrRequirement::prob()); 
  }

  long pos_id  () const { 
    return aiprrRequirement::id(); 
  }

  rpsPosDayItr  posday_iterator() const;

};


//======================================================================
//  rpsPosDay  -  a position on a day (requiring one or more employees)
//
//  Parent classes provide day()
//
//  The proj_id is optional - if the solver is to pay attention 
//  to it, it should be greater than zero.

class rpsPosDay : public aiprrReqDay {

  long       m_proj_id;

  aipTime    m_start_time;
  aipTime    m_end_time;

  long       m_yyyymmdd;

public:

  rpsPosDay(rpsPosition *a_pos, long a_yyyymmdd, long a_proj_id,
            long a_start_hhmm =800, long a_end_hhmm =1700);
  virtual ~rpsPosDay();

  virtual long num_keys (void) const { return 3; }
  virtual long     key1 (void) const { return aiprrReqDay::req()->id(); }
  virtual long     key2 (void) const { return m_yyyymmdd; }
  virtual long     key3 (void) const { return m_proj_id; }

  virtual void take_msg (aipMsg *m);
  // virtual void note_rps_decide (rpsDecision *d, rpsOption *o);

  rpsPosition * pos () const { 
    return (rpsPosition*)(aiprrReqDay::req()); 
  }

  long pos_id () const { 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -