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

📄 rrproj_prob.cpp

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

#include "rrproj_prob.h"
#include "rrproj_fctry.h"

#include <string.h>
#include <stdlib.h>

// #include <iostream>   // for debugging
// #include <fstream>
// using namespace std;

//======================================================================
//  local functions
//
//----------------------------------------------------------------------
//  save the solution from a solver-problem in a problem-problem

void save_solution (rppProblem *rpp_problem, rpsProblem *rps_problem) {

  rpsDecision * rd;
  rpsOption   * ro;
  rpsPosDay   * rpd;
  rpsPosition * rp;
  rpsEmployee * re;
  long          syyyymmdd;
  aipHHOption * shhopt;

  aipHHOptionItr oitr;
  rpsDecisionItr ditr = rps_problem->decision_iterator();
  for ( rd=ditr.first(); rd; rd=ditr.next() ) {

    oitr = rd->bsf_opt_iterator();
    for ( shhopt=oitr.first(); shhopt; shhopt=oitr.next() ) {

      ro = (rpsOption*)shhopt;

      rpd = ro->bsf_posday();
      rp  = rpd->pos();
      re  = ro->emp();

      syyyymmdd = rpd->yyyymmdd();

      rpp_problem->add_posdayemp ( rpd->proj_id(), rp->pos_id(),
                                   syyyymmdd, re->emp_id() );

    }   // end of loop through options in best-so-far solution

  }   // end of loop through decisions

}

//======================================================================
//  rppProblem
//
//----------------------------------------------------------------------
//  Constructor

rppProblem::rppProblem () {

  m_start_yyyymmdd = 19000101;
  m_end_yyyymmdd   = 19000101;
  m_num_tries      = 0;

  m_logger = new aipStringLogger(Max_Log_Len);
  if (m_logger) set_logger(m_logger);

  m_posdays     = new aipPandemonium;
  m_empdows     = new aipPandemonium;
  m_empoffs     = new aipPandemonium;
  m_posemps     = new aipPandemonium;
  m_assignments = new aipPandemonium;
  m_empdaypos   = new aipPandemonium;
  m_posdayemps  = new aipPandemonium;

  m_posdayemp_itr = 0;  // managed by get_pos_day_emp()

}

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

rppProblem::~rppProblem () {

  if (m_logger)      delete m_logger;
  if (m_posdays)     delete m_posdays;
  if (m_empdows)     delete m_empdows;
  if (m_empoffs)     delete m_empoffs;
  if (m_posemps)     delete m_posemps;
  if (m_assignments) delete m_assignments;
  if (m_empdaypos)   delete m_empdaypos;
  if (m_posdayemps)  delete m_posdayemps;

  if (m_posdayemp_itr) delete m_posdayemp_itr;

}

//----------------------------------------------------------------------
//  Return true if the problem is valid after construction.
//  Log problems.

int rppProblem::is_valid () {

  if ( ! m_posdays ) {
    log("Error creating m_posdays");
    return 0;
  }

  if ( ! m_empdows ) {
    log("Error creating m_empdows");
    return 0;
  }

  if ( ! m_empoffs ) {
    log("Error creating m_empoffs");
    return 0;
  }

  if ( ! m_posemps ) {
    log("Error creating m_posemps");
    return 0;
  }

  if ( ! m_assignments ) {
    log("Error creating m_assignments");
    return 0;
  }

  if ( ! m_empdaypos ) {
    log("Error creating m_empdaypos");
    return 0;
  }

  if ( ! m_posdayemps ) {
    log("Error creating m_posdayemps");
    return 0;
  }

  if (m_posdayemp_itr != 0) {
    log("m_posdayemp_itr should be zero");
    return 0;
  }

  return 1;

}

//----------------------------------------------------------------------
//  Read the input data from a file; return 1 (true) on success

