aboutsummaryrefslogtreecommitdiffstats
path: root/test/ccured_olden/health/health.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/ccured_olden/health/health.c')
-rw-r--r--test/ccured_olden/health/health.c309
1 files changed, 309 insertions, 0 deletions
diff --git a/test/ccured_olden/health/health.c b/test/ccured_olden/health/health.c
new file mode 100644
index 00000000..6de1d0d7
--- /dev/null
+++ b/test/ccured_olden/health/health.c
@@ -0,0 +1,309 @@
+/* For copyright information, see olden_v1.0/COPYRIGHT */
+
+/*******************************************************************
+ * Health.c : Model of the Colombian Health Care System *
+ *******************************************************************/
+#ifdef SS_PLAIN
+#include "ssplain.h"
+#endif SS_PLAIN
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "health.h"
+#include <assert.h>
+
+struct Village *alloc_tree(int level, int label, struct Village *back)
+{
+ if (level == 0)
+ {
+ return NULL;
+ }
+ else
+ {
+ int i;
+ struct Village *new;
+
+ new = (struct Village *)malloc(sizeof(struct Village));
+
+ new->back = back;
+ new->label = label;
+ new->seed = label * (IQ + seed);
+ new->hosp.personnel = (int)pow(2, level - 1);
+ new->hosp.free_personnel = new->hosp.personnel;
+ new->hosp.num_waiting_patients = 0;
+ new->hosp.assess.forward = NULL;
+ new->hosp.assess.back = NULL;
+ new->hosp.waiting.forward = NULL;
+ new->hosp.waiting.back = NULL;
+ new->hosp.inside.forward = NULL;
+ new->hosp.inside.back = NULL;
+ new->returned.back = NULL;
+ new->returned.forward = NULL;
+
+ for (i = 0; i < 4; i++)
+ new->forward[i] =
+ alloc_tree(level - 1, (label * 4) + i + 1, new);
+
+ return new;
+ }
+}
+
+
+struct Results get_results(struct Village *village)
+{
+ int i;
+ struct List *list;
+ struct Patient *p;
+ struct Village *v;
+ struct Results r1;
+
+ r1.total_hosps = 0.0;
+ r1.total_patients = 0.0;
+ r1.total_time = 0.0;
+
+ if (village == NULL) return r1;
+
+ for (i = 0; i < 4; i++ ) {
+ struct Results res;
+
+ v = village->forward[i];
+ res = get_results(v);
+
+ r1.total_hosps += res.total_hosps;
+ r1.total_patients += res.total_patients;
+ r1.total_time += res.total_time;
+ }
+
+ list = village->returned.forward;
+ while (list != NULL) {
+ p = list->patient;
+ r1.total_hosps += (float)(p->hosps_visited);
+ r1.total_time += (float)(p->time);
+ r1.total_patients += 1.0;
+ list = list->forward;
+ }
+
+ return r1;
+}
+
+
+void check_patients_inside(struct Village *village, struct List *list)
+{
+ struct Patient *p;
+
+ while (list != NULL)
+ {
+
+ p = list->patient;
+ p->time_left--;
+
+ if (p->time_left == 0)
+ {
+ village->hosp.free_personnel++;
+ removeList(&(village->hosp.inside), p);
+ addList(&(village->returned), p);
+ }
+ list = list->forward;
+ }
+}
+
+
+struct List *check_patients_assess(struct Village *village, struct List *list)
+{
+ float rand;
+ struct Patient *p;
+ int label;
+
+ while (list != NULL)
+ {
+ p = list->patient;
+ p->time_left--;
+ label = village->label;
+
+ if (p->time_left == 0)
+ {
+ rand = my_rand(village->seed);
+ village->seed = (long)(rand * IM);
+ label = village->label;
+
+ if (rand > 0.1 || label == 0)
+ {
+ removeList(&(village->hosp.assess), p);
+ addList(&(village->hosp.inside), p);
+ p->time_left = 10;
+ p->time += p->time_left;
+ }
+ else
+ {
+ village->hosp.free_personnel++;
+ removeList(&(village->hosp.assess), p);
+ addList(&(village->hosp.up), p);
+ }
+ }
+
+ list = list->forward;
+ }
+ return &(village->hosp.up);
+}
+
+
+void check_patients_waiting(struct Village *village, struct List *list)
+{
+ int i;
+ struct Patient *p;
+
+ while (list != NULL)
+ {
+ i = village->hosp.free_personnel;
+ p = list->patient; /* This is a bad load */
+
+ if (i > 0)
+ {
+ village->hosp.free_personnel--;
+ p->time_left = 3;
+ p->time += p->time_left;
+ removeList(&(village->hosp.waiting), p);
+ addList(&(village->hosp.assess), p);
+ }
+ else
+ {
+ p->time++; /* so is this */
+ }
+ list = list->forward;
+ }
+}
+
+
+void put_in_hosp(struct Hosp *hosp, struct Patient *patient)
+{
+ patient->hosps_visited++;
+
+ if (hosp->free_personnel > 0)
+ {
+ hosp->free_personnel--;
+ addList(&(hosp->assess), patient);
+ patient->time_left = 3;
+ patient->time += patient->time_left;
+ }
+ else
+ {
+ addList(&(hosp->waiting), patient);
+ }
+}
+
+
+struct Patient *generate_patient(struct Village *village)
+{
+ struct Patient *patient = NULL;
+ float rand;
+
+ rand = my_rand(village->seed);
+ village->seed = (long)(rand * IM);
+
+ if (rand > 0.666)
+ {
+ patient = (struct Patient *)mymalloc(sizeof(struct Patient));
+ patient->hosps_visited = 0;
+ patient->time = 0;
+ patient->time_left = 0;
+ patient->home_village = village;
+ }
+
+ return patient;
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct Results results;
+ struct Village *top;
+ long i;
+ float total_time,
+ total_patients,
+ total_hosps;
+
+ dealwithargs(argc, argv);
+
+ top = alloc_tree(max_level, 0, NULL);
+
+ chatting("\n\n Colombian Health Care Simulator\n\n");
+ chatting("Working...\n");
+
+ // sm: changed "%d" to "%ld" to silence gcc warning
+ fprintf(stderr, "This is max_time right before the loop: %ld\n", max_time);
+ for (i = 0; i < max_time; i++)
+ {
+ //printf("This is i with each iteration: %d\n", i);
+ if ((i % 10) == 0)
+ chatting("iteration %d\n", i);
+ sim(top);
+ }
+
+ results = get_results(top);
+ total_patients = results.total_patients;
+ total_time = results.total_time;
+ total_hosps = results.total_hosps;
+
+ chatting("Done.\n\n");
+ chatting("# of people treated: %f people\n",
+ total_patients);
+ chatting("Average length of stay: %f time units\n",
+ total_time / total_patients);
+ chatting("Average # of hospitals visited: %f hospitals\n\n",
+ total_hosps / total_patients);
+ return 0;
+}
+
+
+struct List *sim(struct Village *village)
+{
+ int i;
+ struct Patient *patient, *p;
+ struct List *l, *vl, *up;
+
+ if (village == NULL)
+ return NULL;
+
+ for (i = 0; i < 4; i++)
+ {
+ l = vl = sim(village->forward[i]);
+
+ if (l != NULL)
+ {
+ l = l->forward;
+ while (l != NULL)
+ {
+ p = l->patient;
+ put_in_hosp(&(village->hosp), p);
+ removeList(vl, p);
+ l = l->forward;
+ }
+ }
+ }
+
+
+ /* Uses lists inside, and return */
+ check_patients_inside(village, village->hosp.inside.forward);
+
+ /* Uses lists assess, inside, and up */
+ up = check_patients_assess(village, village->hosp.assess.forward);
+
+ /* Uses lists waiting, and assess */
+ check_patients_waiting(village, village->hosp.waiting.forward);
+
+ if ((patient = generate_patient(village)) != NULL)
+ {
+ put_in_hosp(&(village->hosp), patient);
+ }
+
+ return up;
+}
+
+
+
+
+
+
+
+