networkx How to loop through each cluster in graph - networkx

https://ibb.co/xKbTFK9
graph like:
1-8-2 90-22 78-75
8-99
214-2421-200-421
If i have a graph like that with many connected nodes in cluster as you see in the image, how can i iterate through each cluster in for loop like this:
for cluster in graph:
.....do something with cluster....
for node in cluster:
.....do something with node....

if you want to do this just once then do the following:
for connected_comp_subgraph in nx.connected_component_subgraphs(G):
... do something ....
for node in connected_comp_subgraph:
...do something...
If you just need a list of the nodes in each connected component rather than an actual graph, you can do
for connected_comp in nx.connected_components(G):
... do something ....
for node in connected_comp:
...do something...
If you're going to do this multiple times and you don't want to recalculate these components each time, first do
connected_component_subgraphs = list(nx.connected_component_subgraphs(G))
Without list, you get a "generator" which is more efficient memory/speed wise, but it calculates a component and as soon as you use it, it is completely forgotten. Then it calculates the next one. So if you want to save the components, store them in a list.

Related

NodeRED : chart node does not show multiple lines?

I have a NodeRED flow setup with a chart node. In my function node I have a super simple code as following
var left = {payload : msg.payload.readResults[0].v };
var right = {payload : msg.payload.readResults[1].v };
return [[left,right]];
Now I have a debug node connected to both function node and chart node and was hoping the cart would output 2 lines(one for each result).
But all I see is just one line with one color and the debug node connected to the graph is outputting Arrays of multiple objects while the debug node connected to the function is outputting the numbers as I'm expecting.
What am I doing wrong here to get output of 2 lines(left and right variables) with different colors?
You need to add msg.topic values to each message so the chart node knows to assign the values to different datasets.
As it is it will just plot both messages as if they are the same dataset.
From the docs:
Line charts
To display two or more lines on the same chart then each msg must also
contain topic property that identifies which data series it belongs to
for example:
{topic:"temperature", payload:22}
{topic:"humidity", payload:66}

AnyLogic - is there a way to convert a Node from network.nodes() to Rectangular Node?

I am looking to dynamically add each Rectangular Node from my network to a particular collection, on simulation startup. I'm doing this because I will have 1000+ nodes and adding them manually is undesirable.
Each of these nodes is named using a convention and start with either "lane" or "grid".
If it is "lane" then it adds to one collection, and "grid" to the other.
Currently I am using the code:
for (Node n : network.nodes()) {
String layoutIdentifier = n.getName().split("_")[0];
if (layoutIdentifier.equals("lane")) {
laneNodes.add(n);
traceln(n);
//Lane newLane = add_lanes(n);
} else if (layoutIdentifier.equals("grid")) {
gridNodes.add(n);
}
}
This is working fine and adds them to the collections as Nodes, but I was really wanting to add them to collections of Rectangular Nodes (which is what they are) as I need to use this type in my Agents.
I tried this code (changing Node to RectangularNode):
for (RectangularNode n : network.nodes()) {
String layoutIdentifier = n.getName().split("_")[0];
if (layoutIdentifier.equals("lane")) {
laneNodes.add(n);
traceln(n);
//Lane newLane = add_lanes(n);
} else if (layoutIdentifier.equals("grid")) {
gridNodes.add(n);
}
}
but get the error
Type mismatch: cannot convert from element type Node to RectangularNode. Location: pbl_congestion_simulation/Main - Agent Type
Is there a way to convert the Node to RectangularNode? Or a better way to run through all the nodes in the network and add them as Rectangular nodes to collections of the same?
I can see that the Nodes are referenced as com.anylogic.engine.markup.RectangularNode#293cc7d0 so was hoping that RectangularNode portion could be accessed.
many thanks.
Your first code is fine, you can have a collection with elements of type RectangularNode and the only thing you need to change on that code is:
laneNodes.add((RectangularNode)n);
gridNodes.add((RectangularNode)n);
You can transform a node into a rectangular node, but not the other way around, that's why your second code doesn't work.
If you have other nodes on the network, that are not rectangular nodes, then you can add something like this:
if(n.getClass().equals(RectangularNode.class))
laneNodes.add((RectangularNode)n);

Find all paths starting from source node with Perl

