1

everybody. I'm building a DiGraph using NetworkX and iterating an algorithm over it. In a particular iteration, every node "n" changes a specific attribute, let's say "A_n". Now, every edge concerning to this particular node "n" and a given predecessor "m", has another attribute of interest, that depends on "A_n", let's call it "B_mn". My question is: Is it possible to update "B_mn" "automatically" by modifying "A_n" for all "n","m" in my set of nodes? I mean, not iterating over the nodes, and then over their predecessors, but using kind of a dinamic function "B_mn(A_n)" that changes its value at the very moment "A_n" changes. Is this possible?

I thinking in something like this:

Let X and Y be numbers, let's suppose that

G.node["n"]["A"]=X and G.edge["m"]["n"]["B"]= Y+G.node["n"]["A"]

I want that by changing the value of X, the value of the attribute "B" in the edge would be updated as well.

Thank you very much in advance for your help :)

Lucho_TJ
  • 13
  • 4
  • I did not quite understand what you want, [but the solution of this question can help you](https://stackoverflow.com/questions/29800722/can-be-saved-into-a-variable-one-condition). – macabeus Jan 12 '16 at 20:27
  • Are you okay with the attribute of B simply being a function that is evaluated each time you try to access it (depending on what you're doing this may be expensive if evaluated many times), or do you really want it to be have a defined value that gets updated each time a node changes (depending on what you're doing this may be expensive if node weights change a lot while edge weights aren't accessed often). The first is relatively straightforward. The second is harder. – Joel Jan 12 '16 at 22:09

1 Answers1

0

One problem with this question -> Don't ever delete nodes.

In your example you are assigning X to G.node["n"]["A"]. If you say:

G.node["n"]["A"] = 5
G.node["n"]["A"] = 6

That destroy's data locations and now G.node["n"]["A"] is pointing to a new object with a new memory location.

Instead of assignment like '=' you need to do an update of X. Which will leave the datatype and memory location in place. Which means you need a datatype which supports ".update()" like a dictionary.

Everything past here is dependent on your use case:


If the node data is a value (like an int or float) then you don't have a problem adding them together. You can keep running calculations based on value addition of changes only 1 level deeper than the calculation is being performed.

However if the node data is an expression of expressions... example G.node.get('n')['A']+ G.node.get('m')['A'] (which G.node.get('m')['A'] is also an expression that needs to be evaluated.)

then you have one of 2 problems:

  • You will need a recursive function that does the evaluating OR
  • You will need to keep a running list of dictionaries outside of the Graph and perform the running evaluation there which will update the data values in the Graph.

It is possible to do this all within the graph using something like ast.literal_eval() (warning this is not a GOOD idea)

If you only have one operation to perform (addition?) then there are some tricks you can use like keep a running list of the data locations and then do a sum().

Back2Basics
  • 7,406
  • 2
  • 32
  • 45