Graph challenge: Get adjacency list from list of children nodes
Date : March 29 2020, 07:55 AM
this one helps. Not quite recursive, but you could iterate through each child, look it up, and remove all of its children from the current node: def get_adjacency(graph):
graph = {node: set(children) for node, children in graph.items()}
for node, children in graph.items():
for child in children:
children = children - graph[child]
graph[node] = children
return {node: list(children) for node, children in graph.items()}
c = {
'a': ['b','c','d','e'],
'b': ['d'],
'c': ['d','e'],
'd': [],
'e': [],
'f': ['i','j','c','e','d'],
'i': ['c','e','d'],
'j': ['e']
}
print get_adjacency(c)
|
Convert C# class to C++ in implementing graph nodes in C++
Tag : chash , By : Carlos Galdino
Date : March 29 2020, 07:55 AM
will be helpful for those in need My C++ is very rusty. Before we tackle the coding there are some things you need to know. Classes can not directly have access modifiers like public, protected, private or in C++. Meaning we are getting a problem already at private class Node. class Outer
{
private:
class Node
{
public:
}
};
int mValue;
Node* mNodes;
bool mSelected;
#ifndef OUTER_H
#define OUTER_H
class Outer
{
private:
class Node
{
public:
int mValue;
Node* mNodes;
bool mSelected;
}
};
#endif
|
Killed: 9 Creating a graph from a list of nodes and a list of links
Date : March 29 2020, 07:55 AM
This might help you First of all, your second attempt would try to add the same link multiple times; in the worst case, the last link in your links vector might get added as many times as there are nodes in the nodes vector. So, that approach won't work. Second, igraph is not very efficient when you add nodes or edges one by one (due to the indexing operation that it performs after every node addition or removal). It is best to add them in "batches", i.e. prepare multiple nodes or edges to add and then add them at once with a single call to add_vertices() or add_edges(). g = Graph.DictList(vertices=nodes, edges=links, vertex_name_attr="toid", edge_foreign_keys=("positiveNode", "negativeNode")
all_node_ids = set(edge["positiveNode"] for edge in links) | set(edge["negativeNode"] for edge in links)
known_node_ids = set(node["toid"] for node in nodes)
for node in all_node_ids - known_node_ids:
nodes.append({u'toid': node})
|
Elasticsearch query for getting all nodes of a graph's adjacency list (building graph in javascript)
Date : March 29 2020, 07:55 AM
With these it helps Since am more used to JavaScript than the elasticsearch query language, I ended up just using a DFS implementation ( https://en.wikipedia.org/wiki/Depth-first_search) with simple ES queries to get all of the nodes connected to a single selected node this.selectedNode one DFS run to get all the parents (and other ancestors) and another DFS run to get all the children. The code is presented below (its a bit verbose, but main functions to note are buildGraph and _dfs to get the gist of the algorithm here (also note, using a field sources instead of parents as in the question)): async function _getParents(child) {//see https://tutorialzine.com/2017/07/javascript-async-await-explained
// queries our main DB of nodes to get all nodes n with...
// n.currId = child.prevId or child.sources.includes(n.currId)
let data = {
"sort": {"timestamp": {"order": "desc"}},
"query": {
"bool": {
"should": [
{"match": {"currId": child.prevId}},
//{"match": {"currId": child.sources}}
],
"should": child.sources.map((id) => {return {"match": {"currId": id}}})
}//TODO: use pure ES query to match against ES sources array
}
}
let nodes = []
let res = await axios.get("http://myesserver:9200/myindex/mytype/_search", {
// for submiting to elasticsearch, see https://stackoverflow.com/a/45292081/8236733
params: {
source: JSON.stringify(data),
source_content_type: 'application/json'
}
})
console.log('NEW PARENT NODES')
nodes = res['data']['hits']['hits'].map(record => {return record['_source']} )
console.log(nodes)
return nodes
}
async function _getChildren(parent) {// see https://tutorialzine.com/2017/07/javascript-async-await-explained
// queries our main DB of nodes to get all nodes n with...
// n.prevId == parent.currId or n.sources.includes(parent.currId)
let data = {
"sort": {"timestamp": {"order": "desc"}},
"query": {
"bool": {
"should": [
{"match": {"prevId": parent.currId}},
{"match": {"sources": parent.currId}}
]
}
}
}
let nodes = []
let res = await axios.get("http://myesserver:9200/myindex/mytype/_search", {
// for submiting to elasticsearch, see https://stackoverflow.com/a/45292081/8236733
params: {
source: JSON.stringify(data),
source_content_type: 'application/json'
}
})
console.log('NEW CHILD NODES')
nodes = res['data']['hits']['hits'].map(record => {return record['_source']} )
console.log(nodes)
return nodes
}
/**
*
*
* @param {*} root
* @param {(v)=>{}} stopper callback for conditional to determine whether to visit a node
* @param {(v)=>{}} visit callback for what to do when visit each node
* @param {(v)=>{}} getNext callback for how to get the children of a node
*/
async function _dfs(root, stopper, visit, getNext) {//see https://tutorialzine.com/2017/07/javascript-async-await-explained
/* getting children */
/* using DFS method */
console.log('starting wth root node:')
console.log(root)
let s = []
s.push(root)
console.log('initialized stack (FIXME: not showing correctly for some reason):')
console.log(s)
while (s.length > 0) {
let v = s.pop()
console.log('popped:')
console.log(v)
console.log(v.sources)
if (stopper(v)) {
/* save this node for the graph */
visit(v)
/* get the children of this node */
let kids = await getNext(v)
s = s.concat(kids)
console.log('concated stack:')
console.log(s)
}
}
}
/**
*
*
* @param {*} startn the node of the graph that we initially start with
* @param {*} nodes
* @param {*} edges
*/
async function buildGraph(startn, nodes, edges) {
// Had to do async all the way down b/c of the async axios requests to the ES server
//see https://tutorialzine.com/2017/07/javascript-async-await-explained
/* getting ancestors */
// if wanted to get siblings as well, this would be the DFS branch to implement that in
let discovered = []
await _dfs(startn,
(v)=>{return !discovered.includes(v.currId)},
(v)=>{
discovered.push(v.currId)
nodes.push({id: v.currId, label: v.currLocation})
if (v.prevId != 'NULL') {
edges.push({from: v.prevId, to: v.currId})
}
if (v.sources.length > 0 && v.sources[0] != 'NULL') {
for (let i=0; i < v.sources.length; i++) {
edges.push({from: v.sources[i], to: v.currId})
}
}
},
(v)=>{return _getParents(v)})
console.log('completed collecting ancestor nodes')
console.log(nodes)
/* getting children */
// remove root from discovered, so can do another dfs
for (var i=discovered.length-1; i>=0; i--) {
if (discovered[i] === startn.currId) {
discovered.splice(i, 1);
// break; //<-- Uncomment if only the first term has to be removed
}
}
await _dfs(startn,
(v)=>{return !discovered.includes(v.currId)},
(v)=>{
discovered.push(v.currId)
// can't add origin node with same id to graph again in react-graph-vis
if (v.currId != startn.currId) {
nodes.push({id: v.currId, label: v.currLocation})
}
if (v.prevId != 'NULL') {
edges.push({from: v.prevId, to: v.currId})
}
if (v.sources.length > 0 && v.sources[0] != 'NULL') {
for (let i=0; i < v.sources.length; i++) {
edges.push({from: v.sources[i], to: v.currId})
}
}
},
(v)=>{return _getChildren(v)})
console.log('completed collecting child nodes')
console.log(nodes)
}
let nodes = []
let edges = []
buildGraph(this.selectedNode, nodes, edges).then(res => {
console.log('buildGraph promise result:')
console.log(res, nodes, edges)
this.setState({nodes: nodes, edges: edges})
})
|
Given nodes of a graph on a circle, find minimum number of nodes to be removed to have a graph in which each node has ed
Date : September 28 2020, 10:00 AM
will help you Let assume that we have a graph with n nodes, 0 to n - 1. If we view the problem as finding the shortest cycle from node A back to A, the distance between node a and b is the absolute different (b - a - 1) (which is all the nodes between those two) and we could only go from a to b if b > a or a is the start node. This problem is reduced to classic finding the shortest path in the graph. class State{
int node, distance;
}
int result = n - 1;
for(int i = 0; i < n; i++){
//Find the shortest path to move from i -> i
PriorityQueue<State> q = new PriorityQueue<>((a , b) -> Integer.compare(a.distance, b.distance));
for(int j : map[i]) {
if( j > i){
q.add(new State(j , j - i + 1);
}
}
int[]dist = new int[n];
Arrays.fill(dist, n - 1);
while(!q.isEmpty()){
State s = q.poll();
if(s.distance != dist[s.node]){
continue;
}
for(int j : map[s.node]){
if((j > s.node || j == i) && dist[j] > s.distance + (j - s.node + 1)){
dist[j] = s.distance + (j - s.node + 1);
q.add(new State(j, dist[j]);
}
}
}
result = Integer.min(result, dist[i]);
}
|