Example

This example is a resource selection rule that will select the next job based on the standard resource selection number 17, which is Changeover Processing Time/Long Wait. When the standard rule 17 is called it will rank candidates in one of two ways: 1) if there will not be a setup, then jobs are ranked by setup time, then by waiting time, or 2) if there will be a setup, then jobs are ranked by waiting time for all jobs that will change the setup. The problem with the standard rule is that there is no secondary ranking rule, in other words, ties in waiting time are not broken in any explainable way. This rule will change that processing slightly by breaking ties in waiting time using the resource’s sequencing rule. This processing can now be done with the standard product using the Tiered Selection Rule.

Below is a description of each function in the code:

ucini1

Install the rule function, rsel_25, as rule number 25.

ucini2

Set the type of any resource that uses rule 25 to 3. This will cause the data to be collected for cumulative processing time. Other choices for the type are 0 (most standard rules), 1 (number of jobs – used by standard rules 12 and 13), 2 (number of items – used by standard rules 14 and 15), 3 (accumulated processing time - used by standard rules 16 and 17), and 4 (elapsed time – used by standard rules 18 and 19).

rsel_25

  • Set pCurRes as pointer to the resource, which will be used by a function later.
  • Call the standard rule 17 (function
  • serqsl) which will create a sequenced list of candidate jobs.
  • Set rprio1 as the priority value of the first job in the prioritized list.
  • If the number of candidates (numreq) is equal to the number in the queue and the priority of the first job is not zero (setup time), then we are changing setups and the list is currently ranked by waiting time with all non-zero setups at the top of the list. In this case, ties in waiting time will be broken by the sequencing rule. The function
  • cssols reorders the list with the function rqor25seq being a comparison function for a pair of jobs on the list. cssols goes through the list comparing jobs by twos until an ordered list by waiting time and sequencing rule is achieved.
  • Else if the number of candidates is greater than zero, then we are not changing setups. In this case, ties in setup time will be broken by waiting time, while ties in waiting time (within the same setup time) will be broken by the sequencing rule. The function
  • cssols reorders the list with the function rqor25wt being a comparison function for a pair of jobs on the list. cssols goes through the list comparing jobs by twos until an ordered list by setup time (either positive or zero), waiting time, and sequencing rule is achieved.
  • Else if the number of candidates is zero, then we have not yet reached the desired number of setups and a Setup Delay is being scheduled.
  • Function
  • rsel_25 returns the number of jobs in priority order to be considered for allocation.

rqor25seq

  • This function compares two jobs based on priority (waiting time) and if there is a tie, attempts to break the tie based on the sequencing rule.
  • Return values are: -1: request 1 has higher priority, 1: request 2 has higher priority, and 0: requests are equal priority.

rqor25wt

  • This function compares two jobs based on priority (setup time), and if there is a tie, attempts to break the tie based on waiting time, and if there is still a tie, attempts to break the tie based on the sequencing rule.
  • Return values are: -1: request 1 has higher priority, 1: request 2 has higher priority, and 0: requests are equal priority.

Below is the actual user code representing the case described above:


#include "factor.h"

RESRC *pCurRes;

static int rsel_25(RESRC *rp);
static int rqor25seq(CSENTITY *ep1, CSENTITY *ep2);
static int rqor25wt(CSENTITY *ep1, CSENTITY *ep2);

void ucini1(void)
{
  sedfsl(25, rsel_25);
}

void ucini2(void)
{
  RESRC *pstRes;

  /* set selection rule type for user-written rules */
  for (pstRes = (RESRC *) csfsls(ssgvar.sgresrc); pstRes != NULL;
     pstRes = (RESRC *) csnxls((CSENTITY *) pstRes))
  {
    if (pstRes->rsslrl == 25)
    {
      pstRes->rssltype = 3;
    }
  }
}