int rppProblem::read (const char *filename) {

  FILE *ifp = fopen (filename, "r");
  if (!ifp) {
    log("Error opening input file: ");
    log(filename);
    return 0;
  }

  int istatus = 1;
  int rstatus;

  char buf[201], record_type[31];
  const char *p;

  while (istatus) {

    rstatus = fgets(buf,200,ifp) != 0;
    if (!rstatus) break;

    buf[200] = '\0';           // make sure it is terminated

    char *q = buf;
    int anything = 0;
    while (*q) {               // terminate at the newline
      if ( (*q >= 'A' && *q <= 'Z') ||
           (*q >= 'a' && *q <= 'z') ||
           (*q >= '0' && *q <= '9') ) {
        anything = 1;       // has some data
      } else if (*q == '\n') { 
        *q = '\0'; 
        break; 
      } 
      q++; 
    }

    if (buf[0] == '#' || !anything) continue;

    p = buf;
    if (*p) p = aip_get_str(p, 30, record_type, '|');
    if (!p) continue;

    if ( strcmp (record_type, "rppProblem") == 0) {

      istatus = read_str(p);

    } else if ( strcmp (record_type, "rppPosDay") == 0) {

      rppPosDay *pd = new rppPosDay;
      if (!pd) { log("new pd failure"); return 0; }
      istatus =  pd->read_str(p);
      if (istatus && m_posdays) {
        m_posdays->add(pd);
      } else {
        delete pd;
      }

    } else if ( strcmp (record_type, "rppPosEmp") == 0) {

      rppPosEmp *pqe = new rppPosEmp;
      if (!pqe) { log("new pqe failure"); return 0; }
      istatus =  pqe->read_str(p);
      if (istatus && m_posemps) {
        m_posemps->add(pqe);
      } else {
        delete pqe;
      }

    } else if ( strcmp (record_type, "rppEmpDow") == 0) {

      rppEmpDow *edow = new rppEmpDow;
      if (!edow) { log("new edow failure"); return 0; }
      istatus = edow->read_str(p);
      if (istatus && m_empdows) {
        m_empdows->add(edow);
      } else {
        delete edow;
      }

    } else if ( strcmp (record_type, "rppEmpOff") == 0) {

      rppEmpOff *eoff = new rppEmpOff;
      if (!eoff) { log("new eoff failure"); return 0; }
      istatus = eoff->read_str(p);
      if (istatus && m_empoffs) {
        m_empoffs->add(eoff);
      } else {
        delete eoff;
      }

    } else if ( strcmp (record_type, "rppAssignment") == 0) {

      rppAssignment *assg = new rppAssignment;
      if (!assg) { log("new assg failure"); return 0; }
      istatus = assg->read_str(p);
      if (istatus && m_assignments) {
        m_assignments->add(assg);
      } else {
        delete assg;
      }

    } else if ( strcmp (record_type, "rppEmpDayPos") == 0) {

      rppEmpDayPos *edp = new rppEmpDayPos;
      if (!edp) { log("new edp failure"); return 0; }
      istatus = edp->read_str(p);
      if (istatus && m_empdaypos) {
        m_empdaypos->add(edp);
      } else {
        delete edp;
      }

    } else {

      log("Read - bad record_type: ");
      log(record_type);
      return 0;

    }

  }  // end of loop through records in input file

  if (!istatus) {
    log("  Error reading input: ");
    log(buf);
  }

  fclose (ifp);

  return istatus;

}

//----------------------------------------------------------------------
//  Read data from string to setup this object

int rppProblem::read_str (const char *x) {

  m_start_yyyymmdd = m_end_yyyymmdd = 19000101;
  m_week_start_day = m_num_tries = 0;

  char s_start_date[31], s_end_date[31];

  if (x && *x) x = aip_get_str(x, 30, s_start_date,      '|');
  if (x && *x) x = aip_get_str(x, 30, s_end_date,        '|');
  if (x && *x) x = aip_get_val(x, 10, &m_week_start_day, '|');
  if (x && *x) x = aip_get_val(x, 10, &m_num_tries,      '|');

  if (!x) return 0;

  rppFileDate x_start_date(s_start_date);
  if ( !x_start_date.is_valid() ) {
    log("problem start-date must be set and valid");
    return 0;
  }
  m_start_yyyymmdd = x_start_date.long_date();
  if (m_start_yyyymmdd < 19000101 || m_start_yyyymmdd > 21000101) {
    log("problem start-date must be between 1900 and 2100");
    return 0;
  }

  rppFileDate x_end_date(s_end_date);
  if ( !x_end_date.is_valid() ) {
    log("problem end-date must be set and valid");
    return 0;
  }
  m_end_yyyymmdd = x_end_date.long_date();
  if (m_end_yyyymmdd < 19000101 || m_end_yyyymmdd > 21000101) {
    log("problem end-date must be between 1900 and 2100");
    return 0;
  }
  if (m_end_yyyymmdd < m_start_yyyymmdd) {
    log("problem end-date must be after problem start-date");
    return 0;
  }

  if (m_week_start_day < 1 || m_week_start_day > 7) {
    log("week_start_day must be between 1 and 7");
    return 0;
  }

  if (m_num_tries < 1 || m_num_tries > 100000) {
    log("num_tries must be between 1 and 100000");
    return 0;
  }

  return 1;

}

