Beispiel #1
0
void
report (void)			/* Report generator function. */
{
    int i;
    double overall_avg_job_tot_delay, avg_job_tot_delay, sum_probs;

    /* Compute the average total delay in queue for each job type and the
       overall average job total delay. */

    fprintf (outfile, "\n\n\n\nJob type     Average total delay in queue");
    overall_avg_job_tot_delay = 0.0;
    sum_probs = 0.0;
    for (i = 1; i <= num_job_types; ++i)
    {
        avg_job_tot_delay = sampst (0.0, -(num_stations + i)) * num_tasks[i];
        fprintf (outfile, "\n\n%4d%27.3f", i, avg_job_tot_delay);
        overall_avg_job_tot_delay += (prob_distrib_job_type[i] - sum_probs) * avg_job_tot_delay;
        sum_probs = prob_distrib_job_type[i];
    }
    fprintf (outfile, "\n\nOverall average job total delay =%10.3f\n", overall_avg_job_tot_delay);

    /* Compute the average number in queue, the average utilization, and the
       average delay in queue for each station. */

    fprintf (outfile, "\n\n\n Work      Average number      Average       Average delay");
    fprintf (outfile, "\nstation       in queue       utilization        in queue");
    for (j = 1; j <= num_stations; ++j)
        fprintf (outfile, "\n\n%4d%17.3f%17.3f%17.3f", j, filest (j), timest (0.0, -j) / num_machines[j], sampst (0.0, -j));
}
Beispiel #2
0
void
out_timest (FILE * unit, int lowvar, int highvar)
{

/* Write timest statistics for variables lowvar through highvar on file
   "unit". */

  int ivar, iatrr;

  if (lowvar > highvar || lowvar > TIM_VAR || highvar > TIM_VAR)
    return;


  fprintf (unit, "\n  timest");
  fprintf (unit, "\n variable       Time");
  fprintf (unit, "\n  number       average          Maximum          Minimum");
  fprintf (unit, "\n________________________________________________________");
  for (ivar = lowvar; ivar <= highvar; ++ivar)
    {
      fprintf (unit, "\n\n%5d", ivar);
      timest (0.00, -ivar);
      for (iatrr = 1; iatrr <= 3; ++iatrr)
	pprint_out (unit, iatrr);
    }
  fprintf (unit, "\n________________________________________________________");
  fprintf (unit, "\n\n\n");
}
Beispiel #3
0
void
depart (void)			/* Event function for departure of a job from a particular
				   station. */
{
    int station, job_type_queue, task_queue;

    /* Determine the station from which the job is departing. */

    job_type = transfer[3];
    task = transfer[4];
    station = route[job_type][task];

    /* Check to see whether the queue for this station is empty. */

    if (list_size[station] == 0)
    {

        /* The queue for this station is empty, so make a machine in this
           station idle. */

        --num_machines_busy[station];
        timest ((double) num_machines_busy[station], station);
    }

    else
    {

        /* The queue is nonempty, so start service on first job in queue. */

        list_remove (FIRST, station);

        /* Tally this delay for this station. */

        sampst (sim_time - transfer[1], station);

        /* Tally this same delay for this job type. */

        job_type_queue = transfer[2];
        task_queue = transfer[3];
        sampst (sim_time - transfer[1], num_stations + job_type_queue);

        /* Schedule end of service for this job at this station.  Note defining
           attributes beyond the first two for the event record before invoking
           event_schedule. */

        transfer[3] = job_type_queue;
        transfer[4] = task_queue;
        event_schedule (sim_time + erlang (2, mean_service[job_type_queue][task_queue], STREAM_SERVICE), EVENT_DEPARTURE);
    }

    /* If the current departing job has one or more tasks yet to be done, send
       the job to the next station on its route. */

    if (task < num_tasks[job_type])
    {
        ++task;
        arrive (2);
    }
}
Beispiel #4
0
double
filest (int list)
{

/* Report statistics on the length of list "list" in transfer:
       [1] = time-average of list length updated to the time of this call
       [2] = maximum length list has attained
       [3] = minimum length list has attained
   This uses timest variable TIM_VAR + list. */

  return timest (0.0, -(TIM_VAR + list));
}
Beispiel #5
0
void
init_simlib ()
{

/* Initialize simlib.c.  List LIST_EVENT is reserved for event list, ordered by
   event time.  init_simlib must be called from main by user. */

  int list, listsize;

  if (maxlist < 1)
    maxlist = MAX_LIST;
  listsize = maxlist + 1;

  /* Initialize system attributes. */

  sim_time = 0.0;
  if (maxatr < 4)
    maxatr = MAX_ATTR;

  /* Allocate space for the lists. */

  list_rank = (int *) calloc (listsize, sizeof (int));
  list_size = (int *) calloc (listsize, sizeof (int));
  head = (struct master **) calloc (listsize, sizeof (struct master *));
  tail = (struct master **) calloc (listsize, sizeof (struct master *));
  transfer = (double *) calloc (maxatr + 1, sizeof (double));

  /* Initialize list attributes. */

  for (list = 1; list <= maxlist; ++list)
    {
      head[list] = NULL;
      tail[list] = NULL;
      list_size[list] = 0;
      list_rank[list] = 0;
    }

  /* Set event list to be ordered by event time. */

  list_rank[LIST_EVENT] = EVENT_TIME;

  /* Initialize statistical routines. */

  sampst (0.0, 0);
  timest (0.0, 0);
}
Beispiel #6
0
void plane_land(int plane_type, int plane_id) {
    /* Add the plane in transfer to the runway queue */
    transfer[PLANE_ID] = plane_id;
    transfer[TIME_LANDED] = sim_time/60;
    transfer[EVENT_TYPE] = plane_type;
    list_file(LAST, LIST_RUNWAY);

    /* Add the event to the log list */
    log_event(sim_time, plane_type, taxi_state, plane_id, storm_state, 0);

    /* update time statistics for runway queue */
    timest((float)sim_time - transfer[TIME_LANDED], TIMEST_RUNWAY);
    transfer[1] = sim_time;
    transfer[2] = list_size[LIST_RUNWAY];
    list_file(INCREASING, LIST_AVG_PLANES_RUNWAY);

    /* Add plane to in-port residence time list */
    transfer[PLANE_ID] = plane_id;
    transfer[TIME_LANDED] = sim_time;
    transfer[PLANE_TYPE] = plane_type;
    list_file(INCREASING, LIST_PLANE_PORT_TIME);
}
Beispiel #7
0
void
arrive (int new_job)		/* Function to serve as both an arrival event of a job
				   to the system, as well as the non-event of a job's
				   arriving to a subsequent station along its
				   route. */
{
    int station;

    /* If this is a new arrival to the system, generate the time of the next
       arrival and determine the job type and task number of the arriving
       job. */


    if (new_job == 1)
    {

        event_schedule (sim_time + expon (mean_interarrival, STREAM_INTERARRIVAL), EVENT_ARRIVAL);
        job_type = intrand (prob_distrib_job_type, STREAM_JOB_TYPE);
        task = 1;
    }

    /* Determine the station from the route matrix. */

    station = route[job_type][task];

    /* Check to see whether all machines in this station are busy. */

    if (num_machines_busy[station] == num_machines[station])
    {

        /* All machines in this station are busy, so place the arriving job at
           the end of the appropriate queue. Note that the following data are
           stored in the record for each job:
           1. Time of arrival to this station.
           2. Job type.
           3. Current task number. */

        transfer[1] = sim_time;
        transfer[2] = job_type;
        transfer[3] = task;
        list_file (LAST, station);
    }

    else
    {

        /* A machine in this station is idle, so start service on the arriving
           job (which has a delay of zero). */

        sampst (0.0, station);	/* For station. */
        sampst (0.0, num_stations + job_type);	/* For job type. */
        ++num_machines_busy[station];
        timest ((double) num_machines_busy[station], station);

        /* Schedule a service completion.  Note defining attributes beyond the
           first two for the event record before invoking event_schedule. */

        transfer[3] = job_type;
        transfer[4] = task;
        event_schedule (sim_time + erlang (2, mean_service[job_type][task], STREAM_SERVICE), EVENT_DEPARTURE);
    }
}
Beispiel #8
0
void end_warmup()
{
    sampst(0.0, 0); 
    timest(0.0, 0);
    skaut_throughput = 0;
}
Beispiel #9
0
int main() {

    FILE *plane_list,
         *storm_list,
         *output_log_verbose,
         *output_log,
         *output_log_read,
         *verification_log,
         *statistics_log;

    //int sim_length = TIME_YEAR;

    init_simlib();

    /* Set the log list to be ordered by event time */
    list_rank[LIST_LOG] = EVENT_TIME;

    /* Set the in-port residence time list to be ordered by plane id */
    list_rank[LIST_PLANE_PORT_TIME] = PLANE_ID;

    list_rank[LIST_AVG_PLANES_RUNWAY] = EVENT_TIME;
    list_rank[LIST_AVG_PLANES_DEBERTH] = EVENT_TIME;

    /* Set max attributes in a list to 9, for simlog */
    maxatr = 10;

    storm_state = STORM_OFF;
    taxi_state  = TAXI_IDLE;

    int i;
    for (i=0; i<NUMBER_OF_BERTHS; i++) {
        berths[i].state = BERTH_FREE;
        berths[i].time_unoccupied_last = 0;
        berths[i].time_unoccupied = 0;
        berths[i].time_loading = 0;
        berths[i].time_loading_last = 0;
        berths[i].time_occupied = 0;
        berths[i].time_occupied_last = 0;
    }

    stats.taxi_time_idle = 0;
    stats.taxi_time_idle_last = 0;
    stats.taxi_time_travelling = 0;
    stats.taxi_time_travelling_last = 0;
    stats.taxi_time_berthing_deberthing = 0;
    stats.taxi_time_berthing_deberthing_last = 0;

    /* initialize timest */
    timest(0.0, 0);

    /* Load the input paramters for times and such */
    FILE *input = fopen("config.ini", "r");
    verification_log = fopen("verification.log", "w");
    load_input_file(input, verification_log);
    fclose(input);

    /* initialize berths array to specified size */
    //berths = (struct berth *)malloc(sizeof(struct berth)*G.num_berths);

    /* Generate the plane and storm list */
    generate_input_files();

    /* Schedule the plane landing and storm events using the input lists*/
    plane_list = fopen("plane_list.dat", "r");
    storm_list = fopen("storm_list.dat", "r");
    schedule_input_list(plane_list);
    schedule_input_list(storm_list);
    fclose(plane_list);
    fclose(storm_list);

    plane_list = fopen("plane_list.dat", "r");
    storm_list = fopen("storm_list.dat", "r");
    verify_actors(storm_list, plane_list, verification_log);
    fclose(plane_list);
    fclose(storm_list);

    while(list_size[LIST_EVENT] != 0) {

        timing();

        /* If sim time passes a year, exit the simulation. */
        if ((int)sim_time>=G.sim_length) {//TIME_YEAR) {
            if (taxi_state == TAXI_IDLE)
                stats.taxi_time_idle += G.sim_length - stats.taxi_time_idle_last;
            if (taxi_state == TAXI_TRAVELLING_BERTHS || taxi_state == TAXI_TRAVELLING_RUNWAY)
                stats.taxi_time_travelling += G.sim_length - stats.taxi_time_travelling_last;
            if (taxi_state == TAXI_BERTHING || taxi_state == TAXI_DEBERTHING)
                stats.taxi_time_berthing_deberthing += G.sim_length - stats.taxi_time_berthing_deberthing_last;

            /*  Because the stats.taxi_time_travelling isn't quite getting all of the time
                but I know that the idle and berthing/deberthing times are correct,
                I'm cheating and using those to figure out the travelling time. */
            stats.taxi_time_travelling = G.sim_length - stats.taxi_time_idle - stats.taxi_time_berthing_deberthing;
            break;
        }

        /*
        printf("%.1f  %.1f  %s  %s\n", sim_time/60,
                                       stats.taxi_time_berthing_deberthing/60.0f,
                                       strings_event[(int)transfer[EVENT_TYPE]],
                                       strings_taxi[taxi_state]);
                                       */

        /* Main event handler switch */
        switch(next_event_type) {

            case EVENT_LAND1:
            case EVENT_LAND2:
            case EVENT_LAND3:
                plane_land(next_event_type, transfer[EVENT_PLANE_ID]);
                break;
            case EVENT_STORM_START:
                storm_start();
                break;
            case EVENT_STORM_END:
                storm_end();
                break;
            case EVENT_BERTH:
                berth(transfer[BERTH_NUMBER]);
                break;
            case EVENT_DEBERTH:
                deberth(transfer[BERTH_NUMBER]);
                break;
            case EVENT_FINISH_LOADING:
                finish_loading(transfer[BERTH_NUMBER]);
                break;
            case EVENT_BERTH_FINISH:
                berth_finish(transfer[BERTH_NUMBER]);
                break;
            case EVENT_DEBERTH_FINISH:
                deberth_finish(transfer[BERTH_NUMBER]);
                break;
            case EVENT_TAXI_RETURNS_IDLE:
                taxi_returns();
                break;
        }

        if (sim_time == 129705)
            printf("%d\n", taxi_state == TAXI_IDLE);

        /* Taxi handler */
        switch (taxi_state) {
            case TAXI_IDLE:
                taxi_idle();
                break;
            case TAXI_TRAVELLING_RUNWAY:
                taxi_travelling_runway();
                break;
            case TAXI_TRAVELLING_BERTHS:
                taxi_travelling_berths();
                break;
            case TAXI_BERTHING:
                taxi_berthing();
                break;
            case TAXI_DEBERTHING:
                taxi_deberthing();
                break;
        }
    }// end simulation loop

    printf("Log list size: %d\n", list_size[LIST_LOG]);

    output_log_verbose = fopen("output_log_verbose.csv", "w");
    save_log_file_verbose(output_log_verbose);
    fclose(output_log_verbose);

    output_log = fopen("output_log.csv", "w");
    save_log_file(output_log);
    fclose(output_log);
    /*
    output_log = fopen("output_log.csv", "w");
    //verify_output(output_log, verification_log);
    fclose(output_log);
    fclose(verification_log);
    */
    statistics_log = fopen("statistics.log", "w");
    generate_statistics(statistics_log);
    fclose(statistics_log);

    /*  Clean up files  */
    remove("plane_list.dat");
    remove("storm_list.dat");
    remove("storm_list.csv");
}
Beispiel #10
0
void
list_file (int option, int list)
{

/* Place transfr into list "list".
   Update timest statistics for the list.
   option = FIRST place at start of list
            LAST  place at end of list
            INCREASING  place in increasing order on attribute list_rank(list)
            DECREASING  place in decreasing order on attribute list_rank(list)
            (ties resolved by FIFO) */

  struct master *row=NULL, *ahead, *behind, *ihead, *itail;
  int item, postest;

  /* If the list value is improper, stop the simulation. */

  if (!((list >= 0) && (list <= MAX_LIST)))
    {
      printf ("\nInvalid list %d for list_file at time %f\n", list, sim_time);
      exit (1);
    }

  /* Increment the list size. */

  list_size[list]++;

  /* If the option value is improper, stop the simulation. */

  if (!((option >= 1) && (option <= DECREASING)))
    {
      printf ("\n%d is an invalid option for list_file on list %d at time %f\n", option, list, sim_time);
      exit (1);
    }

  /* If this is the first record in this list, just make space for it. */

  if (list_size[list] == 1)
    {

      row = (struct master *) malloc (sizeof (struct master));
      head[list] = row;
      tail[list] = row;
      (*row).pr = NULL;
      (*row).sr = NULL;
    }

  else
    {				/* There are other records in the list. */

      /* Check the value of option. */

      if ((option == INCREASING) || (option == DECREASING))
	{
	  item = list_rank[list];
	  if (!((item >= 1) && (item <= maxatr)))
	    {
	      printf ("%d is an improper value for rank of list %d at time %f\n", item, list, sim_time);
	      exit (1);
	    }

	  row = head[list];
	  behind = NULL;	/* Dummy value for the first iteration. */

	  /* Search for the correct location. */

	  if (option == INCREASING)
	    {
	      postest = (transfer[item] >= (*row).value[item]);
	      while (postest)
		{
		  behind = row;
		  row = (*row).sr;
		  postest = (behind != tail[list]);
		  if (postest)
		    postest = (transfer[item] >= (*row).value[item]);
		}
	    }

	  else
	    {

	      postest = (transfer[item] <= (*row).value[item]);
	      while (postest)
		{
		  behind = row;
		  row = (*row).sr;
		  postest = (behind != tail[list]);
		  if (postest)
		    postest = (transfer[item] <= (*row).value[item]);
		}
	    }

	  /* Check to see if position is first or last.  If so, take care of
	     it below. */

	  if (row == head[list])

	    option = FIRST;

	  else
	   if (behind == tail[list])

	    option = LAST;

	  else
	    {			/* Insert between preceding and succeeding records. */

	      ahead = (*behind).sr;
	      row = (struct master *) malloc (sizeof (struct master));
	      (*row).pr = behind;
	      (*behind).sr = row;
	      (*ahead).pr = row;
	      (*row).sr = ahead;
	    }
	}			/* End if inserting in increasing or decreasing order. */

      if (option == FIRST)
	{
	  row = (struct master *) malloc (sizeof (struct master));
	  ihead = head[list];
	  (*ihead).pr = row;
	  (*row).sr = ihead;
	  (*row).pr = NULL;
	  head[list] = row;
	}
      if (option == LAST)
	{
	  row = (struct master *) malloc (sizeof (struct master));
	  itail = tail[list];
	  (*row).pr = itail;
	  (*itail).sr = row;
	  (*row).sr = NULL;
	  tail[list] = row;
	}
    }

  /* Copy the data. */

  (*row).value = transfer;

  /* Make room for new transfer. */

  transfer = (double *) calloc (maxatr + 1, sizeof (double));

  /* Update the area under the number-in-list curve. */

  timest ((double) list_size[list], TIM_VAR + list);
}
Beispiel #11
0
int
event_cancel (int event_type)
{

/* Remove the first event of type event_type from the event list, leaving its
   attributes in transfer.  If something is cancelled, event_cancel returns 1;
   if no match is found, event_cancel returns 0. */

  struct master *row, *ahead, *behind;
  static double high, low, value;

  /* If the event list is empty, do nothing and return 0. */

  if (list_size[LIST_EVENT] == 0)
    return 0;

  /* Search the event list. */

  row = head[LIST_EVENT];
  low = event_type - EPSILON;
  high = event_type + EPSILON;
  value = (*row).value[EVENT_TYPE];

  while (((value <= low) || (value >= high)) && (row != tail[LIST_EVENT]))
    {
      row = (*row).sr;
      value = (*row).value[EVENT_TYPE];
    }

  /* Check to see if this is the end of the event list. */

  if (row == tail[LIST_EVENT])
    {

      /* Double check to see that this is a match. */

      if ((value > low) && (value < high))
	{
	  list_remove (LAST, LIST_EVENT);
	  return 1;
	}

      else			/* no match */
	return 0;
    }

  /* Check to see if this is the head of the list.  If it is at the head, then
     it MUST be a match. */

  if (row == head[LIST_EVENT])
    {
      list_remove (FIRST, LIST_EVENT);
      return 1;
    }

  /* Else remove this event somewhere in the middle of the event list. */

  /* Update pointers. */

  ahead = (*row).sr;
  behind = (*row).pr;
  (*behind).sr = ahead;
  (*ahead).pr = behind;

  /* Decrement the size of the event list. */

  list_size[LIST_EVENT]--;

  /* Copy and free memory. */

  free ((char *) transfer);	/* Free the old transfer. */
  transfer = (*row).value;	/* Transfer the data. */
  free ((char *) row);		/* Free the space vacated by row. */

  /* Update the area under the number-in-event-list curve. */

  timest ((double) list_size[LIST_EVENT], TIM_VAR + LIST_EVENT);
  return 1;
}
Beispiel #12
0
void
list_remove (int option, int list)
{

/* Remove a record from list "list" and copy attributes into transfer.
   Update timest statistics for the list.
   option = FIRST remove first record in the list
            LAST  remove last record in the list */

  struct master *row = NULL, *ihead, *itail;

  /* If the list value is improper, stop the simulation. */

  if (!((list >= 0) && (list <= MAX_LIST)))
    {
      printf ("\nInvalid list %d for list_remove at time %f\n", list, sim_time);
      exit (1);
    }

  /* If the list is empty, stop the simulation. */

  if (list_size[list] <= 0)
    {
      printf ("\nUnderflow of list %d at time %f\n", list, sim_time);
      exit (1);
    }

  /* Decrement the list size. */

  list_size[list]--;

  /* If the option value is improper, stop the simulation. */

  if (!(option == FIRST || option == LAST))
    {
      printf ("\n%d is an invalid option for list_remove on list %d at time %f\n", option, list, sim_time);
      exit (1);
    }

  if (list_size[list] == 0)
    {

      /* There is only 1 record, so remove it. */

      row = head[list];
      head[list] = NULL;
      tail[list] = NULL;
    }

  else
    {

      /* There is more than 1 record, so remove according to the desired
         option. */

      switch (option)
	{

	  /* Remove the first record in the list. */

	case FIRST:
	  row = head[list];
	  ihead = (*row).sr;
	  (*ihead).pr = NULL;
	  head[list] = ihead;
	  break;

	  /* Remove the last record in the list. */

	case LAST:
	  row = tail[list];
	  itail = (*row).pr;
	  (*itail).sr = NULL;
	  tail[list] = itail;
	  break;
	}
    }

  /* Copy the data and free memory. */

  free ((char *) transfer);
  transfer = (*row).value;
  free ((char *) row);

  /* Update the area under the number-in-list curve. */

  timest ((double) list_size[list], TIM_VAR + list);
}