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

📄 rrproj_prob.h

📁 aiParts is a set of C++ classes that can be used to develop artificial intelligence for multi-decisi
💻 H
📖 第 1 页 / 共 3 页
字号:
//**********************************************************************
//  rrproj_prob.h  -  rrproj Problem
//
//  An rrproj problem is the problem of assigning people and/or 
//  equipment to projects.  An application includes this file to 
//  define and solve this type of problem.
//    
//  Copyright (c)  2008  Brian Marshall
//
//  See the license at end of this file.
//
//  Developers/Contributers:
//    [BRM] Brian Marshall - Calgary - bmarshal@agt.net
//
//  08/01/19  [BRM] began development
//
//----------------------------------------------------------------------
//  Required Source Files
//
// To use the solve() function, the following files must be compiled:
//     rrproj_prob.cpp       (with rrproj_prob.h)
//     rrproj_solv.cpp       (with rrproj_solv.h)
//     rrproj_fctry.cpp      (with rrproj_fctry.h)
//     aipReqRes.cpp         (with aipReqRes.h)
//     aipHighHope.cpp       (with aipHighHope.h)
//     aipProblem.cpp        (with aipProblem.h)
//     aipDecision.cpp       (with aipDecision.h)
//     aipEmotion.cpp        (with aipEmotion.h)
//     aipPandemonium.cpp    (with aipPandemonium.h)
//     aipBase.cpp           (with aipBase.h)
//     aipGood.cpp           (with aipGood.h)
//
//----------------------------------------------------------------------
//  Data relationships in a rrproj Problem
//
//  If A is joined to B by a line, and A is higher than B in the
//  diagram, there is a one-to-many relationship between A and B.
//
//  <xyz> angle brackets indicate output solution data
//  {abc} curly braces   indicate virtual datasets
//
//                        [Problem]____[ProbWriter]
//               _________|     | |__________
//              |               |            |
//       {Position}  {Project}  |       _{Employee}__________
//       |  |  |  |    |        |      |  |  |  | |_______   |
//       |  |  |  [Pos_Day]     |      |  |  |  |         |  |
//       |  |  |       |        |      |  |  |  [Emp_Dow] |  |
//       |  |  |      <Pos_Day_Emp>____|  |  |            |  |
//       |  |  |                          |  [Emp_Off]    |  |
//       |  |  |__________[Pos_Emp]_______|               |  |
//       |  |                                             |  |
//       |  |___________[Emp_Day_Pos]_____________________|  |
//       |                                                   |
//       |_______________[Assignment]________________________|
//
//
//
//  Pos_Day_Emp is the normalized output solution data.
//  Emp_Day_Pos is for (optional) historic data.
//  Other entities define the problem to be solved.
//
//  If the problem is configured with an rppProbWriteWeek1
//  for a [ProbWriter], the output solution data is
//  denormalized into weeks:
//
//                        [Problem]____[rppProbWriteWeek1]
//               _________|     | |__________
//              |               |            |
//       {Position}  {Project}  |        {Employee}
//               |     |        |          |  |
//              [Pos_Day]   <<Proj_Week>>  |  |
//                |             |          |  |
//                |      <<Proj_Week_Emp>>_|  |
//                |             |             |
//     <Pos_Day_Emp>___<Proj_Week_Emp_Day>____|
//
//
//  <Pos_Day_Emp> is the normalized solution data
//  <Proj_Week_Emp_Day> is reordered noralized solution data
//  <<Proj_Week>>  and  <<Proj_Week_Emp>> are the solution data
//      by project-week: master and detail data
//      which are created from <Proj_Week_Emp_Day>
//
//  The data is stored in the order indicated by the name.
//  Input data can be provided in any order.
//
//  In this software, Problem, Project, Position and Employee are 
//  virtual datasets.  They would be in a logical data model, but
//  they are not datasets in this software.
//
//----------------------------------------------------------------------
//  Optionally providing historic Emp_Day_Pos data
//
//  If an application expects the solver to consider data prior to
//  the start of the problem, historic Emp_Day_Pos data must
//  be supplied before the problem solve() function is called.
//
//  Adding Emp_Day_Pos data is optional, and it may be added for 
//  just the employees for which it matters.
//
//  Examples requiring (some) historic data:
//  - It may be desirable to rotate through (some) employees 
//    (ex. part-time employees, contractors, volunteers).
//  - It is desirable, for an employee who worked a position yesterday
//    to work the same position today (if the employee works today).
//
//  Currently, the minimum desirable amount of historic Emp_Day_Pos 
//  data is the last day worked (before the first day of the problem)
//  for each employee.  Employees may be omitted if they worked
//  in the last couple of days before the problem.
//
//  The solver does not get historic Emp_Day_Pos data; this data is
//  used to set attributes in entities that are part of the solver.
//
//  The output solution data does not include the historic data.
//
//----------------------------------------------------------------------
//  Using this software in an application
//
//  The application will create an instance of class rppProblem
//  and call (some of) its public functions:
//    either:
//      - call functions to add the problem data to the rppProblem
//    or:
//      - call the problem read() function
//    call solve() to solve the problem
//    either:
//      - call get_rslt_desc()
//      - call get_pos_day_emp () to get the solution
//    or:
//      - create an instance of a subclass of rppProbWrite
//      - call the write() function of the instance
//  and then delete the instance of rrpProblem if required.
//
//  The char* pointer returned from rrpProblem::get_rslt_desc()
//  must not be used after the rrpProblem is deleted.
//
//  A subclass of rppProbWrite can denormalize the data in a
//  particular way - it customizes the solution data file
//  for one or more applications.
//
//  The application developer does not have to know or care about:
//   - how rrpProblem stores data
//   - how the public functions work
//   - anything about any of the other classes in this file
//
//----------------------------------------------------------------------
//  What rppProblem::solve() does  (optional information)
//
//  When solve() is called, it:
//    - creates an instance of rpsFactory
//    - uses the factory with the problem data to build a solver
//    - deletes the factory
//    - calls the solver solve() function
//    - copies the solution data to the problem data
//    - deletes the solver
//
//----------------------------------------------------------------------

