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

📄 rrproj_fctry.cpp

📁 aiParts is a set of C++ classes that can be used to develop artificial intelligence for multi-decisi
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//**********************************************************************
//  rrproj_fctry.cpp   function bodies for rrproj_fctry.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/28  [BRM] began development
//
//----------------------------------------------------------------------

#include "rrproj_fctry.h"

//     for debugging...
// #include <string.h>
// #include <iostream>
// using namespace std;

//======================================================================
//  Factory Data
//
//      3 datasets:
//  - problem - setup with data from the user
//  - solver  - factory creates it from the problem dataset
//  - factory - temporary data owned by the factory
//
//      variable names in functions:
//  The first letter of some variables in functions indicates the
//  dataset from which the function is set:
//     pemp   is an emp from the problem
//     semp   is an emp from the solver
//     fempid is an empid from the factory
//
//      class name prefix
//  rpp   rrproj  problem  (setup by application)
//  rps   rrproj  solver   (used by the problem)
//  rpf   rrproj  factory  (solver-factory)
//
//----------------------------------------------------------------------
//  Constructor

rpfFactory::rpfFactory (rppProblem *pdata) {

  m_problem_data = pdata;

  m_emp_ids = new aipPandemonium;
  if (m_emp_ids) m_emp_ids->set_is_distinct();

  m_opts = new aipPandemonium;
  if (m_opts) m_opts->set_is_distinct();

}

//----------------------------------------------------------------------
//  Destructor

rpfFactory::~rpfFactory () { 

  if (m_emp_ids)        delete m_emp_ids;
  if (m_opts)           delete m_opts;

}

//----------------------------------------------------------------------
//  create and setup a new rpsProblem from the problem data.

rpsProblem * rpfFactory::make_rps_problem () {

  if (!m_problem_data) return 0;

  rpsProblem *sp = new rpsProblem ();
  if (!sp) return 0;

  sp->set_num_try (m_problem_data->num_tries());

  int status = 1;
  if (status) status = setup(sp);

  if (!status) return 0;

  return sp;

}

//----------------------------------------------------------------------
//  setup an rpsProblem - return true on success

int rpfFactory::setup (rpsProblem *sprob) {

  int status = 1;

                             // iterators in the problem data
  rppPosDayItr  pditr = pprob()->posday_iterator();
  rppPosEmpItr  peitr = pprob()->posemp_iterator();
  rppAssgnItr   aitr  = pprob()->assgn_iterator();

                             // iterators in the factory data
  rpfOptItr    oitr  = opt_iterator();

                      // setup pos, posday, dcsn
  if (status) status = handle_pd (pditr, sprob);

                      // setup emp, empday
  if (status) status = handle_pe_a (peitr, aitr, sprob);

                      // add to the opt list
  if (status) status = handle_a_ed (aitr, sprob);

                      // add to opt list
  if (status) status = handle_pe_pd_ed (peitr, sprob);

                      // setup options from opt list
  if (status) status = handle_o (oitr, sprob);

  return status;

}

//----------------------------------------------------------------------
//  handle the set of PosDays in the problem data
//
//  create positions and handle individual posdays

int rpfFactory::handle_pd (rppPosDayItr pditr, rpsProblem *sprob) {

  int status = 1;

  long min_yyyymmdd = 20200101;
  long max_yyyymmdd = 19800101;

  long prev_pos_id   = very_unlikely_id();

  long         pner;       // num-emps_required in the problem
  rppPosDay   *ppd;        // posday in the problem
  rpsPosDay   *spd;        // posday in the solver
  rpsPosition *spos;       // pos in the solver

  if (status) {                      // create (Pos), (PosDay), (Dcsn)
    for (ppd = pditr.first(); ppd; ppd = pditr.next()) {

      if (ppd->pos_id() != prev_pos_id) {
        spos = new rpsPosition(ppd->pos_id(), sprob);
        if (!spos) { status = 0;  log(" Err new rpsPosition"); break; }
        sprob->add_position(spos);
        prev_pos_id = ppd->pos_id();
      }

      spd = new rpsPosDay(spos, ppd->yyyymmdd(), ppd->proj_id(),
                                ppd->start_hhmm(), ppd->end_hhmm());
      if (!spd) { status = 0;  log("Err new rpsPosDay"); break; }
      spos->add_posday(spd);

      pner = ppd->num_emps_req();
      if (pner < 1 || pner > 1000) {
        status = 0;   log("Err bad num-emps-required");  break;
      }
      rpsDecision *sdcsn = new rpsDecision(spd, pner);
      if (!sdcsn) {status = 0;  log("Err new rpsDecision"); break; }
      sprob->add_decision(sdcsn);
      spd->set_dcsn(sdcsn);

      long ppd_yyyymmdd = ppd->yyyymmdd();
      if (ppd_yyyymmdd < min_yyyymmdd) min_yyyymmdd = ppd_yyyymmdd;
      if (ppd_yyyymmdd > max_yyyymmdd) max_yyyymmdd = ppd_yyyymmdd;
    
    }
  }

  if (status) {
    sprob->set_day_range (min_yyyymmdd, max_yyyymmdd);
  }

  return status;

}