//----------------------------------------------------------------------
//  Write the data in this object to the string; return 0 on failure

int rppProblem::write_str (char *x) const {

  rppFileDate x_start_date(m_start_yyyymmdd);
  if ( !x_start_date.is_valid() ) return 0;

  rppFileDate x_end_date(m_end_yyyymmdd);
  if ( !x_end_date.is_valid() ) return 0;

  int n = sprintf (x, "rppProblem|%s|%s|%ld|%ld",
                             x_start_date.file_date(), 
                             x_end_date.file_date(), 
                             m_week_start_day,
                             m_num_tries);

  return (n ? 1 : 0);

}

//----------------------------------------------------------------------
//  Write the input data to a file; return 1 (true) on success

int rppProblem::write_input (const char *filename) {

  FILE *ofp = fopen (filename, "w");
  if (!ofp) {
    log("Error opening export file");
    return 0;
  }

  int n = 1;

  if (n) n = fprintf (ofp, "#  rrproj export file\n");
  if (n) n = fprintf (ofp, "# \n");

  char rec[1001];

  if (n) n = write_str(rec);
  if (n) n = fprintf (ofp, "%s\n", rec);  // rppProblem record

  rppPosDayItr pditr = posday_iterator();
  rppPosDay *pd;
  for (pd = pditr.first(); pd && n; pd = pditr.next()) {
    if (n) n = pd->write_str(rec);
    if (n) n = fprintf (ofp, "%s\n", rec);
  }

  rppPosEmpItr peitr = posemp_iterator();
  rppPosEmp *pe;
  for (pe = peitr.first(); pe && n; pe = peitr.next()) {
    if (n) n = pe->write_str(rec);
    if (n) n = fprintf (ofp, "%s\n", rec);
  }

  rppEmpDowItr edowitr = empdow_iterator();
  rppEmpDow *edow;
  for (edow = edowitr.first(); edow && n; edow = edowitr.next()) {
    if (n) n = edow->write_str(rec);
    if (n) n = fprintf (ofp, "%s\n", rec);
  }

  rppEmpOffItr eoffitr = empoff_iterator();
  rppEmpOff *eoff;
  for (eoff = eoffitr.first(); eoff && n; eoff = eoffitr.next()) {
    if (n) n = eoff->write_str(rec);
    if (n) n = fprintf (ofp, "%s\n", rec);
  }

  rppAssgnItr assgnitr = assgn_iterator();
  rppAssignment *assgn;
  for (assgn = assgnitr.first(); assgn && n; assgn = assgnitr.next()) {
    if (n) n = assgn->write_str(rec);
    if (n) n = fprintf (ofp, "%s\n", rec);
  }

  rppEmpDayPosItr edpitr = empdaypos_iterator();
  rppEmpDayPos *edp;
  for (edp = edpitr.first(); edp && n; edp = edpitr.next()) {
    if (n) n = edp->write_str(rec);
    if (n) n = fprintf (ofp, "%s\n", rec);
  }

  fclose(ofp);

  if (!n) {
    log("Error writing export file");
    return 0;
  }

  return 1;

}

//----------------------------------------------------------------------
//  Return a pointer to a description of the results of trying to
//  to solve this problem.

const char * rppProblem::get_rslt_desc () const {

  return m_logger->get();

}

//----------------------------------------------------------------------
//  Add a Position-Day 

void rppProblem::add_pos_day (long a_proj_id, long a_pos_id, 
                              long a_yyyymmdd, long a_num_emps_req) {

  rppPosDay *x = new rppPosDay (a_proj_id, a_pos_id, 
                                a_yyyymmdd, a_num_emps_req);

  if (x) m_posdays->add(x);

}

//----------------------------------------------------------------------
//  Add an Employee-Day-of-week

void rppProblem::add_emp_dow (long a_emp_id, long a_dow,
                              long a_start_hhmm, long a_end_hhmm) {

  rppEmpDow *x = new rppEmpDow (a_emp_id, a_dow,
                                a_start_hhmm, a_end_hhmm);

  if (x) m_empdows->add(x);

}

//----------------------------------------------------------------------

⌨️ 快捷键说明

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