#ifndef rrproj_prob_h_guard
#define rrproj_prob_h_guard

#include "aipPandemonium.h"
#include "aipTime.h"

#include <stdio.h>

//----------------------------------------------------------------------
//  Local Constants

const long Max_Str_Key_Len = 30;

const long File_Date_Len = 10;   // "yyyy-mm-dd"
const long File_Time_Len =  5;   // "hh:mm"

const long Max_Log_Len = 300;

const long Max_File_Name = 100;

//----------------------------------------------------------------------
//  Classes.  Sub-classing is shown by indentation.
//
//  class  aipG  is a typedef for aipGoodness.
//
//  A class is a subclass of aipDemon (a list element) so that
//  a pointer to it can be added to pandemoniums (lists). 

// class aipBase;                        ( in aipBase.h )
     class rppProblem;             // rrproj problem
//   class aipDemon;                     ( in aipPandemonium.h )
       class rppPosDay;            // position on a day
       class rppEmpDow;            // days-of-week the emp can work
       class rppEmpOff;            // days an emp cannot work
       class rppPosEmp;            // pos and an emp that can work it
       class rppAssignment;        // an emp pre-assigned to a pos
       class rppEmpDayPos;         // historic solution data
       class rppPosDayEmp;         // normalized solution data
       class rppProjWeekEmpDay;    // re-ordered normalized solution
       class rppProjWeek;          // output master for a week 
       class rppProjWeekEmp;       // output detail for a week
     class rppProbWrite;           // problem solution-writer
       class rppProbWriteWeek1;    // week-based writer number 1
//   class aipLogger;                    ( in aipBase.h )
//     class aipStringLogger;            ( in aipBase.h )
// class aipDemonItr;                    ( in aipPandemonium.h )
     class rppPosDayItr;           // position-day iterator
     class rppEmpItr;              // employee iterator
     class rppEmpDowItr;           // emp-off iterator
     class rppEmpOffItr;           // emp-off iterator
     class rppPosEmpItr;           // position-employee-pair iterator
     class rppAssgnItr;            // assignment iterator
     class rppEmpDayPosItr;        // historic emp-day-pos iterator
     class rppPosDayEmpItr;        // normalized-output iterator
     class rppProjWeekEmpDayItr;   // re-ordered output iterator
     class rppProjWeekItr;         // output-master iterator
     class rppProjWeekEmpItr;      // output-detail iterator
   class rppFileDate;              // read/write dates in a file
   class rppFileTime;              // read/write times in a file

//======================================================================
//  rppProblem  -  an rrproj problem as defined by the application

class rppProblem : public aipBase {

  long      m_start_yyyymmdd;
  long      m_end_yyyymmdd;
  long      m_week_start_day;          // 0=Sunday
  long      m_num_tries;

  aipStringLogger * m_logger;          // for calls to log()

  aipPandemonium  * m_posdays;         // problem data
  aipPandemonium  * m_empdows;
  aipPandemonium  * m_empoffs;
  aipPandemonium  * m_posemps;
  aipPandemonium  * m_assignments;

  aipPandemonium  * m_empdaypos;       // historic solution data

  aipPandemonium  * m_posdayemps;      // output solution data

  rppPosDayEmpItr * m_posdayemp_itr;   // for get_pos_day_emp()

public:
                   //  Functions Used by the Application
  rppProblem ();
  virtual ~rppProblem ();

  int is_valid ();    // returns true if valid