//----------------------------------------------------------------------
//  handle the sets of posemps and assignments in the problem data
//
//  create a distinct list of empids, and then create emps and empdays
//     (which also uses empdows and empoffs)

int rpfFactory::handle_pe_a (rppPosEmpItr peitr, rppAssgnItr aitr, 
                                                   rpsProblem *sprob) {

  int status = 1;

  rpfEmpId   *feid;            // an empid owned by the factory
  long prev_eid = very_unlikely_id();

  if (status) {                  // start {EmpId}
    rppPosEmp *ppe;            // a posemp in the problem
    for (ppe = peitr.first(); ppe; ppe = peitr.next()) {
      if (ppe->emp_id() != prev_eid) {
        feid = new rpfEmpId(ppe->emp_id());
        if (!feid) { status = 0;  log("Err new rpfEmpId"); break; }
        m_emp_ids->add (feid);  // list is forced distinct
        prev_eid = ppe->emp_id();
      }
    }
  }

  if (status) {                  // add to {EmpId}
    rppAssignment *pa;         // an assignment in the problem
    for (pa = aitr.first(); pa; pa = aitr.next()) {
      if (pa->emp_id() != prev_eid) {
        feid = new rpfEmpId(pa->emp_id());
        if (!feid) { status = 0;  log("Err new rpfEmpId"); break; }
        m_emp_ids->add (feid);  // list is forced distinct
        prev_eid = pa->emp_id();
      }
    }
  }

    // we now have a distinct list of emp_ids

  rpsEmployee *semp;           // an emp in the solver

  if (status) {                  // create (Emp)
   rpfEmpIdItr eiditr = empid_iterator();
    for (feid = eiditr.first(); feid; feid = eiditr.next()) {

      semp = new rpsEmployee(feid->emp_id(), sprob);
      if (!semp) { status = 0; log("Err new rpsEmployee"); break; }
      sprob->add_employee(semp);

      status = handle_e (semp, sprob);
      if (!status) break;

    }
  }

  return status;

}

//----------------------------------------------------------------------
//  handle a solver emp - create empday 

int rpfFactory::handle_e (rpsEmployee *semp, rpsProblem *sprob) {

  int status = 1;

  if (status) {
    apply_empdaypos(semp);
  }

  if (status) {                  // create (EmpDay)
    aipTime curday( (sprob->start_day()) );
    aipTime lastday( (sprob->end_day()) );
    for ( ; curday <= lastday; curday.add_days(1) ) {

      long x_yyyymmdd = curday.yyyymmdd();
      if (!x_yyyymmdd) { status = 0; log("Err h_e yyyymmdd"); break; }

      if ( emp_is_off (semp->emp_id(), curday) ) continue;

      long x_start_hhmm, x_end_hhmm;
      long x_dow = curday.days_since_sunday();
      
      get_dow_data (semp->emp_id(), x_dow, 
                    &x_start_hhmm, &x_end_hhmm);
      if (x_start_hhmm == x_end_hhmm) continue;

      rpsEmpDay *sed = new rpsEmpDay (semp, x_yyyymmdd,
                                      x_start_hhmm, x_end_hhmm);
      if (!sed) { status = 0; log("Err new rpsEmpDay"); break; }
      semp->add_empday(sed);

    }
  }

  return status;

}

//----------------------------------------------------------------------
//  handle the set of assignments (plus solution EmpDays)
//
//  start a list of options (that is forced to have distinct keys)

int rpfFactory::handle_a_ed (rppAssgnItr aitr, rpsProblem *sprob) {

  int status = 1;

  if (status) {                  // create {opt} from [Assgnmnt]

    rppAssignment *pa;      // an assignment in the problem
    rpsPosDay     *spd;     // a  posday in the solver
    rpsEmpDay     *sed;     // an empday in the solver

    for (pa = aitr.first(); pa; pa = aitr.next()) {

      aipTime curday(pa->start_yyyymmdd());
      aipTime lastday(pa->end_yyyymmdd());

      for ( ; curday <= lastday; curday.add_days(1) ) {

        spd = find_posday (pa->pos_id(), curday.yyyymmdd(), 
                           pa->proj_id(), sprob);
        if (!spd) continue;

        sed = find_empday (pa->emp_id(), curday.yyyymmdd(), sprob);
        if (!sed) continue;

⌨️ 快捷键说明

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