Untitled
unknown
plain_text
4 years ago
7.2 kB
6
Indexable
#include "Graph.h"
Graph createGraph()
{
Graph graph;
graph.edges = make_jrb();
graph.vertices = make_jrb();
return graph;
}
void dropGraph(Graph graph)
{
JRB node, tree;
jrb_traverse(node, graph.edges)
{
tree = (JRB)jval_v(node->val);
jrb_free_tree(tree);
}
jrb_free_tree(graph.edges);
jrb_free_tree(graph.vertices);
}
void addVertex(Graph graph, int id, char *name)
{
JRB node = jrb_find_int(graph.vertices, id);
if (node == NULL)
jrb_insert_int(graph.vertices, id, new_jval_s(strdup(name)));
}
void addEdge(Graph graph, int v1, int v2, int weight)
{
JRB node, tree;
if (!hasEdge(graph, v1, v2))
{
//add v1->v2
node = jrb_find_int(graph.edges, v1);
if (node == NULL)
{
tree = make_jrb();
jrb_insert_int(graph.edges, v1, new_jval_v(tree));
}
else
{
tree = (JRB)jval_v(node->val);
}
jrb_insert_int(tree, v2, new_jval_i(weight));
//add v2->v1
node = jrb_find_int(graph.edges, v2);
if (node == NULL)
{
tree = make_jrb();
jrb_insert_int(graph.edges, v2, new_jval_v(tree));
}
else
{
tree = (JRB)jval_v(node->val);
}
jrb_insert_int(tree, v1, new_jval_i(weight));
}
}
int getEdgeValue(Graph graph, int v1, int v2)
{
JRB node, tree, node1;
node = jrb_find_int(graph.edges, v1);
if (node == NULL)
return INFINITIVE_VALUE;
tree = (JRB)jval_v(node->val);
node1 = jrb_find_int(tree, v2);
if (node1 == NULL)
return INFINITIVE_VALUE;
return jval_i(node1->val);
}
char *getVertex(Graph graph, int id)
{
JRB node = jrb_find_int(graph.vertices, id);
if (node == NULL)
return NULL;
else
return jval_s(node->val);
}
int hasEdge(Graph graph, int v1, int v2)
{
JRB node, tree;
node = jrb_find_int(graph.edges, v1);
if (node == NULL)
return 0;
tree = (JRB)jval_v(node->val);
if (jrb_find_int(tree, v2) == NULL)
return 0;
else
return 1;
}
int indegree(Graph graph, int v, int *output)
{
JRB tree, node;
int total = 0;
jrb_traverse(node, graph.edges)
{
tree = (JRB)jval_v(node->val);
if (jrb_find_int(tree, v))
{
output[total] = jval_i(node->key);
total++;
}
}
return total;
}
int outdegree(Graph graph, int v, int *output)
{
JRB tree, node;
int total = 0;
node = jrb_find_int(graph.edges, v);
if (node == NULL)
return 0;
tree = (JRB)jval_v(node->val);
jrb_traverse(node, tree)
{
output[total] = jval_i(node->key);
total++;
}
return total;
}
int shortestPath(Graph graph, int s, int t, int *path, int *length)
{
int distance[1000], min, w, total;
int previous[1000], tmp[1000], visited[1000];
int n, output[100], i, v, u;
Dllist queue, ptr, node;
for (i = 0; i < 1000; i++)
{
distance[i] = INFINITIVE_VALUE;
visited[i] = 0;
previous[i] = 0;
}
distance[s] = 0;
previous[s] = s;
visited[s] = 1;
queue = new_dllist();
dll_append(queue, new_jval_i(s));
while (!dll_empty(queue))
{
min = INFINITIVE_VALUE;
dll_traverse(ptr, queue)
{
u = jval_i(ptr->val);
if (min > distance[u])
{
min = distance[u];
node = ptr;
}
}
u = jval_i(node->val);
visited[u] = 1;
dll_delete_node(node);
if (u == t)
break;
n = outdegree(graph, u, output);
for (i = 0; i < n; i++)
{
v = output[i];
w = getEdgeValue(graph, u, v);
if (distance[v] > distance[u] + w)
{
distance[v] = distance[u] + w;
previous[v] = u;
}
if (visited[v] == 0)
dll_append(queue, new_jval_i(v));
}
}
total = distance[t];
if (total != INFINITIVE_VALUE)
{
tmp[0] = t;
n = 1;
while (t != s)
{
t = previous[t];
tmp[n++] = t;
}
for (i = n - 1; i >= 0; i--)
{
path[n - i - 1] = tmp[i];
}
*length = n;
}
return total;
}
int getNumOfV(Graph graph)
{
JRB node;
int total = 0;
jrb_traverse(node, graph.vertices)
total++;
return total;
}
int getNumOfE(Graph graph)
{
JRB node1, node2;
int total = 0;
jrb_traverse(node1, graph.vertices)
jrb_traverse(node2, graph.vertices) if (hasEdge(graph, jval_i(node1->key), jval_i(node2->key)))
total++;
return total;
}
int shortestPath_5(Graph graph, int s, int t, int *path, int *length)
{
int distance[1000], min, w, total;
int previous[1000], tmp[1000], visited[1000];
int n, output[100], i, v, u;
Dllist queue, ptr, node;
for (i = 0; i < 1000; i++)
{
distance[i] = INFINITIVE_VALUE;
visited[i] = 0;
previous[i] = 0;
}
distance[s] = 0;
previous[s] = s;
visited[s] = 1;
queue = new_dllist();
dll_append(queue, new_jval_i(s));
while (!dll_empty(queue))
{
min = INFINITIVE_VALUE;
dll_traverse(ptr, queue)
{
u = jval_i(ptr->val);
if (min > distance[u] && distance[u] >= 50 || distance[u] == 0)
{
min = distance[u];
node = ptr;
}
}
u = jval_i(node->val);
visited[u] = 1;
dll_delete_node(node);
if (u == t)
break;
n = outdegree(graph, u, output);
for (i = 0; i < n; i++)
{
v = output[i];
w = getEdgeValue(graph, u, v);
if(w < 50)
continue;
if (distance[v] > distance[u] + w)
{
distance[v] = distance[u] + w;
previous[v] = u;
}
if (visited[v] == 0)
dll_append(queue, new_jval_i(v));
}
}
total = distance[t];
if (total != INFINITIVE_VALUE)
{
tmp[0] = t;
n = 1;
while (t != s)
{
t = previous[t];
tmp[n++] = t;
}
for (i = n - 1; i >= 0; i--)
{
path[n - i - 1] = tmp[i];
}
*length = n;
}
return total;
}
// int checkPath(Graph graph, int *path, int length)
// {
// for (int i = 0; i < length-1; i++)
// {
// if(getEdgeValue(graph, path[i], path[i+1]) < 50)
// {
// return 0;
// break;
// }
// }
// }
Editor is loading...