int rsel_25 (RESRC *rp)
/* Resource selection rule 25 for Changeover Processing Time/Longest
  Wait/Sequence Rule */
{
  int numreq;
  RREQ *rq;
  double rprio1 = 0.0;

  /* Set resource pointer for later use */
  pCurRes = rp;

  /* Call standard rule 17 (Changeover P.T./Longest Wait) */
  numreq = serqsl(rp, 17);

  /* Get priority of first load waiting */
  rq = (RREQ *) csfsls(rp->rsrqls);
  if (rq != NULL)
  {
    rprio1 = rq->rrprio;
  }

  /* There is going to be a change so use sequencing rule as secondary 
    ranking, i.e. considering all requests and first is non-zero setup
    time */
  if (numreq == csszls((CSENTITY *) rp->rsrqls) && rprio1 > 0.0)
  {
    /* Sort list based on changover then sequencing rule. */
    cssols(rp->rsrqls, rqor25seq);
  }

  /* Need to rank zero setups by Waiting Time, then sequencing rule */
  else if (numreq > 0)
  {
    cssols(rp->rsrqls, rqor25wt);
  }

  return(numreq);
}

static int rqor25seq(CSENTITY *ep1, CSENTITY *ep2)
/*----------------------------------------------------------------------
    Ordering (comparison) function to return the relationship of
    resource requests based on the following tiered criteria:

       Current priority
       Sequencing rule value

    Args:
     ep1 - pointer to resource request 1
     ep2 - pointer to resource request 2

    Returns:
     -1 - request 1 should go before request 2 in list
     0 - request 1 has same priority as request 2
     1 - request 1 should go after request 2 in list

----------------------------------------------------------------------*/
{
    RREQ *rq1, *rq2;
    double rv1, rv2;

    rq1 = (RREQ *) ep1;
    rq2 = (RREQ *) ep2;

    /* Return if order priorities are not equal */
    if (rq1->rrprio < rq2->rrprio)
      return(-1);
    if (rq1->rrprio > rq2->rrprio)
      return(1);

    /* If still tied break based on sequencing rule. */
    rv1 = selork(rq1->rrload, pCurRes->rssqrl, NULL);
    rv2 = selork(rq2->rrload, pCurRes->rssqrl, NULL);

    if (rv1 < rv2)
      return(-1);
    if (rv1 > rv2)
      return(1);
    return(0);
}



static int rqor25wt(CSENTITY *ep1, CSENTITY *ep2)
/*----------------------------------------------------------------------
    Ordering (comparison) function to return the relationship of
    resource requests based on the following tiered criteria:
       Current priority
       Sequencing rule value

    Args:
     ep1 - pointer to resource request 1
     ep2 - pointer to resource request 2

    Returns:
     -1 - request 1 should go before request 2 in list
     0 - request 1 has same priority as request 2
     1 - request 1 should go after request 2 in list

----------------------------------------------------------------------*/
{
    RREQ *rq1, *rq2;
    double rv1 = 0.0, rv2 = 0.0;
    CSENTHD *hp1, *hp2;

    rq1 = (RREQ *) ep1;
    rq2 = (RREQ *) ep2;

    /* Return if order priorities are not equal */

    if (rq1->rrprio < rq2->rrprio)
      return(-1);
    if (rq1->rrprio > rq2->rrprio)
      return(1);

    /* If tied break based on waiting time. */
    hp1 = (CSENTHD *)rq1;
    --hp1;
    rv1 = hp1->_letime;
    hp2 = (CSENTHD *)rq2;
    --hp2;
    rv2 = hp2->_letime;

    if (rv1 < rv2)
      return(-1);
    if (rv1 > rv2)
      return(1);

    /* If still tied break based on sequencing rule. */
    rv1 = selork(rq1->rrload, pCurRes->rssqrl, NULL);
    rv2 = selork(rq2->rrload, pCurRes->rssqrl, NULL);

    if (rv1 < rv2)
      return(-1);
    if (rv1 > rv2)
      return(1);

    /* still tied return 0 */
    return(0);
}