From: Brendan Hansen Date: Thu, 21 Feb 2019 07:13:02 +0000 (-0600) Subject: second commit X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=7a9a621210d1508ea1eb107aedd451896ee9652a;p=graph-algorithms.git second commit --- diff --git a/main.lua b/main.lua index 0a1670a..3162e34 100644 --- a/main.lua +++ b/main.lua @@ -1,6 +1,14 @@ require "graphs" function love.load() + local graph = graphs.create_graph() + + local node1 = graphs.add_node(graph) + local node2 = graphs.add_node(graph) + local node3 = graphs.add_node(graph) + + graphs.add_directed(graph, node1, node2, 2) + graphs.add_directed(graph, node2, node3, 4) end function love.update() diff --git a/modules/graph_module.c b/modules/graph_module.c new file mode 100644 index 0000000..fdd897e --- /dev/null +++ b/modules/graph_module.c @@ -0,0 +1,22 @@ +#include + +#include "graph_standard.h" +#include "graph_utils.h" + +int luaopen_graphs(lua_State *L) +{ + printf("LOADING MODULE\n"); + + const luaL_Reg functions[] = { + { "create_graph", create_graph }, + { "add_node", add_node }, + { "del_node", del_node }, + { "add_directed", add_directed }, + { "add_undirected", add_undirected }, + { "del_edge", del_edge }, + { NULL, NULL } + }; + + luaL_register(L, "graphs", functions); + return 1; +} \ No newline at end of file diff --git a/modules/graph_standard.c b/modules/graph_standard.c index 2028492..b2cbb50 100644 --- a/modules/graph_standard.c +++ b/modules/graph_standard.c @@ -2,20 +2,21 @@ #include #include -#include -#include -#include +#include "graph_standard.h" -#include "graph_types.h" +static connect find_node(header head, int node_id); +static void add_edge(header head, int from_node, int to_node, int edge_weight); +// graph pointer create_graph() int create_graph(lua_State *L) { - header newGraph = (header)malloc(sizeof(head_structure)); + header new_graph = (header)malloc(sizeof(head_structure)); - newGraph->front = NULL; - newGraph->node_count = 0; + new_graph->front = NULL; + new_graph->node_count = 0; + new_graph->next_edge_id = 0; - lua_pushlightuserdata(L, (void*)newGraph); + lua_pushlightuserdata(L, (void*)new_graph); return 1; } @@ -24,103 +25,215 @@ int create_graph(lua_State *L) int add_node(lua_State *L) { header head = (header)lua_touserdata(L,1); - connect newNode = (connect)malloc(sizeof(node)); - newNode->next_node = NULL; + connect new_node = (connect)malloc(sizeof(node)); + new_node->next_node = NULL; if (head->node_count == 0) { - newNode->id = 0; - head->front = newNode; + new_node->node_id = 0; + head->front = new_node; } else { connect walker = head->front; - while (walker->next_node != NULL && walker->id == walker->next_node->id - 1) { + while (walker->next_node != NULL && walker->node_id == walker->next_node->node_id - 1) { walker = walker->next_node; } if (walker->next_node == NULL) { - newNode->id = head->node_count; - walker->next_node = newNode; + new_node->node_id = head->node_count; + walker->next_node = new_node; } else { - newNode->id = walker->id + 1; - newNode->next_node = walker->next_node; - walker->next_node = newNode; + new_node->node_id = walker->node_id + 1; + new_node->next_node = walker->next_node; + walker->next_node = new_node; } } head->node_count++; - lua_pushnumber(L,newNode->id); + lua_pushnumber(L,new_node->node_id); return 1; } +// del_node(graph pointer, int nodeID) int del_node(lua_State *L) { header head = (header)lua_touserdata(L,1); - int nodeID = lua_tointeger(L,2); + int nid = lua_tointeger(L,2); + + //find the node connect walker = head->front; connect follower = walker; - while(walker->id != nodeID){ + while(walker->node_id != nid && walker != NULL){ + if(walker->node_id > nid) + { + puts("c'mon brendan..."); + return 0; + } + follower = walker; + walker = walker->next_node; + } + if (walker == NULL) + { + puts("brother, this node don't exist"); + return 0; + } + + //delete all edges that correspond to the node + edge edge_walker = walker->neighbor_list; + edge delete_walker = edge_walker; + while (edge_walker != NULL) + { + edge_walker = edge_walker->next_edge; + free(delete_walker); + delete_walker = edge_walker; + } + connect node_walker = head->front; + while (node_walker != NULL) + { + edge_walker = node_walker->neighbor_list; + delete_walker = edge_walker; + while (edge_walker != NULL) + { + if (edge_walker->to_id == nid) + { + edge_walker = edge_walker->next_edge; + if (edge_walker == node_walker->neighbor_list) + { + node_walker->neighbor_list = node_walker->neighbor_list->next_edge; + } + else + { + delete_walker->next_edge = edge_walker; + delete_walker = delete_walker->next_edge; + } + free(delete_walker); + } + else + { + delete_walker = edge_walker; + edge_walker = edge_walker->next_edge; + } + } + node_walker = node_walker->next_node; } + //delete the node + if (walker == head->front) + { + head->front = head->front->next_node; + } + else + { + follower->next_node = walker->next_node; + } + head->node_count--; + free(walker); return 0; } +static void add_edge(header head, int from_node, int to_node, int edge_weight) +{ + //walk through node list to find from node + connect runner = find_node(head, from_node); + + if(runner == NULL) + return; + + //setup edge search + edge edge_run = runner->neighbor_list; + + //setup new edge + edge new_edge = (edge)malloc(sizeof(edge_struct)); + new_edge->edge_id = head->next_edge_id++; + new_edge->to_id = to_node; + new_edge->weight = edge_weight; + new_edge->next_edge = NULL; + + + //place the new edge + if(edge_run == NULL) + runner->neighbor_list = new_edge; //this is first edge for node + else + { + while(edge_run->next_edge != NULL) //go to end of neighbor list + { + edge_run = edge_run->next_edge; + } + + edge_run->next_edge = new_edge; + + } +} +// add_directed(graph pointer, int from, int to, int weight) int add_directed(lua_State *L) { + //grab variables from lua_State header head = (header)lua_touserdata(L,1); + int from_node = lua_tointeger(L, 2); int to_node = lua_tointeger(L, 3); + int edge_weight = lua_tointeger(L, 4); - connect runner = head->front; + //add single edge with add_edge function + add_edge(head, from_node, to_node, edge_weight); - if(runner == NULL) - { - puts("WTF bro you can't do this"); - return 0; //graph is empty - } + return 0; +} - while(runner->id != from_node) - { - if(runner == NULL) - return 0; //from id is never found +int add_undirected(lua_State *L) +{ + header head = (header)lua_touserdata(L, 1); - runner = runner->next_node; - } + int from_node = lua_tointeger(L, 2); + int to_node = lua_tointeger(L, 3); + int edge_weight = lua_tointeger (L, 4); - edge edge_run = runner->neighbor_list; - edge new_edge; + //add two edges (from -> to and to -> from) + add_edge(head, from_node, to_node, edge_weight); + add_edge(head, to_node, from_node, edge_weight); - if(edge_run == NULL) + return 0; +} + +int del_edge(lua_State *L) +{ + header head = (header)lua_touserdata(L, 1); + + //we will have to walk through each node and walk through each edge of each node + connect runner = head->front; + while(runner != NULL) { - edge_run = (edge)malloc(sizeof(edge_struct)); - edge_run->to_id = to_node; - - } + } - return 1; } -int luaopen_graphs(lua_State *L) +static connect find_node(header head, int node_id) { - printf("LOADING MODULE\n"); + //walk through node list to find from node + connect runner = head->front; + if(runner == NULL) + { + puts("GRAPH HEADER LIST IS EMPTY"); + return NULL; //graph is empty + } + + //run through list of nodes until node with passed node_id is found + while(runner->node_id != node_id) + { + if(runner == NULL) + return NULL; //from id is never found - const luaL_Reg functions[] = { - { "create_graph", create_graph }, - { "add_node", add_node }, - { "del_node", del_node }, - { "add_directed", add_directed }, - { NULL, NULL } - }; + runner = runner->next_node; //move to next node in list + } - luaL_register(L, "graphs", functions); - return 1; -} \ No newline at end of file + return runner; +} diff --git a/modules/graph_standard.h b/modules/graph_standard.h new file mode 100644 index 0000000..6c7f618 --- /dev/null +++ b/modules/graph_standard.h @@ -0,0 +1,17 @@ +#ifndef __GRAPH_STANDARD_H__ +#define __GRAPH_STANDARD_H__ + +#include +#include +#include + +#include "graph_types.h" + +LUA_FUNCTION(create_graph); +LUA_FUNCTION(add_node); +LUA_FUNCTION(del_node); +LUA_FUNCTION(add_directed); +LUA_FUNCTION(add_undirected); +LUA_FUNCTION(del_edge); + +#endif \ No newline at end of file diff --git a/modules/graph_types.h b/modules/graph_types.h index 5640bea..862a34c 100644 --- a/modules/graph_types.h +++ b/modules/graph_types.h @@ -1,21 +1,26 @@ #ifndef __GRAPH_TYPES_H__ #define __GRAPH_TYPES_H__ -typedef struct { +typedef struct edge_struct { + int edge_id; int to_id; int weight; -} edge_struct,*edge; + struct edge_struct* next_edge; +} edge_struct, *edge; typedef struct node { edge neighbor_list; - int id; + int node_id; int edge_count; struct node* next_node; -} node,*connect; +} node, *connect; typedef struct { connect front; - int node_count; + int node_count; + int next_edge_id; } head_structure, *header; +#define LUA_FUNCTION(func) int (func)(lua_State*) + #endif \ No newline at end of file diff --git a/modules/graph_utils.c b/modules/graph_utils.c new file mode 100644 index 0000000..7242520 --- /dev/null +++ b/modules/graph_utils.c @@ -0,0 +1 @@ +#include "graph_utils.h" \ No newline at end of file diff --git a/modules/graph_utils.h b/modules/graph_utils.h new file mode 100644 index 0000000..106faad --- /dev/null +++ b/modules/graph_utils.h @@ -0,0 +1,28 @@ +#ifndef __GRAPH_UTILS_H__ +#define __GRAPH_UTILS_H__ + +#include +#include +#include + +#include "graph_types.h" + +/* Returns all nodes in the form: + { + id = , + x = , + y = + } +*/ +LUA_FUNCTION(get_nodes); + +/* Returns all edges in the form: + { + id = , + from_node = , + to_node = + } +*/ +LUA_FUNCTION(get_edges); + +#endif \ No newline at end of file