void graph_check(const graph_s *gp) { assert(gp != NULL); unsigned int err = 0; #ifdef DEBUG if (gp->degrees == NULL) err = 1; if (gp->adjacency == NULL) err = 2; uint32_t n = gp->num_vertices; for (uint32_t v=0; v < n; v++) if (gp->degrees[v] > n) err = 3; if (err == 0) for (uint32_t v=0; v < n; v++) { uint32_t deg = 0; for (uint32_t v2=0; v2 < n; v2++) { if (graph_get_edge(gp, v, v2) != graph_get_edge(gp, v, v2)) err = 4; if (graph_get_edge(gp, v, v2)) deg += 1; } if (deg != graph_degree(gp, v)) err = 5; } /* Check if adjacency matrix and lists are the same */ if (err == 0) for (uint32_t v=0; v < n; v++) { bool from_matrix[n]; bool from_list[n]; memset(from_list, 0, n * sizeof(bool)); for (uint32_t v2=0; v2 < n; v2++) from_matrix[v2] = graph_get_edge(gp, v, v2); for (uint32_t pos=0; pos < graph_degree(gp, v); pos++) from_list[graph_get_edge_pos(gp, v, pos)] = true; for (uint32_t v2=0; v2 < n; v2++) if (from_matrix[v2] != from_list[v2]) err = 6; } #endif if (err > 0) { graph_pp(gp); log_debug("check_graph code: %d", err); } assert(err == 0); }
static ssize_t graph_find_edge(chm_imp_t *data, size_t nvertex, uintmax_t *vertex, uintmax_t *edge_id){ // {{{ intmax_t ret; uintmax_t curr_edge_id; graph_edge_t curr_edge; if(nvertex != 2) return -EINVAL; curr_edge_id = 0; if( (ret = graph_get_first(data, 1, (uintmax_t *)&vertex[0], &curr_edge_id)) < 0) return ret; do{ if( (ret = graph_get_edge(data, curr_edge_id, &curr_edge)) < 0) return ret; if(memcmp(vertex, curr_edge.vertex, MIN(nvertex * sizeof(vertex[0]), sizeof(curr_edge.vertex))) == 0){ *edge_id = curr_edge_id; return 0; } if(curr_edge.vertex[0] == vertex[0]){ curr_edge_id = curr_edge.next[0]; }else if(curr_edge.vertex[1] == vertex[0]){ curr_edge_id = curr_edge.next[1]; }else return error("find_edge db inconsistency"); }while(curr_edge_id != 0); return -ENOENT; } // }}}
void graph_pp(const graph_s* gp) { #ifdef DEBUG assert(gp != NULL); log_debug("graph_pp"); uint32_t n = gp->num_vertices; fprintf(stderr, "Graph %p has %d vertices\n", gp, n); fprintf(stderr, "Adjacency matrix\n"); for (uint32_t v=0; v < n; v++) { fprintf(stderr, "Vertex %d (degree %d):", v, graph_degree(gp, v)); for (uint32_t v2=0; v2 < n; v2++) if (graph_get_edge(gp, v, v2)) fprintf(stderr, " %d", v2); fprintf(stderr, "\n"); } fprintf(stderr, "Adjacency lists\n"); for (uint32_t v=0; v < n; v++) { fprintf(stderr, "Vertex %d (degree %d):", v, graph_degree(gp, v)); for (uint32_t p=0; p < graph_degree(gp, v); p++) fprintf(stderr, " %d", graph_get_edge_pos(gp, v, p)); fprintf(stderr, "\n"); } #endif }
void graph_remove_edge(graph *g, int edge_index) { void *edge_to_remove; if(g == NULL) { return; } /* make sure that these verticies actually exist */ if((graph_get_vertex(g, graph_get_edge_src(g, edge_index)) == NULL) || (graph_get_vertex(g, graph_get_edge_dst(g, edge_index)) == NULL)) { return; } edge_to_remove = graph_get_edge(g, edge_index); if(edge_to_remove == NULL) { return; } if(g->freeedge_fn != NULL) { g->freeedge_fn(edge_to_remove); } g->edges[edge_index] = NULL; g->nedges--; }
void dijkstra(graph_t *g, void *current, void *to, list_t *visited, list_t *distanceLabels) { assert(g); assert(current); assert(to); assert(visited); assert(distanceLabels); while (true) { if (!list_has(visited, g->comp, current)) { list_t *unvisited_neighs = unvisited_neighbors(g, current, visited); distance_label_t *here = get_distance_label(distanceLabels, current, g->comp); iter_t *it; for (it = iter(unvisited_neighs); !iter_done(it); iter_next(it)) { void *neigh = iter_get(it); int line = list_quickest_line(g->nodes, current, neigh, here->arrival_time); // printf("med linje:%i i dijkstra\n",line); assert(line); edge_t *edge = graph_get_edge(g,line,current,here->path_edges); assert(edge); list_t *tentativePath = list_clone(here->path); list_t *tentativeEdgePath = list_clone(here->path_edges); list_add(tentativePath, neigh); list_add(tentativeEdgePath, edge); char *bussDepart = list_next_dep_time(g->nodes,current,neigh,line,here->arrival_time); assert(bussDepart); int total_distance = graph_add_penalty(edge, here->arrival_time, bussDepart);// egen rad char *new_arrival_time = add_duration(bussDepart, network_get_dur(edge->label)); //egen rad //free(bussDepart); update_distance(distanceLabels, neigh, g->comp, here->dist + total_distance, tentativePath, tentativeEdgePath, new_arrival_time); //la till new_arrival_tim. ost-bågen borde gå in här!! } iter_free(it); list_free(unvisited_neighs); } list_add(visited, current); if (g->comp(current, to)) { return; } current = get_min_distance_node(distanceLabels, g->comp, visited); assert(current); } }
Particle* graph_get_neighbor(Particle* a, int i, const GraphData &d) { Particle *edge= graph_get_edge(a, i, d); if (graph_get_node(edge, 0, d) == a) { return graph_get_node(edge, 1, d); } else { IMP_INTERNAL_CHECK(graph_get_node(edge, 1, d) == a, "Broken graph"); return graph_get_node(edge, 0, d); } }
} END_TEST START_TEST(test_graph_get_edge) { kld_graph_t * g = (kld_graph_t *) new_graph(); int data = 1; int * data_ref = &data; kld_graph_node_t * n1 = (kld_graph_node_t *) new_graph_node(g); kld_graph_node_t * n2 = (kld_graph_node_t *) new_graph_node(g); graph_insert_edge(g, n1, n2, data_ref); kld_graph_edge_t * e = (kld_graph_edge_t *) graph_get_edge(g, n1, n2); kld_graph_edge_t * e2 = (kld_graph_edge_t *) graph_get_edge(g, n2, n1); fail_if(e == NULL, "Incorrect edge returned."); fail_if(e->data == NULL, "Incorrect edge data returned."); fail_if(e->data != data_ref, "Incorrect edge data returned."); fail_if(e2 != NULL, "Incorrect edge returned."); } END_TEST
static ssize_t graph_recalc(chm_imp_t *data, vertex_list_t *vertex, uintmax_t g_old, uintmax_t g_new, uintmax_t skip_edge){ // {{{ ssize_t ret; size_t our_vertex, frn_vertex; uintmax_t edge_id, frn_g_old, frn_g_new; graph_edge_t edge; vertex_list_t vertex_new, *curr; //printf("recalc called: %llx, g_old: %llx g_new: %llx\n", // vertex, g_old, g_new //); for(curr = vertex->next; curr; curr = curr->next){ if(curr->vertex == vertex->vertex){ return -EBADF; } } if( (ret = graph_get_first(data, 1, &vertex->vertex, &edge_id)) < 0) return ret; for(; edge_id != 0; edge_id = edge.next[our_vertex]){ if( (ret = graph_get_edge(data, edge_id, &edge)) < 0) return ret; if(edge.vertex[0] == vertex->vertex){ our_vertex = 0; frn_vertex = 1; }else if(edge.vertex[1] == vertex->vertex){ our_vertex = 1; frn_vertex = 0; }else return error("recalc db inconsistency"); //printf("recalc edge: %llx -> v:{%llx,%llx:%llx,%llx} next: %llx\n", // edge_id, edge.vertex[0], edge.vertex[1], edge.next[0], edge.next[1], // edge.next[our_vertex] //); if(skip_edge == edge_id) continue; if( (ret = graph_getg(data, 1, &edge.vertex[frn_vertex], &frn_g_old)) < 0) return ret; frn_g_new = g_old + frn_g_old - g_new; vertex_new.vertex = edge.vertex[frn_vertex]; vertex_new.next = vertex; if((ret = graph_recalc(data, &vertex_new, frn_g_old, frn_g_new, edge_id)) < 0) return ret; } if(( ret = graph_setg(data, 1, &vertex->vertex, &g_new)) < 0) return ret; return 0; } // }}}
} END_TEST START_TEST(test_graph_remove_edge) { kld_graph_t * g = (kld_graph_t *) new_graph(); int data = 1; int * data_ref = &data; kld_graph_node_t * n1 = (kld_graph_node_t *) new_graph_node(g); kld_graph_node_t * n2 = (kld_graph_node_t *) new_graph_node(g); graph_insert_edge(g, n1, n2, data_ref); graph_remove_edge(g, n1, n2); kld_graph_edge_t * e = (kld_graph_edge_t *) graph_get_edge(g, n1, n2); fail_if(e != NULL, "Edge should be NULL after inserting and then removing it."); } END_TEST
void ShortestPath_Dijekstra(struct graph *g, int src, int *d, int *prev) { struct heap *prio_q; prio_q = heap_create(g->nvertices); int v; for (v = 1; v <= g->nvertices; v++) { if (v != src) { g->visited[v] = 0; d[v] = INT_MAX; prev[v] = -1; heap_insert(prio_q, d[v], v); } } d[src] = 0; prev[src] = -1; g->visited[src] = 0; heap_insert(prio_q, d[src], src); struct heapnode node; int tmp; for (v = 1; v <= g->nvertices; v++) { node = heap_extract_min(prio_q); tmp = node.value; g->visited[tmp] = 1; /*printf("vert %d\n\n", v); printf("min prio %d to vert %d\n", node.key, node.value);*/ for (int u = 1; u <= g->nvertices; u++) { int way = graph_get_edge(g, tmp, u); if ((way != 0) && (g->visited[u] != 1)) { //printf("sm ne pos vert %d\nway %d\n", u, way); if (d[tmp] + way < d[u]) { d[u] = d[tmp] + way; //printf("path do %d = %d\n", u, d[u]); heap_decrease_key(prio_q, u, d[u]); prev[u] = tmp; } } } } }
} END_TEST START_TEST(test_graph_insert_edge) { kld_graph_t * g = (kld_graph_t *) new_graph(); int data = 1; int * data_ref = &data; kld_graph_node_t * n1 = (kld_graph_node_t *) new_graph_node(g); kld_graph_node_t * n2 = (kld_graph_node_t *) new_graph_node(g); graph_insert_edge(g, n1, n2, data_ref); kld_graph_edge_t * e = (kld_graph_edge_t *) graph_get_edge(g, n1, n2); fail_if(e == NULL, "Edge is NULL after inserting it."); fail_if(e->data == NULL, "Edge data is NULL after inserting it."); fail_if(e->data != data_ref, "Edge data is not the expected value."); } END_TEST
int *graph_get_edges_dst(graph *g, int vertex) { int *full_list; int *copy_edge; int edge_index; int nedges; int i; int full_idx; if(g == NULL) { return NULL; } if(vertex >= g->max_verticies) { return NULL; } nedges = graph_nedges_dst(g, vertex) + 1; /* allocate the space for the list */ full_list = malloc(sizeof(int)*nedges); if(full_list == NULL) { return NULL; } memset(full_list, 0, sizeof(int)*nedges); full_idx = 0; /* get the from edges, and copy them in */ for(i = 0; i < g->max_verticies; i++) { edge_index = row_col_to_1d(i, vertex, g->max_verticies); copy_edge = graph_get_edge(g, edge_index); if(copy_edge != NULL) { full_list[full_idx++] = edge_index; } } full_list[full_idx] = -1; return full_list; }
bool graph_check_end_station(graph_t *g,int line, list_t *visited_edges, void *next_node) // Egen Funktion { if(graph_get_edge(g,line,next_node,visited_edges) != NULL) return false; return true; }