From: Brendan Hansen Date: Sun, 24 Feb 2019 20:53:52 +0000 (-0600) Subject: presentation ready version X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=40c494537a80eaddce588d73609d3549418be7f0;p=graph-algorithms.git presentation ready version --- diff --git a/conf.lua b/conf.lua new file mode 100644 index 0000000..820c076 --- /dev/null +++ b/conf.lua @@ -0,0 +1,6 @@ +function love.conf(t) + t.window.title = "Graph Visualizer" + + t.window.width = 1200 + t.window.height = 800 +end \ No newline at end of file diff --git a/lua/graph.lua b/lua/graph.lua index 9e91b8a..1f89cc2 100644 --- a/lua/graph.lua +++ b/lua/graph.lua @@ -111,4 +111,16 @@ function Graph:dijkstras(startID, iterations) return graphs.dijkstras(self.graph, startID, iterations) end +function Graph:depthFirst(startID, iterations) + return graphs.depth_first_search(self.graph, startID, iterations) +end + +function Graph:breadthFirst(startID, iterations) + return graphs.breadth_first_search(self.graph, startID, iterations) +end + +function Graph:prims(startID, iterations) + return graphs.prims(self.graph, startID, iterations) +end + return Graph \ No newline at end of file diff --git a/lua/utils.lua b/lua/utils.lua index dd1793f..cc21175 100644 --- a/lua/utils.lua +++ b/lua/utils.lua @@ -2,6 +2,10 @@ function math.lerp(a, b, t) return a + (b - a) * t end +function math.sqrDist(x1, y1, x2, y2) + return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) +end + function math.uuid() return ("xxxxxxxx-xxxx-4yxx-xxxxxxxx"):gsub('[xy]', function (c) local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb) diff --git a/main.lua b/main.lua index 2a784c0..0e2e229 100644 --- a/main.lua +++ b/main.lua @@ -13,24 +13,12 @@ function love.load() SIDEBAR_FONT = love.graphics.setNewFont(24) graph = Graph:new() - - -- graph:addNode(100, 100) - -- graph:addNode(300, 100) - -- graph:addNode(200, 200) - -- graph:addNode(500, 400) - -- graph:addNode(300, 300) - - -- graph:addArc(0, 1) - -- graph:addEdge(0, 2) - -- graph:addArc(1, 3, 99) - -- graph:addEdge(1, 2) - regions = Regions:new() graph_region = { -- needed for Regions calculations priority = 1; - rect = { 200, 0, 600, 600 }; + rect = { 200, 0, 1000, 800 }; -- other properties selectedNode = nil; @@ -41,7 +29,7 @@ function love.load() update = function(self) end; draw = function(self) love.graphics.setColor(0.7, 0.8, 0.9) - love.graphics.rectangle("fill", 0, 0, 600, 600) + love.graphics.rectangle("fill", 0, 0, 1000, 800) drawGraph(graph, self.selectedNode) if self.postDrawFunction then @@ -53,6 +41,7 @@ function love.load() self.isMouseDown = true self.selectedNode = nil local nodes = graph:getNodes() + local edges = graph:getEdges() for _, node in pairs(nodes) do local nx = node.x @@ -65,6 +54,22 @@ function love.load() else self.clickNodeFunction(node) end + + return + end + end + + for _, edge in pairs(edges) do + local x1, y1 = graph:getNodePos(edge.from_node) + local x2, y2 = graph:getNodePos(edge.to_node) + + local d1 = math.sqrt(math.sqrDist(x1, y1, x, y)) + local d2 = math.sqrt(math.sqrDist(x2, y2, x, y)) + local d3 = math.sqrt(math.sqrDist(x1, y1, x2, y2)) + + if d1 + d2 <= d3 + 2 then + createWeightChanger(edge.id, (x1 + x2) / 2 + 100, (y1 + y2) / 2 - 50) + return end end end; @@ -90,7 +95,7 @@ function love.load() -- Sidebar regions:add { priority = 1; - rect = { 0, 0, 200, 600 }; + rect = { 0, 0, 200, 800 }; buttons = { { @@ -106,7 +111,7 @@ function love.load() click = function(self) graph:addNode(self.placeX, self.placeY) self.placeX = self.placeX + 40 - if self.placeX >= 600 then + if self.placeX >= 1000 then self.placeX = 20 self.placeY = self.placeY + 40 end @@ -162,7 +167,62 @@ function love.load() text = "Run Dijkstras", click = function() if graph_region.selectedNode ~= nil then - createDijskstraStepper(graph_region.selectedNode) + function dijkstrasStepper(start, step) + local dj, done = graph:dijkstras(start, step) + graph_region.postDrawFunction = function(reg) + drawDijkstras(graph, dj) + end + return done + end + createStepper(graph_region.selectedNode, dijkstrasStepper) + end + end; + }; + { + text = "Run DFS", + click = function() + if graph_region.selectedNode ~= nil then + function dfsStepper(start, step) + local dfs, done = graph:depthFirst(start, step) + graph_region.postDrawFunction = function(reg) + drawTree(graph, dfs) + end + return done + end + + createStepper(graph_region.selectedNode, dfsStepper, 0) + end + end; + }; + { + text = "Run BFS", + click = function() + if graph_region.selectedNode ~= nil then + function bfsStepper(start, step) + local bfs, done = graph:breadthFirst(start, step) + graph_region.postDrawFunction = function(reg) + drawTree(graph, bfs) + end + return done + end + + createStepper(graph_region.selectedNode, bfsStepper, 0) + end + end; + }; + { + text = "Run Prims", + click = function() + if graph_region.selectedNode ~= nil then + function primStepper(start, step) + local prims, done = graph:prims(start, step) + graph_region.postDrawFunction = function(reg) + drawTree(graph, prims) + end + return done + end + + createStepper(graph_region.selectedNode, primStepper, 0) end end; }; @@ -172,16 +232,19 @@ function love.load() update = function(self) end; draw = function(self) + love.graphics.setColor(1, 1, 1) + love.graphics.rectangle("fill", unpack(self.rect)) love.graphics.setFont(SIDEBAR_FONT) + for i, button in ipairs(self.buttons) do if self.mousePos >= (i - 1) * 60 + 10 and self.mousePos < i * 60 - 10 then - love.graphics.setColor(.4, .4, .4) + love.graphics.setColor(.9, .9, .9) else - love.graphics.setColor(.2, .2, .2) + love.graphics.setColor(.7, .7, .7) end love.graphics.rectangle("fill", 10, (i - 1) * 60 + 10, 180, 40) - love.graphics.setColor(1, 1, 1) + love.graphics.setColor(0, 0, 0) love.graphics.printf(button.text, 0, (i - 1) * 60 + 15, 200, "center") end end; @@ -189,7 +252,7 @@ function love.load() mousedown = function(self, x, y) for i, button in ipairs(self.buttons) do if y >= (i - 1) * 60 + 10 and y <= i * 60 + 10 then - button.click(button) + button:click() end end end; @@ -215,60 +278,53 @@ function love.load() -- mouseenter = function(self) end; -- mouseleave = function(self) end; -- } - - createWeightChanger(0) end -local dijkstrasOpen = false -function createDijskstraStepper(start) - if dijkstrasOpen then return end +local stepperOpen = false +function createStepper(start, update, startStep) + if stepperOpen then return end - dijkstrasOpen = true - local step = -1 + stepperOpen = true + startStep = startStep or -1 + local step = startStep - local isDone = false - function updateDijkstras() - local dj, done = graph:dijkstras(start, step) - isDone = done - graph_region.postDrawFunction = function(reg) - drawDijkstras(graph, dj) - end - end - updateDijkstras() + update(start, step) + local isDone = false local reg_id + local width = 1000 local region = { priority = 10; - rect = { 200, 550, 600, 50 }; + rect = { 200, 750, width, 50 }; update = function(self) end; draw = function(self) love.graphics.setFont(SIDEBAR_FONT) love.graphics.setColor(0, 0, 0, 0.7) - love.graphics.rectangle("fill", 0, 0, 600, 50) + love.graphics.rectangle("fill", 0, 0, width, 50) love.graphics.setColor(1, 1, 1) - love.graphics.polygon("fill", 265, 25, 295, 10, 295, 40) - love.graphics.polygon("fill", 335, 25, 305, 10, 305, 40) + love.graphics.polygon("fill", (width / 2) - 35, 25, (width / 2) - 5, 10, (width / 2) - 5, 40) + love.graphics.polygon("fill", (width / 2) + 35, 25, (width / 2) + 5, 10, (width / 2) + 5, 40) - love.graphics.printf("X", 540, 5, 50, "center", 0, 1.4, 1.4) + love.graphics.printf("X", width - 60, 5, 50, "center", 0, 1.4, 1.4) end; mousedown = function(self, x, y) - if x >= 265 and x <= 295 then + if x >= (width / 2) - 35 and x <= (width / 2) - 5 then step = step - 1 isDone = false - if step < -1 then step = -1 end - elseif x >= 305 and x <= 335 then + if step < startStep then step = startStep end + elseif x >= (width / 2) + 5 and x <= (width / 2) + 35 then if not isDone then step = step + 1 end end - updateDijkstras() - if x >= 550 then + isDone = update(start, step) + if x >= width - 50 then regions:remove(reg_id) graph_region.postDrawFunction = nil - dijkstrasOpen = false + stepperOpen = false end end; mouseup = function(self, x, y) end; @@ -280,10 +336,15 @@ function createDijskstraStepper(start) reg_id = regions:add(region) end -function createWeightChanger(edgeID) - regions:add { +function createWeightChanger(edgeID, x, y) + if y < 0 then + y = 0 + end + + local reg_id + reg_id = regions:add { priority = 100; - rect = { 200, 0, 200, 100 }; + rect = { x, y, 200, 100 }; update = function(self) end; draw = function(self) @@ -315,7 +376,32 @@ function createWeightChanger(edgeID) end end; mousedown = function(self, x, y) + if math.sqrDist(x, y, 160, 60) <= 20 * 20 then + local edge = graph:getEdge(edgeID) + local otherEdge = graph:getEdgeID(edge.to_node, edge.from_node, edge.weight) + + if otherEdge ~= -1 then + graph:setEdgeWeight(otherEdge, edge.weight + 1) + end + + graph:setEdgeWeight(edge.id, edge.weight + 1) + end + if math.sqrDist(x, y, 40, 60) <= 20 * 20 then + local edge = graph:getEdge(edgeID) + local otherEdge = graph:getEdgeID(edge.to_node, edge.from_node, edge.weight) + + if edge.weight >= 2 then + if otherEdge ~= -1 then + graph:setEdgeWeight(otherEdge, edge.weight - 1) + end + graph:setEdgeWeight(edge.id, edge.weight - 1) + end + end + + if x >= 170 and y <= 30 then + regions:remove(reg_id) + end end; mouseup = function(self, x, y) end; mousemove = function(self, x, y, dx, dy) end; @@ -324,23 +410,9 @@ function createWeightChanger(edgeID) } end -function love.mousepressed(x, y, button, isTouch, presses) - regions:mousedown(x, y) -end - -function love.mousereleased(x, y, button, isTouch, presses) - regions:mouseup(x, y) -end - -function love.mousemoved(x, y, dx, dy) - regions:mousemove(x, y, dx, dy) -end - -function love.update() - regions:update() -end - -- DRAWING FUNCTIONS +local NODE_INNER_RADIUS = 17 +local NODE_OUTER_RADIUS = 20 function drawEdge(x1, y1, x2, y2, directed, weight, color) love.graphics.setColor(color) @@ -365,12 +437,12 @@ function drawEdge(x1, y1, x2, y2, directed, weight, color) love.graphics.rectangle("fill", cx - arrowSize * .6, cy - arrowSize * .6, arrowSize * 1.2, arrowSize * 1.2) end - love.graphics.setColor(1, 1, 1) - love.graphics.printf(tostring(weight), cx - 20, cy - 10, 40, "center") + if weight ~= nil then + love.graphics.setColor(1, 1, 1) + love.graphics.printf(tostring(weight), cx - 20, cy - 10, 40, "center") + end end -local NODE_INNER_RADIUS = 17 -local NODE_OUTER_RADIUS = 20 function drawGraph(graph, selectedNode) local nodes = graph:getNodes() local edges = graph:getEdges() @@ -420,6 +492,35 @@ function drawDijkstras(graph, dijkstras) end end +function drawTree(graph, tree) + love.graphics.setFont(GRAPH_FONT) + + for _, edge in ipairs(tree) do + local x1, y1 = graph:getNodePos(edge.from) + local x2, y2 = graph:getNodePos(edge.to) + + drawEdge(x1, y1, x2, y2, 0, nil, {1, 0, 0}) + end +end + + +-- Love +function love.update() + regions:update() +end + function love.draw() regions:draw() end + +function love.mousepressed(x, y, button, isTouch, presses) + regions:mousedown(x, y) +end + +function love.mousereleased(x, y, button, isTouch, presses) + regions:mouseup(x, y) +end + +function love.mousemoved(x, y, dx, dy) + regions:mousemove(x, y, dx, dy) +end diff --git a/modules/graph_algorithms.c b/modules/graph_algorithms.c index 7f5773a..9195835 100644 --- a/modules/graph_algorithms.c +++ b/modules/graph_algorithms.c @@ -23,7 +23,7 @@ static dj_node_p dj_search(header head, int start_node) } edge edge_walker = walker->neighbor_list; - while (edge_walker != NULL && is_in_list(visited_nodes, edge_walker->to_id) == 1) + while (edge_walker != NULL && is_in_list(visited_nodes, edge_walker->to_id) == 1) { edge_walker = edge_walker->next_edge; } @@ -37,6 +37,7 @@ static dj_node_p dj_search(header head, int start_node) push(stack, edge_walker->to_id); } } + return visited_nodes; } @@ -45,26 +46,28 @@ int breadth_first_search(lua_State *L) header head = (header)lua_touserdata(L, 1); int start_id = lua_tointeger(L, 2); int iterations = lua_tointeger(L, 3); + lua_pop(L, 3); int previous_node = start_id; int current_iterations = 0; - sq_node_p visited_nodes = NULL; + sq_node_p visited = NULL; sq_node_p from_visited_nodes = NULL; - enque(visited_nodes, start_id); - enque(from_visited_nodes, start_id); - sq_node_p queue = NULL; + sq_node_p from_queue = NULL; enque(queue, start_id); + enque(from_queue, start_id); while(queue != NULL && current_iterations <= iterations) { int node_id = front(queue); + int previous_node = front(from_queue); deque(queue); + deque(from_queue); - if(sq_contains(visited_nodes, node_id)) + if(sq_contains(visited, node_id)) continue; connect runner = find_node(head, node_id); @@ -74,49 +77,45 @@ int breadth_first_search(lua_State *L) while(edge_runner != NULL) { enque(queue, edge_runner->to_id); + enque(from_queue, runner->node_id); edge_runner = edge_runner->next_edge; } enque(from_visited_nodes, previous_node); - previous_node = node_id; - enque(visited_nodes, node_id); + enque(visited, node_id); current_iterations++; } - deque(visited_nodes); - deque(from_visited_nodes); - - //BUILD OUT RETURN TO LUA lua_newtable(L); - sq_node_p vwalker; - sq_node_p fvwalker; + int index = 1; - while (vwalker != NULL) + while (visited != NULL) { lua_pushnumber(L, index); lua_newtable(L); - lua_pushnumber(L, front(fvwalker)); + lua_pushnumber(L, front(from_visited_nodes)); lua_setfield(L, 3, "from"); - deque(fvwalker); + deque(from_visited_nodes); - lua_pushnumber(L, front(vwalker)); + lua_pushnumber(L, front(visited)); lua_setfield(L, 3, "to"); - deque(vwalker); + deque(visited); lua_settable(L, 1); index++; } + lua_pushboolean(L, queue == NULL); - sq_delete(visited_nodes); + sq_delete(visited); sq_delete(from_visited_nodes); sq_delete(queue); - return 1; + return 2; } int depth_first_search(lua_State *L) @@ -124,77 +123,75 @@ int depth_first_search(lua_State *L) header head = (header)lua_touserdata(L, 1); int start_id = lua_tointeger(L, 2); int iterations = lua_tointeger(L, 3); - - int previous_node = start_id; + lua_pop(L, 3); int current_iterations = 0; - sq_node_p visited_nodes = NULL; + sq_node_p visited = NULL; sq_node_p from_visited_nodes = NULL; - enque(visited_nodes, start_id); - enque(from_visited_nodes, start_id); + //enque(visited, start_id); + //enque(from_visited_nodes, start_id); sq_node_p stack = NULL; + sq_node_p from_stack = NULL; push(stack, start_id); + push(from_stack, start_id); - while(stack != NULL && current_iterations <= iterations) + while (stack != NULL && current_iterations <= iterations) { int node_id = top(stack); + int previous_node = top(from_stack); pop(stack); + pop(from_stack); - if(sq_contains(visited_nodes, node_id)) + if(sq_contains(visited, node_id)) continue; connect runner = find_node(head, node_id); edge edge_runner = runner->neighbor_list; //grab the neighbor list of our current node - while(edge_runner != NULL) + while (edge_runner != NULL) { push(stack, edge_runner->to_id); + push(from_stack, runner->node_id); edge_runner = edge_runner->next_edge; } enque(from_visited_nodes, previous_node); - previous_node = node_id; - enque(visited_nodes, node_id); + enque(visited, node_id); current_iterations++; } - deque(from_visited_nodes); - deque(visited_nodes); - - //BUILD OUT RETURN TO LUA lua_newtable(L); - sq_node_p vwalker; - sq_node_p fvwalker; int index = 1; - while (vwalker != NULL) + while (visited != NULL) { lua_pushnumber(L, index); lua_newtable(L); - lua_pushnumber(L, front(fvwalker)); + lua_pushnumber(L, front(from_visited_nodes)); lua_setfield(L, 3, "from"); - deque(fvwalker); + deque(from_visited_nodes); - lua_pushnumber(L, front(vwalker)); + lua_pushnumber(L, front(visited)); lua_setfield(L, 3, "to"); - deque(vwalker); + deque(visited); lua_settable(L, 1); index++; } + lua_pushboolean(L, stack == NULL); - sq_delete(visited_nodes); + sq_delete(visited); sq_delete(from_visited_nodes); sq_delete(stack); - return 1; + return 2; } int dijkstras(lua_State *L) @@ -314,3 +311,182 @@ int dijkstras(lua_State *L) return 2; } +int prims(lua_State *L) +{ + header head = (header)lua_touserdata(L, 1); + int start_id = lua_tointeger(L, 2); + int iterations = lua_tointeger(L, 3); + lua_pop(L, 3); + + sq_node_p visited_nodes = NULL; + sq_node_p from_visited_nodes = NULL; + enque(visited_nodes, start_id); + enque(from_visited_nodes, start_id); + + int min_edge_weight; + int from_node_id; + int to_node_id; + + int current_iterations = 0; + int is_completed = 0; + + while (current_iterations <= iterations) + { + min_edge_weight = -1; + from_node_id = -1; + to_node_id = -1; + + edge edge_runner = NULL; + sq_node_p node_runner = visited_nodes; + while(node_runner != NULL) + { + edge_runner = find_node(head, node_runner->value)->neighbor_list; + while(edge_runner != NULL) + { + if(sq_contains(visited_nodes, edge_runner->to_id) == 0 && (edge_runner->weight < min_edge_weight || min_edge_weight == -1)) + { + min_edge_weight = edge_runner->weight; + from_node_id = node_runner->value; + to_node_id = edge_runner->to_id; + } + + edge_runner = edge_runner->next_edge; + } + + node_runner = node_runner->next; + } + + if(min_edge_weight == -1) + { + is_completed = 1; + break; + } + + enque(visited_nodes, to_node_id); + enque(from_visited_nodes, from_node_id); + + current_iterations++; + } + + + //RETURN STUFF + lua_newtable(L); + deque(visited_nodes); + deque(from_visited_nodes); + + int index = 1; + while (visited_nodes != NULL) + { + lua_pushnumber(L, index); + + lua_newtable(L); + + lua_pushnumber(L, front(from_visited_nodes)); + lua_setfield(L, 3, "from"); + deque(from_visited_nodes); + + lua_pushnumber(L, front(visited_nodes)); + lua_setfield(L, 3, "to"); + deque(visited_nodes); + + lua_settable(L, 1); + + index++; + } + + lua_pushboolean(L, is_completed == 1); + + //MEMORY IS ALREADY FREE'D FROM DEQUEs + //sq_delete(visited_nodes); + //sq_delete(from_visited_nodes); + return 2; +} + + +int kruskals(lua_State *L) +{ + header head = (header)lua_touserdata(L, 1); + int iterations = lua_tointeger(L, 3); + lua_pop(L, 2); + + sq_node_p visited_nodes = NULL; + sq_node_p from_visited_nodes = NULL; + + int min_edge_weight; + int from_node_id; + int to_node_id; + + int current_iterations = 0; + int is_completed = 0; + + while (current_iterations <= iterations) + { + min_edge_weight = -1; + from_node_id = -1; + to_node_id = -1; + + edge edge_runner = NULL; + connect node_runner = head->front; + while(node_runner != NULL) + { + edge_runner = node_runner->neighbor_list; + while(edge_runner != NULL) + { + if((sq_contains(visited_nodes, edge_runner->to_id) == 0 || sq_contains(visited_nodes, node_runner->node_id) == 0) && (edge_runner->weight < min_edge_weight || min_edge_weight == -1)) + { + min_edge_weight = edge_runner->weight; + from_node_id = node_runner->node_id; + to_node_id = edge_runner->to_id; + } + + edge_runner = edge_runner->next_edge; + } + + node_runner = node_runner->next_node; + } + + if(min_edge_weight == -1) + { + is_completed = 1; + break; + } + + enque(visited_nodes, to_node_id); + enque(from_visited_nodes, from_node_id); + + iterations++; + } + + + //RETURN STUFF + lua_newtable(L); + deque(visited_nodes); + deque(from_visited_nodes); + + int index = 1; + while (visited_nodes != NULL) + { + lua_pushnumber(L, index); + + lua_newtable(L); + + lua_pushnumber(L, front(from_visited_nodes)); + lua_setfield(L, 3, "from"); + deque(from_visited_nodes); + + lua_pushnumber(L, front(visited_nodes)); + lua_setfield(L, 3, "to"); + deque(visited_nodes); + + lua_settable(L, 1); + + index++; + } + + lua_pushboolean(L, is_completed == 1); + + //MEMORY IS ALREADY FREE'D FROM DEQUEs + //sq_delete(visited_nodes); + //sq_delete(from_visited_nodes); + return 2; +} \ No newline at end of file diff --git a/modules/graph_algorithms.h b/modules/graph_algorithms.h index 4cc8572..ab63cb2 100644 --- a/modules/graph_algorithms.h +++ b/modules/graph_algorithms.h @@ -1,3 +1,4 @@ + #ifndef __GRAPH_ALGORITHM_H__ #define __GRAPH_ALGORITHM_H__ @@ -6,5 +7,8 @@ #include "graph_types.h" LUA_FUNCTION(dijkstras); +LUA_FUNCTION(depth_first_search); +LUA_FUNCTION(breadth_first_search); +LUA_FUNCTION(prims); #endif \ No newline at end of file diff --git a/modules/graph_module.c b/modules/graph_module.c index 41f3cfd..7f3d2fe 100644 --- a/modules/graph_module.c +++ b/modules/graph_module.c @@ -26,6 +26,9 @@ int luaopen_graphs(lua_State *L) { "print_graph", print_graph }, { "dijkstras", dijkstras }, + { "depth_first_search", depth_first_search }, + { "breadth_first_search", breadth_first_search }, + { "prims", prims }, { NULL, NULL } }; diff --git a/modules/graph_standard.c b/modules/graph_standard.c index cabbd73..0c77360 100644 --- a/modules/graph_standard.c +++ b/modules/graph_standard.c @@ -31,7 +31,7 @@ int add_node(lua_State *L) new_node->x = 0; new_node->y = 0; - if (head->node_count == 0) + if (head == NULL || head->node_count == 0 || head->front == NULL) { new_node->node_id = 0; head->front = new_node; @@ -54,6 +54,7 @@ int add_node(lua_State *L) walker->next_node = new_node; } } + head->node_count++; lua_pushnumber(L,new_node->node_id); diff --git a/modules/graph_utils.c b/modules/graph_utils.c index eec6ad0..4b1ec28 100644 --- a/modules/graph_utils.c +++ b/modules/graph_utils.c @@ -96,7 +96,8 @@ int get_edge_id(lua_State *L) int edge_id = lua_tointeger(L, 2); lua_pop(L, 2); - edge e = get_edge(head, edge_id); + connect node = NULL; + edge e = get_edge(head, edge_id, &node); if (e == NULL) { lua_pushnil(L); } else { @@ -105,6 +106,12 @@ int get_edge_id(lua_State *L) lua_pushnumber(L, e->weight); lua_setfield(L, 1, "weight"); + lua_pushnumber(L, node->node_id); + lua_setfield(L, 1, "from_node"); + + lua_pushnumber(L, e->to_id); + lua_setfield(L, 1, "to_node"); + lua_pushnumber(L, e->edge_id); lua_setfield(L, 1, "id"); } @@ -119,7 +126,7 @@ int set_edge_weight(lua_State *L) int new_weight = lua_tointeger(L, 3); lua_pop(L, 3); - edge e = get_edge(head, edge_id); + edge e = get_edge(head, edge_id, NULL); if (e == NULL) return 0; e->weight = new_weight; @@ -225,7 +232,7 @@ edge find_edge(header head, int from_node, int to_node, int weight) return jogger; } -edge get_edge(header head, int edge_id) +edge get_edge(header head, int edge_id, connect* node) { connect jogger = head->front; while (jogger != NULL) @@ -236,6 +243,9 @@ edge get_edge(header head, int edge_id) { if (curr_edge->edge_id == edge_id) { + if (node != NULL) + *node = jogger; + return curr_edge; } diff --git a/modules/graph_utils.h b/modules/graph_utils.h index b6f1f26..63d4c3d 100644 --- a/modules/graph_utils.h +++ b/modules/graph_utils.h @@ -40,6 +40,6 @@ LUA_FUNCTION(print_graph); connect find_node(header head, int node_id); edge find_edge(header head, int from_node, int to_node, int weight); -edge get_edge(header head, int edge_id); +edge get_edge(header head, int edge_id, connect* node); #endif \ No newline at end of file diff --git a/modules/utils.c b/modules/utils.c index 4352cb5..12717cd 100644 --- a/modules/utils.c +++ b/modules/utils.c @@ -44,8 +44,7 @@ sq_node_p sq_pop(sq_node_p stack_top) stack_top = stack_top->next; - int n = temp->value; - free(temp); + free(temp); //dump the removed top of stack return stack_top; } @@ -76,17 +75,17 @@ sq_node_p sq_enque(sq_node_p front_of_queue, int val) sq_node_p sq_deque(sq_node_p front_of_queue) { - if(front_of_queue == NULL) + sq_node_p temp = front_of_queue; + + if(temp == NULL) { puts("QUEUE IS ALREADY EMPTY"); return NULL; } - sq_node_p temp = front_of_queue; - front_of_queue = front_of_queue->next; - free(temp); //dump the removed queue + free(temp); //dump the removed front of queue return front_of_queue; } @@ -120,15 +119,8 @@ void sq_print(sq_node_p sq) void sq_delete(sq_node_p sq) { - sq_node_p runner = sq; - while(sq != NULL) - { - sq_node_p tmp = sq; - sq = sq->next; - - free(tmp); - } + pop(sq); } dj_node_p insert_dj(dj_node_p front_of_list, int id, int distance)