Code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#include "queue.h"
struct parameters // struct för parametrarna i kön
{
int randomMinItem;
int randomMaxItem;
int randomMinCustomers;
int randomMaxCustomers;
int itemsPerCycle;
int amountOfCheckouts;
};
struct queue // en struct per kö med pekare mot start och slut på kön
{
struct node *head; // struct pekare
struct node *tail; // struct pekare
};
struct node // struct node för varje människa i kön med antal varor och pekare till nästa
{
int customerItems;
struct node *next;
};
struct customers // struct för att hålla koll på statistik
{
int customersArrived;
int customersServed;
int totalItems;
};
struct parameters *defaultParameters(struct parameters *parameters) // default parametrar!
{
parameters=(struct parameters*)malloc(sizeof(parameters)); // allokerar minne
parameters->randomMinItem=1;
parameters->randomMaxItem=10;
parameters->randomMinCustomers=1;
parameters->randomMaxCustomers=10;
parameters->itemsPerCycle=8;
parameters->amountOfCheckouts=3;
return parameters;
}
struct queue *createArray(struct parameters *parameters) // funktion för att skapa arrayen
{
struct queue *array=NULL;
int checkOut;
int i=0;
checkOut=parameters->amountOfCheckouts; // antal kassor
array=malloc(sizeof(struct queue)*checkOut); // Allokerar minne, en kö för varje checkout i parameters
while(checkOut!=0) // Loopar igenom samtliga köer
{
array[i].head=NULL; // varje array gås igenom och får nullvärde på head
array[i].tail=NULL; // resp tail
i++;
checkOut--; // räknar ner checkout
}
return array;
}
int setParameters(struct parameters *parameters) // Funktion för att ändra parametrar att simulera med
{
int input;
int menubreaker=1;
do
{
system("cls");
printf("Parameters");
printf("\n1. Minimum items");
printf("\n2. Maximum items");
printf("\n3. Minimum customers");
printf("\n4. Maximum customers");
printf("\n5. Amount of checkouts");
printf("\n6. Items per cycle");
printf("\n0. Quit");
printf("\nChoice: ");
if(scanf("%d", &input)&&input>=0&&input<=6)
{
switch(input)
{
case 1:
printf("Minimum items: ");
scanf("%d", ¶meters->randomMinItem);
break;
case 2:
printf("Maximum items: ");
scanf("%d", ¶meters->randomMaxItem);
break;
case 3:
printf("Minimum customers: ");
scanf("%d", ¶meters->randomMinCustomers);
break;
case 4:
printf("Maximum customers: ");
scanf("%d", ¶meters->randomMaxCustomers);
break;
case 5:
printf("Amount of checkouts: ");
scanf("%d", ¶meters->amountOfCheckouts);
break;
case 6:
printf("Items per cycle: ");
scanf("%d", ¶meters->itemsPerCycle);
break;
case 0:
menubreaker=0;
break;
}
}
else
{
printf("Error, not a valid choice.");
printf("\nPress 'Enter' to continue!");
getch();
}
}
while(menubreaker==1);
return 0;
}
// själva köfunktionen
struct queue *runSimulation(struct queue *array, struct node *node, struct parameters *parameters, struct customers *customers)
{
int minutes;
int customersInternal=0;
int tempCustomer=0;
int range=0;
int cycleCounter=1;
customers=(struct customers *)malloc(sizeof(customers)); // Allokerar minne för kunderna.
node=(struct node *)malloc(sizeof(node)); // Allokerar minne för kund.
range=(parameters->randomMaxCustomers-parameters->randomMinCustomers); // kollar spannet för antal varor
customers->customersArrived=0; // sätter Arrived resp Served till 0.
customers->customersServed=0;
customers->totalItems=0;
printf("arrived: %d\n", customers->customersArrived);
printf("served: %d\n", customers->customersServed);
printf("items: %d\n", customers->totalItems);
printf("How long do you want to run(in minutes)?");
printf("\nChoice: ");
scanf("%d", &minutes);
srand(time(0));
system("cls");
while(minutes>0) // Så länge man väljer något över 0
{
system("cls");
printf("\nMinutes: %d", cycleCounter); // Varje cykel är "1" minut
customersInternal=rand()%range+parameters->randomMinCustomers; // randomizer av antal kunder
tempCustomer=customers->customersArrived;
tempCustomer=tempCustomer+customersInternal; // tempCustomer får värdet för customerArrived + randomizer
customers->customersArrived=tempCustomer; // Läggs i customerArrived(randomtalet för antal varor + customersArrived).
selectQueue(customersInternal, array, parameters, node, customers); // välj kö och läggs till i kö
//printf("\nNumbers of customers currently in queue: ");
//traverse(array, node, parameters); // output folk i kassa
removeCustomerFromQueue(array, node, parameters, customers); // ta bort från kö
//printf("\nNumber of customers after service: ");
traverse(array, node, parameters); // mer output om folk i kassakön
minutes--; // räknar ner en minut! (cycle)
cycleCounter++; // räkna cyklerna
}
statistics(customers);// statistik
printf("Press key to continue!");
getch();
fflush(stdin);
int j=0;
struct node *ptr;
struct node *del;
while(j<parameters->amountOfCheckouts) // loopa igenom samtliga
{
ptr=array[j].head;
while(ptr!=array[j].tail)
{
if(array[j].tail!=NULL)
{
del=ptr;
ptr=ptr->next;
free(del); // Free
}
}
array[j].head=NULL; // varje array gås igenom och får nullvärde på head
array[j].tail=NULL;
j++;
}
return array;
}
struct queue *selectQueue(int customersInternal, struct queue *array, struct parameters *parameters, struct node *node, struct customers *customers) // välj kö
{
while(customersInternal>0) // så länge det är över 0
{
array=addCustomerToQueue(array, parameters, node, customers); // in i AddCustomerToQueue
customersInternal--;// loopar igenom hela
}
return 0;
}
struct queue *addCustomerToQueue(struct queue *array, struct parameters *parameters, struct node *node, struct customers *customers) // lägg till i kö
{
int i=0;
int j;
int initFlag=0;// vid 0 är kön tom annars är det någon före.
int range=0;
struct node *temp=NULL; // temp structs
struct node *tempNy=NULL; // temp struct
range=(parameters->randomMaxItem-parameters->randomMinItem); // range för varor
while(i<parameters->amountOfCheckouts&&initFlag==0) // så länge i är mindre än kassor och flaggan är 0**Alltså loopar genom alla kassor
{
if(array[i].head==NULL) // om arrayplatsens head är noll(kassa tom)
{
temp=(struct node *)malloc(sizeof(struct node)); // allokera minne för temp
if(temp!=NULL) // om ok för allokering
{
// printf("\nCheckout %d: ", i+1);
//printf("\nCustomer arrived at checkout %d:\n", i+1); // kunden kommer fram till kassan
temp->next=array[i].head; // sparar pekaren head i fältet next
temp->customerItems=rand()%range+parameters->randomMinItem; // kundens varor är randomizat
// printf("\tCustomer has %d items", temp->customerItems); // kunden har antal varor enligt randomizern
customers->totalItems=customers->totalItems+temp->customerItems;
array[i].head=temp; // flyttar pekare från temp till head
array[i].tail=temp;
initFlag=1; // ändrar flagga
}
}
i++; // plussar i
}
if((initFlag==0)) // Vid 0 flagga så
{
j=isShortest(array, parameters, node); // j får värdet på kortaste kassa
//printf("\nCheckout %d: ", j+1);
// printf("\nCustomer arrived at checkout %d.\n", j+1); // kunden kommer till den kassan
tempNy=(struct node *)malloc(sizeof(struct node)); // allokera minne
tempNy->next=array[j].head; // next pekar på huvudet i aktuell kö
tempNy->customerItems=rand()%range+parameters->randomMinItem; // antal varor blir randomizat
// printf("\tCustomer has %d items", tempNy->customerItems); // kunden har varor
customers->totalItems=customers->totalItems+tempNy->customerItems;
array[j].head=tempNy; // arrayens huvud pekar på tempNy
}
return array;
}
int isShortest(struct queue *array, struct parameters *parameters, struct node *node) // kortast kö
{
int shortest=0;
int i=0;
int count=0;
int baseLine=0;
int baseLineFlag=0;
struct node *ptr;
while(i<parameters->amountOfCheckouts) // så länge i är mindre än kassor ** loopar genom alla kassor
{
//struct node *ptr=array[i].head; // ptr pekar på köns huvud
ptr=array[i].head; // ptr pekar på köns huvud
count=0;
while(ptr!=array[i].tail) // så länge ptrn inte är i slutet
{
ptr=ptr->next; // peka på nästa
count++; // räkna upp
}
if(baseLineFlag==0) // flaggan är 0
{
baseLine=count; // baseline blir count
baseLineFlag=1; // ändrar flagga
}
if(count<=baseLine) // om count är mindre eller samma som baseline
{
baseLine=count; // så blir baseline count
shortest=i; // kortast = i
}
i++;
}
return shortest; // returnera kortast kö
}
void traverse(struct queue *array, struct node *node, struct parameters *parameters) // traversera
{
int count;
int j=0;
int x=0;
struct node *temp;
while(j<parameters->amountOfCheckouts) // loopa genom alla kassor
{
temp=array[j].head; // temp blir huvudet på aktuell kassa
count=0;// räkna från 0
while(temp!=array[j].tail) // så länge temp inte är i slutet
{
temp=temp->next;//frammåt
count++;//plussa
}
if(temp==array[j].tail&&array[j].tail!=NULL)//om sista inte är tom lägg på 1
count++;
j++;
//printf("\nCheckout %d currently have %d customers in queue.", j, count);// output för aktuell kassa j=akteull kassa count=kunder i kassa
printf("\nCheckout %d: ", j);
while(count>x)
{
printf("*");
count--;
}
}
//getch();
}
// ta bort från kö
struct queue* removeCustomerFromQueue(struct queue* array,struct node* node,struct parameters* parameters,struct customers* customers)
{
int i=0;
int time;
while(i<parameters->amountOfCheckouts) // loopa genom alla ksassor
{
time=parameters->itemsPerCycle;// tid blir antalet varor som hinns med per cykel (minut)
while (time>0) // så länge det inte är 0
{
if(array[i].tail!=NULL) // om botten inte är tom
{
if((array[i].tail->customerItems-time)<1) // om köns bottens antal varor minus tid är mindre än 1(finns ingen tid kvar men antal varor är mindre än 1)
{
time=time-array[i].tail->customerItems; // tid får då tid minus bottens varor
array=deleteCustomerFromQueue(array,node,i,customers); // ta bort kund
}
else
{
array[i].tail->customerItems=(array[i].tail->customerItems-time);// antal varor är ursprungsantalvaror - tid
time=time-array[i].tail->customerItems;// tid är tid minus bottens antal varor
}
}
else
time=0;// tiden är slut
}
i++;// fram i arrayen
}
return 0;
}
struct queue *deleteCustomerFromQueue(struct queue *array, struct node *node, int i, struct customers *customers) // ta bort kund
{
int tempDelete;
struct node *temp=array[i].head; // toppen på kön
tempDelete=customers->customersServed;
tempDelete=tempDelete+1;
customers->customersServed=tempDelete; // för att öka på customerServed
while(temp->next!=array[i].tail&&array[i].head!=array[i].tail) //så länge, temps nästa inte är bottem och huvudet inte är botten
{
temp=temp->next;// frammåt
}
if(temp->next==array[i].tail) //om temps nästa är botten
{
free(array[i].tail); // free bottem
array[i].tail=temp; // botten får då next från förra whilesatsen
}
else if(array[i].head==array[i].tail) // annars om topp och botten är samma
{
array[i].head=NULL; // nollar båda
array[i].tail=NULL;
}
return array;// returnera arrayen
}
void statistics(struct customers *customers) // statistik
{
int queue=0;
queue=(customers->customersArrived-customers->customersServed);// kö är kvar - hjälpta
printf("\nTotal customers arrived: %d", customers->customersArrived);//output
printf("\nTotal customers served: %d", customers->customersServed);//output
printf("\nCustomers still in queue: %d", queue);// output
printf("\nTotal items: %d", customers->totalItems);
printf("\nAverage amount of items: %d", customers->totalItems/customers->customersArrived);
printf("\n");
}
void terminate(struct queue *array, struct node *node, struct parameters *parameters)
{
int j=0;
struct node *ptr;
struct node *del;
while(j<parameters->amountOfCheckouts) // loopa igenom samtliga
{
ptr=array[j].head;
while(ptr!=array[j].tail)
{
if(array[j].tail!=NULL)
{
del=ptr;
ptr=ptr->next;
free(del); // Free
}
}
j++;
}
free(array);// Free
}