  virtual int read (const char *filename);  // return 0 on failure

                   // for problem data record - returns 0 on failure
  virtual int read_str  (const char *x);
  virtual int write_str (char *x) const;

  virtual int write_input (const char *filename);

  const char * get_rslt_desc () const;  

                                        // or i/o by calls
  void add_pos_day    (long a_proj_id, long a_pos_id, 
                       long a_yyyymmdd, long a_num_emps_req);

  void add_emp_dow    (long a_emp_id, long a_dow,
                       long a_start_hhmm, long a_end_hhmm);

  void add_emp_off    (long a_emp_id, 
                       long a_start_yyyymmdd, long a_end_yyyymmdd);

  void add_pos_emp    (long a_pos_id, long a_emp_id);

  void add_assignment (long a_proj_id, long a_pos_id, long a_emp_id,
                       long a_start_yyyymmdd, long a_end_yyyymmdd);

  void add_empdaypos  (long a_emp_id, long a_yyyymmdd,  // historic
                       long a_proj_id, long a_pos_id);

  void add_posdayemp  (long a_proj_id, long a_pos_id,   // solution
                       long a_yyyymmdd, long a_emp_id);

  virtual int solve();      // returns 1 (true) on success

                    // get solution, returns 0 after last
  int get_pos_day_emp (long *a_proj_id, long *a_pos_id, 
                       long *a_yyyymmdd, long *a_emp_id);

                    //  Functions Used Internally

  long  start_yyyymmdd () const { return m_start_yyyymmdd; }
  long  end_yyyymmdd   () const { return m_end_yyyymmdd;   }
  long  week_start_day () const { return m_week_start_day; }
  long  num_tries      () const { return m_num_tries;      }

  rppPosDayItr       posday_iterator    () const;  // get an iterator
  rppEmpDowItr       empdow_iterator    () const;
  rppEmpOffItr       empoff_iterator    () const;
  rppPosEmpItr       posemp_iterator    () const;
  rppAssgnItr        assgn_iterator     () const;
  rppEmpDayPosItr    empdaypos_iterator () const;
  rppPosDayEmpItr    posdayemp_iterator () const;

};

//======================================================================
//  rppPosDay  -  Position on a Day that requires Employees

class rppPosDay : public aipDemon {

  long      m_proj_id;
  long      m_pos_id;
  long      m_yyyymmdd;

  long      m_num_emps_req;   // employees required

  long      m_start_hhmm;     // 1430 is 2:30 pm
  long      m_end_hhmm;

public:

  rppPosDay () {}
  rppPosDay (long a_proj_id, long a_pos_id,
             long a_yyyymmdd, long a_num_emps_req,
             long a_start_hhmm =0, long a_end_hhmm =0);
  virtual ~rppPosDay ();

  virtual long num_keys (void) const { return 3;          }
  virtual long     key1 (void) const { return m_proj_id;  }
  virtual long     key2 (void) const { return m_pos_id;   }
  virtual long     key3 (void) const { return m_yyyymmdd; }

                                          // returns 0 on failure
  virtual int read_str  (const char *x);
  virtual int write_str       (char *x) const;

  long  proj_id      () const { return m_proj_id;      }
  long  pos_id       () const { return m_pos_id;       }
  long  yyyymmdd     () const { return m_yyyymmdd;     }
  long  num_emps_req () const { return m_num_emps_req; }
  long  start_hhmm   () const { return m_start_hhmm;   }
  long  end_hhmm     () const { return m_end_hhmm;     }

};

//======================================================================
//  rppEmpDow  -  Day-of-week on which the employee can work

class rppEmpDow : public aipDemon {

  long      m_emp_id;
  long      m_dow;           // ex: 0=sun, 1=mon, 2=tue, etc.

  long      m_start_hhmm;    // 1430 is 2:30 pm
  long      m_end_hhmm;

public:

  rppEmpDow () {}
  rppEmpDow (long a_emp_id, long a_dow, 
             long a_start_hhmm, long a_end_hhmm);
  virtual ~rppEmpDow ();

  virtual long num_keys (void) const { return 2;        }
  virtual long     key1 (void) const { return m_emp_id; }
  virtual long     key2 (void) const { return m_dow;    }

                                          // returns 0 on failure
  virtual int read_str  (const char *x);
  virtual int write_str       (char *x) const;

  long emp_id () const { return m_emp_id; }
  long dow    () const { return m_dow;    }

  long start_hhmm () const { return m_start_hhmm; }
  long end_hhmm   () const { return m_end_hhmm;   }

};

//======================================================================
//  rppEmpOff  -  Days on which the employee cannot work

class rppEmpOff : public aipDemon {

  long      m_emp_id;
  long      m_start_yyyymmdd;
  long      m_end_yyyymmdd;

⌨️ 快捷键说明

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