First I would like to clarify that I have very little experience with Graph Theory and the proper algorithms to parse a directed graph, and that I've searched here on SO but didn't quite find what I was looking for. Hopefully you guys can help me :)
I have a large directed graph (around 3000 nodes) that has several subgraphs made out of connected nodes, and the subgraphs are not connected to each other. Here is a small representative graph of the data I have here:
I am writing a Perl script to find all possible paths starting from each source node to the sink nodes and store them in an array of arrays. So, for this graph, the possible paths would be:
1,2,3,4,5,6
1,2,3,4,5,7
1,8,9,10
11,12,13
11,14
15,16,17
The way I've done this search in my script was to use the Graph module in the following steps:
Find all source nodes in the graph and store them in an array
Find all sink nodes in the graph and store them in an array
Find all pairs short paths with the Floyd-Warshall algorithm
Search the APSP Floyd-Warshall graph object if exist a path between a source node and a sink node. If there is a path, store it in array of arrays. If there isn't a path, do nothing.
Here is the part of my script that does it:
#Getting all source nodes in the graph:
my #source_nodes = $dot_graph->source_vertices();
my #sink_nodes = $dot_graph->sink_vertices();
# Getting all possible paths between from source to sink nodes in the graph:
print "Calculating all possible overlaps in graph\n";
my $all_possible_paths = $dot_graph->APSP_Floyd_Warshall();
print "Done\n";
# print "Extending overlapping contigs\n";
my #all_paths;
foreach my $source (#source_nodes) {
foreach my $sink (#sink_nodes) {
my #path_vertices = $all_possible_paths->path_vertices($source, $sink);
my $path_length = $all_possible_paths->path_length($source,$sink);
#Saving only the paths that actually exist:
push (#all_paths, \#path_vertices) unless (!#path_vertices);
}
}
The problem with that is that it works fine for small graphs, but now that I have 3000 nodes, it would take a very very long time to finish (assuming that each path would take 1ms to be found, it would take 312.5 days to go through all of them). I know using the Floyd-Warshall algorithm to find all possible paths in the graph to only find the paths between sources and sinks is not efficient, but when I wrote the script I needed the results as soon as possible and my graphs were a lot smaller.
My question is how can I find the all paths starting from each source in the graph that will end in a sink node, without find all possible paths first? Is that what is called a breadth-first or a depth-first search? How to implement that with Perl (and if possible, with the Graph module)? Any help would be awesome!
P.S.: In order to make the program run faster, I started trying to breaking the initial big graph into its subgraphs and running the original script, but forking the main loop that searches for the paths between sources and sinks using Parallel::ForkManager. What do you guys think of that approach?
You're not interested in finding the shortest path, so forget about all those shortest path algorithms.
You're interested in finding all paths. This is called tree traversal, and it can be performed depth-first or breadth-first. Since you're traversing the entire tree, it doesn't really matter which approach is taken. The following performs a depth-first search using recursion:
sub build_paths {
my ($graph) = #_;
my #paths;
local *_helper = sub {
my $v = $_[-1];
my #successors = $graph->successors($v);
if (#successors) {
_helper(#_, $_)
for #successors;
} else {
push #paths, [ #_ ];
}
};
_helper($_)
for $graph->source_vertices();
return \#paths;
}
die if $graph->has_a_cycle;
my $paths = build_paths($graph);
Yes, it would be possible to parallelize the work, but I'm not writing that for you.
What concerns me the most is memory. Depending on the number of branches in the paths, you could easily end up running out of memory. Note that storing the paths as strings (of comma-separated values) would take less memory than storing them as arrays.

Creating custom widgets for ruby gem dashing.io - Or combining widgets elements

I'm working with the dashing ruby gem and I would really like to combine elements of the graph and number widgets. I would like all elements of the graph and include the up/down percentage arrow from the number widget.
I've never done much work with ruby and I understand there are a few files within the widget that might need to be changed.
I've setup a few nice widgets and I'm using a job to pull data from a redis db to populate. I've added the following to the graph.html page:
<p class="change-rate">
<i data-bind-class="arrow"></i><span data-bind="difference"></span>
</p>
This has no effect, and I'm sure that I'm missing something in one of the many files that makes this all work.
Your on the right track, and I've actually put together something very similar but in order to complete what you are trying to do you need to send data to your two new data binds, which would be done with your jobs file and the graph.coffee file.
I'm not sure how exactly you're getting your graph data from redis to your jobs erb file but you will want to setup a couple new variables, for the example I have used nowNumber and lastNumber. These will be the number that the valuation is performed on.
jobs/jobname.erb
send_event('graph', points: points, current: nowNumber, last: lastNumber )
If you print this out you will get something like this:
{:points=>[{:x=>6, :y=>64}, {:x=>5, :y=>62}, {:x=>4, :y=>56}], :current=>57, :last=>64}
Tweak your graph/graph.coffee file:
# The following 6 lines aren't needed for your solution, but if you wanted to take advantage of 'warning', 'danger', and 'ok' status classes (changes background color and flashes), just feed your send_event with 'status: [one of the three status names]
if data.status
# clear existing "status-*" classes
$(#get('node')).attr 'class', (i,c) ->
c.replace /\bstatus-\S+/g, ''
# add new class
$(#get('node')).addClass "status-#{data.status}"
#accessor 'difference', ->
if #get('last')
last = parseInt(#get('last'))
current = parseInt(#get('current'))
if last != 0
diff = Math.abs(Math.round((current - last) / last * 100))
"#{diff}%"
else
""
# Picks the direction of the arrow based on whether the current value is higher or lower than the last
#accessor 'arrow', ->
if #get('last')
if parseInt(#get('current')) > parseInt(#get('last')) then 'icon-arrow-up' else 'icon-arrow-down'

Traversing DOM nodes in CKEditor-4

We have a bug at this CKEditor plugin, and a generic solution is like to this, applying a generic string-filter only to terminal text nodes of the DOM.
QUESTION: how (need code example) to traverse a selection node (editor.getSelection()) by CKEditor-4 tools, like CKEDITOR.dom.range?
First step will be to get ranges from current selection. To do this just call:
var ranges = editor.getSelection().getRanges();
This gives you an array of ranges, because theoretically (and this theory is proved only by Firefox) one selection can contain many ranges. But in 99% of real world cases you can just handle the first one and ignore other. So you've got range.
Now, the easiest way to iterate over each node in this range is to use CKEDITOR.dom.walker. Use it for example this way:
var walker = new CKEDITOR.dom.walker( range ),
node;
while ( ( node = walker.next() ) ) {
// Log values of every text node in range.
console.log( node.type == CKEDITOR.NODE_TEXT && node.getText() );
}
However, there's a problem with text nodes at the range's boundaries. Consider following range:
<p>[foo<i>bar</i>bo]m</p>
This will log: foo, bar, and bom. Yes - entire bom, because it is a single node and walker does not modify DOM (there's a bug in documentation).
Therefore you should check every node you want to transform if it equals range's startContainer or endContainer and if yes - transform only that part of it which is inside range.
Note: I don't know walker's internals and I'm not sure whether you can modify DOM while iterating over it. I'd recommend first caching nodes and then making changes.