Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
generate algebraic expression from cyclic graph (#736)
* generate algebraic expression from cyclic graph * improved longest path starting point candidate nomination
- Loading branch information
Showing
11 changed files
with
154 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,5 +11,6 @@ | |
#include "./dfs.h" | ||
#include "./all_paths.h" | ||
#include "./detect_cycle.h" | ||
#include "./longest_path.h" | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* Copyright 2018-2019 Redis Labs Ltd. and Contributors | ||
* | ||
* This file is available under the Redis Labs Source Available License Agreement | ||
*/ | ||
|
||
#include "./longest_path.h" | ||
#include "./bfs.h" | ||
#include "./dfs.h" | ||
#include "../util/arr.h" | ||
#include"./detect_cycle.h" | ||
|
||
// Scans the graph in a DFS fashion, keeps track after the longest path length. | ||
static void __DFSMaxDepth(QGNode *n, int level, int *max_depth, rax *visited) { | ||
if(level > *max_depth) *max_depth = level; | ||
|
||
// Mark n as visited, return if node already marked. | ||
if(!raxInsert(visited, (unsigned char *)n->alias, strlen(n->alias), NULL, NULL)) { | ||
// We've already processed n. | ||
return; | ||
} | ||
|
||
// Expand node N by visiting all of its neighbors | ||
for(uint i = 0; i < array_len(n->outgoing_edges); i++) { | ||
QGEdge *e = n->outgoing_edges[i]; | ||
__DFSMaxDepth(e->dest, level + 1, max_depth, visited); | ||
} | ||
|
||
for(uint i = 0; i < array_len(n->incoming_edges); i++) { | ||
QGEdge *e = n->incoming_edges[i]; | ||
__DFSMaxDepth(e->src, level + 1, max_depth, visited); | ||
} | ||
|
||
raxRemove(visited, (unsigned char *)n->alias, strlen(n->alias), NULL); | ||
} | ||
|
||
// Finds out the longest path distance from given node. | ||
static int _DFSMaxDepth(QGNode *n) { | ||
int level = 0; // Starting at level 0. | ||
int max_depth = 0; // Longest path length. | ||
rax *visited = raxNew(); // Dictionary of visited nodes. | ||
|
||
__DFSMaxDepth(n, level, &max_depth, visited); | ||
|
||
raxFree(visited); | ||
return max_depth; | ||
} | ||
|
||
// Finds the longest path in an cyclic graph. | ||
QGNode *LongestPathGraph(const QueryGraph *g, int *level) { | ||
/* To find the longest path in a graph containing a cycle | ||
* where we do not expand from a visited node: | ||
* 1. the entire graph is a cycle, in which case it doesn't matter | ||
* which node we pick to begin out traversal. | ||
* 2. there's a node with in-degree of out-degree 0, as we know | ||
* this node resided on the "edge" of the graph from which the longest path | ||
* begins/ends. */ | ||
|
||
QGNode *n = NULL; // Node from which the longest path expand. | ||
uint node_count = QueryGraph_NodeCount(g); | ||
for(uint i = 0; i < node_count; i++) { | ||
n = g->nodes[i]; | ||
if(QGNode_IncomeDegree(n) == 0 || QGNode_OutgoingDegree(n) == 0) { | ||
*level = _DFSMaxDepth(n); | ||
return n; | ||
} | ||
} | ||
|
||
// All nodes are part of a cycle, pick one randomly. | ||
n = g->nodes[0]; | ||
*level = _DFSMaxDepth(n); | ||
return n; | ||
} | ||
|
||
// Finds the longest path in an acyclic graph. | ||
QGNode *LongestPathTree(const QueryGraph *g, int *level) { | ||
int l = BFS_LOWEST_LEVEL; | ||
QGNode **leafs = BFS(g->nodes[0], &l); | ||
QGNode *leaf = leafs[0]; | ||
array_free(leafs); | ||
|
||
l = BFS_LOWEST_LEVEL; | ||
leafs = BFS(leaf, &l); | ||
|
||
assert(array_len(leafs) > 0 && l >= 0); | ||
QGNode *n = leafs[0]; | ||
array_free(leafs); | ||
|
||
*level = l; | ||
return n; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Copyright 2018-2019 Redis Labs Ltd. and Contributors | ||
* | ||
* This file is available under the Redis Labs Source Available License Agreement | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "../graph/query_graph.h" | ||
#include "../graph/entities/qg_node.h" | ||
|
||
// Determins the longest path length within a tree structured graph. | ||
QGNode *LongestPathTree(const QueryGraph *g, int *level); | ||
// Determins the longest path length within a graph (containing cycles). | ||
QGNode *LongestPathGraph(const QueryGraph *g, int *level); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -161,4 +161,3 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) | |
|
||
return REDISMODULE_OK; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters