/* -------------------------------------------------------------------- * ADD ARC */ void tg_add_arc(tg graph, tg_task task_from, tg_task task_to) { tg_ptask pfrom, pto; /* 1. CHECK TASKS IDENTIFIERS */ if (!tg_id(graph, task_from) || !tg_id(graph,task_to)) Asystem_error("tg_add_arc","Unknown task","Cheking task ids"); /* 2. OBTAINING POINTERS */ pfrom = tgp(graph, task_from); pto = tgp(graph, task_to); /* 3. IF ARC ALREADY EXISTS, RETURN */ if (tg_arc(graph, task_from, task_to)) return; /* 4. CREATING SPACE IN NODES */ pfrom->succnum ++; pto->prenum ++; pfrom->succ = (task_list)realloc(pfrom->succ, sizeof(tg_task)*(pfrom->succnum)); if ( pfrom->succ == NULL ) { Asystem_error("tg_add_arc", "Not enough memory", "pfrom->succ"); } pto->pred = (task_list)realloc(pto->pred, sizeof(tg_task)*(pto->prenum)); if ( pto->pred == NULL ) { Asystem_error("tg_add_arc", "Not enough memory", "pto->pred"); } /* 5. INITIALIZATING POINTERS */ pfrom->succ[ pfrom->succnum -1 ] = task_to; pto->pred[ pto->prenum -1 ] = task_from; }
/* -------------------------------------------------------------------- * DELETE NODE */ void tg_del_node(tg graph, tg_task task) { int count; task_list todelete=NULL; int elements; /* 0. CHECKING IDENTIFICATION */ if (!tg_id(graph, task)) return; /* 1. DELETING ARCS */ elements = tg_pred_num(graph,task); todelete = (task_list) malloc( sizeof(tg_task) * elements ); if ( todelete == NULL ) { Asystem_error("tg_del_node", "Not enough memory", "todelete 1"); } memcpy(todelete, tg_pred(graph,task), sizeof(tg_task)*elements); for (count=0; count < elements; count ++ ) { tg_del_arc(graph, todelete[count], task); } free(todelete); todelete=NULL; elements = tg_succ_num(graph,task); todelete = (task_list) malloc( sizeof(tg_task) * elements ); if ( todelete == NULL ) { Asystem_error("tg_del_node", "Not enough memory", "todelete 2"); } memcpy(todelete, tg_succ(graph,task), sizeof(tg_task)*elements); for (count=0; count < elements; count ++ ) { tg_del_arc(graph, task, todelete[count]); } free(todelete); todelete=NULL; /* 2. FREEING INTERNAL SPACE */ free(tgp(graph,task)->resour); tgp(graph,task)->resour = NULL; /* 3. FREEING TASK SPACE */ free(tgp(graph,task)); tgp(graph,task) = NULL; /* 4. CHANGING GRAPH STRUCTURE */ graph->tasknum --; graph->idarray[task] = NULL; if (task == graph->maxid) graph->maxid --; /* Innecesary reallocate */ /* 5. END */ }
/* -------------------------------------------------------------------- * MOVE PREDECESORS FROM A NODE TO ANOTHER */ void tg_move_pred(tg graph, tg_task task_orig, tg_task task_dest) { task_list predlist=NULL; int count; int elements; /* 1. GET THE PREDECESORS LIST OF THE ORIGIN */ elements = tg_pred_num(graph, task_orig); predlist = (task_list) malloc( sizeof(tg_task)*elements); if ( predlist == NULL ) { Asystem_error("tg_move_pred", "Not enough memory", "predlist"); } memcpy(predlist, tg_pred(graph,task_orig), sizeof(tg_task)*elements ); /* 2. FOR ALL THE ARCS ON THE LIST */ for (count = 0; count < elements; count ++ ) { /* 2.1. DELETE ARC ORIGIN - SUCCESOR */ tg_del_arc(graph, predlist[count], task_orig); /* 2.2. CREATE ARC DEST - SUCCESOR */ tg_add_arc(graph, predlist[count], task_dest); } /* 3. FREEING NLIST SPACE */ free(predlist); predlist = NULL; /* 4. END */ }
/* -------------------------------------------------------------------- * DELETE ALL LEAVING EDGES OF A NODE */ void tg_del_arcs_L(tg graph, tg_task node) { task_list succlist=NULL; int count; int elements; /* 1. GET THE SUCCESORS LIST OF THE NODE */ elements = tg_succ_num(graph, node); succlist = (task_list)malloc(sizeof(tg_task)*elements); if ( succlist == NULL ) { Asystem_error("tg_del_arcs_L", "Not enough memory", "succlist"); } memcpy(succlist, tg_succ(graph,node), sizeof(tg_task)*elements); /* 2. FOR ALL THE ARCS ON THE LIST */ for (count = 0; count < elements; count ++ ) { /* 2.1. DELETE ARC ORIGIN - SUCCESOR */ tg_del_arc(graph, node, succlist[count]); } /* 3. FREEING LIST SPACE */ free(succlist); succlist = NULL; /* 4. END */ }
/* -------------------------------------------------------------------- * MINIMUM FREE IDENTIFIER */ int tg_free_id(tg graph) { int count; Bool found; /* 1. CHECK IF THERE ARE IDENTIFIERS */ if (graph->maxid < 0) return 0; /* 2. CHECK IF THERE ARE NOT HOLES IN THE INDEX ARRAY */ if (tg_nodes(graph) == tg_maxid(graph)+1) return graph->maxid + 1; /* 3. LOCATE A NULL POINTER ON THE ARRAY */ for (count = 0, found = FALSE; count <= graph->maxid && !found; count ++ ) { if (graph->idarray[count] == NULL) found = TRUE; } /* 3. IF FOUND RETURN THE IDENTIFIER */ if (found) return count - 1; /* 4. IF NOT, ERROR */ else Asystem_error("tg_free_id","No NULL pointer in array",""); /* 5. END */ return 0; }
/* -------------------------------------------------------------------- * COPY RESOURCES VALUES FROM A GRAPH TO ANOTHER */ void tg_dup_resources(tg g1, tg g2) { int count, resource; /* 0. CHECK THE RESOURCE NUMBERS ON THE GRAPHS */ if (tg_resnum(g1) != tg_resnum(g2)) Asystem_error("tg_dup_resources","Different resnum",""); /* 1. FOR ALL TASKS ON THE ORIGIN GRAPH */ for (count = 0; count <= tg_maxid(g1); count ++ ) { /* 1.1. ... THAT EXISTS ON THE TWO GRAPHS ... */ if (!tg_id(g1, count) || !tg_id(g2,count)) continue; /* 1.2. COPY RESOURCE VALUES */ for (resource = 0; resource < tg_resnum(g1); resource ++ ) { tg_set_resource(g2, count, resource, tg_get_resource(g1, count, resource)); } } /* 2. END */ }
/* -------------------------------------------------------------------- * DUPLICATE THE GRAPH */ tg tg_dup(tg graph) { tg g2; int node; task_list arcs=NULL; int elements, count; int resource; /* 1. INITIALIZE THE NEW GRAPH */ g2 = tg_init(tg_resnum(graph)); /* 2. FOR ALL NODES ON THE OLD ONE */ for (node = 0; node <= tg_maxid(graph); node ++ ) { /* 2.1. ... THAT EXISTS ... */ if (!tg_id(graph, node)) continue; /* 2.2. CREATE NODE */ tg_add_node(g2, node); /* 2.3. COPY INFORMATION */ for (resource = 0; resource < tg_resnum(graph); resource ++ ) { tg_set_resource(g2, node, resource, tg_get_resource(graph, node, resource)); } /* 2.4. CREATE ARCS FOR SUCCESORS */ elements = tg_succ_num(graph, node); arcs = (task_list) malloc( sizeof(tg_task) * elements); if ( arcs == NULL ) { Asystem_error("tg_dup", "Not enough memory", "arcs"); } memcpy(arcs,tg_succ(graph,node), sizeof(tg_task)*elements ); for (count = 0; count < elements; count ++ ) { /* 2.4.1. IF SUCCESOR DOES NOT EXIST YET, CREATE */ if (!tg_id(g2, arcs[count])) tg_add_node(g2, arcs[count]); /* 2.4.2. ADD ARC */ tg_add_arc(g2, node, arcs[count]); } free(arcs); arcs=NULL; } /* 3. SET ROOT */ tg_set_root(g2, tg_root(graph)); /* 4. RETURN THE NEW GRAPH */ return g2; }
/* -------------------------------------------------------------------- * INITIALIZE GRAPH */ tg tg_init(int resources) { tg graph = NULL; /* 1. CHECKING INPUT */ if (resources < 0) Asystem_error("tg_init","Improper number of resources input",""); /* 2. CREATING SPACE FOR THE GRAPH STRUCTURE */ graph = (tg) malloc( sizeof(tg_graph) ); if ( graph == NULL ) { Asystem_error("tg_init", "Not enough memory", "graph"); } /* 3. FILLING FIELDS */ graph->tasknum = 0; graph->root = TG_NULLID; graph->resnum = resources; graph->maxid = TG_NULLID; graph->idarray = NULL; /* 4. END */ return graph; }
/* -------------------------------------------------------------------- * 1. INITIALIZE FUNCTION */ Astack Ast_init (void) { Astack stack = NULL; /* 1. CREATING SPACE FOR THE NEW POINTER */ stack = (Astack) malloc(sizeof(AstNode)); if (stack == NULL) Asystem_error("Ast_init","Not enough memory", "-"); /* 2. INITIALIZE THE POINTER TO NULL */ *stack = NULL; /* 3. RETURNING THE NEW STACK */ return stack; }
/* -------------------------------------------------------------------- * PUSH OPERATION */ void Ast_push (Astack stack, int datum) { AstNode node = NULL; /* 1. CREATING SPACE FOR THE NEW NODE */ node = (AstNode) malloc(sizeof(Astnode)); if (node == NULL) Asystem_error("Ast_push","Not enough memory", "-"); /* 2. INITIALIZING FIELDS */ node->datum = datum; node->next = *stack; /* 3. CHANGING THE STACK POINTER */ *stack = node; }
/* -------------------------------------------------------------------- * LIST OF NODES OF SUCCESORS GRADE n */ int tg_succ_grade(tg graph, int grade, task_list *resultlist) { int count, already, nodes; task_list list=NULL; /* 1. COUNT THE NUMBER OF NODES */ for (count = 0, nodes = 0; count <= tg_maxid(graph); count ++ ) { if (!tg_id(graph, count)) continue; if (tg_succ_num(graph, count) == grade) nodes ++; } /* 2. GET SPACE FOR THE NULL LIST */ list = (task_list) malloc( sizeof(tg_task) * (nodes + 1) ); if ( list == NULL ) { Asystem_error("tg_succ_grade", "Not enough memory", "list"); } /* 3. FILL THE LIST */ for (count = 0, already = 0; count <= tg_maxid(graph) && already < nodes; count ++ ) { if (!tg_id(graph, count)) continue; if (tg_succ_num(graph, count) == grade) { list[already] = count; already ++; } } /* 4. RETURN THE LIST */ *resultlist = list; return nodes; }
/* -------------------------------------------------------------------- * POP OPERATION */ int Ast_pop (Astack stack) { AstNode node = NULL; int datum; /* 0. CHECK EMPTY */ if (Ast_more(stack)==FALSE) Asystem_error("Ast_pop","Empty stack",""); /* 1. REMEMBER THE NEXT POINTER */ node = (*stack)->next; /* 2. REMEMBER THE TASK POINTER */ datum = (*stack)->datum; /* 3. FREEING THE SPACE OF THE NODE */ free(*stack); /* 4. CHANGING THE STACK POINTER */ *stack = node; /* 5. RETURNING THE TASK POINTER */ return datum; }
/* -------------------------------------------------------------------- * CHANGES TASK IDENTIFICATION */ Bool tg_change_id(tg graph, tg_task task, tg_task id) { tg_task target; int count, count2; /* 1. IF id EXISTS OR task DOES NOT, RETURN FALSE */ if (tg_id(graph,id) || !tg_id(graph,task)) return FALSE; /* 2. IF id IS GREATER THAN maxid */ if (id > graph->maxid) { /* 2.1. ASK FOR MORE SPACE */ graph->idarray = (ptask_list)realloc(graph->idarray, sizeof(tg_ptask)*(id+1)); if ( graph->idarray == NULL ) { Asystem_error("tg_change_id","Not enough memory", "idarray"); } /* 2.2. INITIALIZE THE NEW POSITIONS */ for (count = graph->maxid + 1; count < id; count ++ ) { graph->idarray[count] = NULL; } /* 2.3. CHANGE TO THE NEW maxid */ graph->maxid = id; } /* 3. CHANGE POINTER */ tgp(graph,task)->tid = id; graph->idarray[id] = graph->idarray[task]; graph->idarray[task] = NULL; /* 4. CHANGE THE SUCCESORS AND PREDECESSORS POINTERS */ for (count = 0; count < tg_pred_num(graph, id); count ++ ) { target = tgp(graph, id)->pred[count]; for (count2 = 0; count2 < tg_succ_num(graph, target); count2 ++ ) { if (tgp(graph, target)->succ[count2] == task) { tgp(graph, target)->succ[count2] = id; } } } for (count = 0; count < tg_succ_num(graph, id); count ++ ) { target = tgp(graph, id)->succ[count]; for (count2 = 0; count2 < tg_pred_num(graph, target); count2 ++ ) { if (tgp(graph, target)->pred[count2] == task) tgp(graph, target)->pred[count2] = id; } } /* 5. END */ return TRUE; }
/* -------------------------------------------------------------------- * DELETE ARC */ void tg_del_arc(tg graph, tg_task task_from, tg_task task_to) { int count; Bool deleted; tg_ptask pfrom, pto; /* 0. OBTAINING POINTERS */ pfrom = tgp(graph, task_from); pto = tgp(graph, task_to); /* 1. IF ARC DOES NOT EXIST, RETURN */ if (!tg_arc(graph, task_from, task_to)) return; /* 2. CHANGING TO NODE STRUCTURE */ /* 2.1. FOR ALL PRED, COMPARE UNTIL FIND THE ONE THAT MUST BE DELETED */ for ( deleted = FALSE, count=0 ; count < pto->prenum; count ++ ) { if ( ! deleted) { if ( task_from == pto->pred[count] ) { /* 2.1.1. FINDED, CHANGE FLAG */ deleted = TRUE; } } else { /* 2.1.2. MOVE ALL THE REST POINTERS BACK */ pto->pred[count - 1] = pto->pred[count]; } } /* 2.2. REALLOCATING IN FEW SPACE */ pto->prenum --; pto->pred = (task_list)realloc(pto->pred, sizeof(tg_task)*(pto->prenum)); if ( pto->pred == NULL ) { Asystem_error("tg_del_arc", "Not enough memory", "pto->pred"); } /* 3. CHANGING FROM NODE STRUCTURE */ /* 3.1. FOR ALL SUCC, COMPARE UNTIL FIND THE ONE THAT MUST BE DELETED */ for ( deleted = FALSE, count=0 ; count < pfrom->succnum; count ++ ) { if ( ! deleted) { if ( task_to == pfrom->succ[count] ) { /* 3.1.1. FINDED, CHANGE FLAG */ deleted = TRUE; } } else { /* 3.1.2. MOVE ALL THE REST POINTERS BACK */ pfrom->succ[count - 1] = pfrom->succ[count]; } } /* 3.2. REALLOCATING IN FEW SPACE */ pfrom->succnum --; pfrom->succ = (task_list)realloc(pfrom->succ, sizeof(tg_task)*(pfrom->succnum)); if ( pfrom->succ == NULL ) { Asystem_error("tg_del_arc", "Not enough memory", "pfrom->succ"); } /* 4. END */ }
/* -------------------------------------------------------------------- * ADD NODE */ Bool tg_add_node(tg graph, tg_task id) { tg_ptask ptask=NULL; int count; /* 0. CHECKING THE IDENTIFIER */ if (tg_id(graph, id)) return FALSE; /* 1. CREATING SPACE FOR THE TASK */ ptask = (tg_ptask) malloc( sizeof(tg_tsk) ); if ( ptask == NULL ) { Asystem_error("tg_add_node", "Not enough memory", "ptask"); } /* 2.1. ADDING ONE TO THE NUMBER OF TASKS */ graph->tasknum ++; /* 2.2. IF id IS GREATER THAN maxid */ if (id > graph->maxid) { /* 2.1. ASK FOR MORE SPACE */ graph->idarray = (ptask_list) realloc(graph->idarray, sizeof(tg_ptask)*(id+1)); if ( graph->idarray == NULL ) { Asystem_error("tg_add_node","Not enough memory", "idarray" ); } /* 2.2. INITIALIZE THE NEW POSITIONS */ for (count = graph->maxid + 1; count < id; count ++ ) { graph->idarray[count] = NULL; } /* 2.3. CHANGE TO THE NEW maxid */ graph->maxid = id; } graph->idarray[id] = ptask; /* 3. SETTING THE TASK IDENTIFICATION */ ptask->tid = id; /* 5. INITIALIZING TASK FIELDS */ ptask->resour = NULL; ptask->resour = (double *) malloc( sizeof(double) * ( graph->resnum )); if ( ptask->resour == NULL ) { Asystem_error("tg_add_node", "Not enough memory", "resour"); } for (count = 0; count < graph->resnum; count++ ) { ptask->resour[ count ] = 0.0; } ptask->prenum = 0; ptask->pred = NULL; ptask->succnum = 0; ptask->succ = NULL; return TRUE; }