Initial Answer - Based on nx.simple_cycles
There are many ways to achieve what you're looking for, but here's one suggestion:
First, let me replace the original graph with one that has more cycles and another layout.
G = nx.DiGraph()
G.add_edges_from([('A', 'B'),('B', 'A'), ('C','D'),('G','D')], weight=50)
G.add_edges_from([('D','B')], weight=1)
G.add_edges_from([('B','C'),('F','E'),('E','A')], weight=2)
G.add_edges_from([('C','F'),('B','G'),('A','G')], weight=3)
edge_labels=dict([((u,v,),d['weight'])
for u,v,d in G.edges(data=True)])
# improve layout and draw node labels
pos=nx.drawing.layout.circular_layout(G,scale=10)
nx.draw_networkx_edge_labels(G,pos,edge_labels=edge_labels)
nx.draw_networkx_labels(G,pos,font_color='white')
nx.draw(G,pos, node_size=1500,edge_cmap=plt.cm.Reds)

Now we find all simple cycles in G that start and end at a given node of interest and calculate n for each cycle.
# node of interest
inode = 'A'
acycs = [ cyc for cyc in nx.simple_cycles(G) if inode in cyc ]
# for ease of computation we append the first node to the end of each cycle
acycs = [cyc+[cyc[0]] for cyc in acycs]
mcyc = []
maxn = 0
# for each cycle involving node of interest
for cyc in acycs:
n = 100
# group the nodes in the cycle by pairs
for u, v in zip(cyc[:-1], cyc[1:]):
# retrieve the respective edge weigth for the current pair
print(u,v, end=',\t')
div = G.get_edge_data(u,v)['weight']
# calculate and update n
r = n/div
print(f"{n}\t/\t{div}\t=\t{r}")
n=r
print('----------------------------------------------------------------------------')
if n>maxn:
maxn=n
mcyc=cyc
This gives us all loops starting at inode='A':
[out]:
E A, 100 / 2 = 50.0
A G, 50.0 / 3 = 16.666666666666668
G D, 16.666666666666668 / 50 = 0.33333333333333337
D B, 0.33333333333333337 / 1 = 0.33333333333333337
B C, 0.33333333333333337 / 2 = 0.16666666666666669
C F, 0.16666666666666669 / 3 = 0.05555555555555556
F E, 0.05555555555555556 / 2 = 0.02777777777777778
----------------------------------------------------------------------------
E A, 100 / 2 = 50.0
A B, 50.0 / 50 = 1.0
B C, 1.0 / 2 = 0.5
C F, 0.5 / 3 = 0.16666666666666666
F E, 0.16666666666666666 / 2 = 0.08333333333333333
----------------------------------------------------------------------------
B A, 100 / 50 = 2.0
A G, 2.0 / 3 = 0.6666666666666666
G D, 0.6666666666666666 / 50 = 0.013333333333333332
D B, 0.013333333333333332 / 1 = 0.013333333333333332
----------------------------------------------------------------------------
B A, 100 / 50 = 2.0
A B, 2.0 / 50 = 0.04
----------------------------------------------------------------------------
And also the cycle that maximizes n:
print(f"The loop {mcyc} in G maximizes n with {maxn}")
[out]:
The loop ['E', 'A', 'B', 'C', 'F', 'E'] in G maximizes n with 0.08333333333333333
I've uploaded this notebook here in case you prefer to clone it and test this approach locally.
Non-Iterative Alternative - Based on nx.dijkstra_path
As per your comment, it seems like what you're after is not to traverse every path in the network, but if possible traverse only the n-maximizing path and calculate nmax.
This is just a variant of Dijkstra Shortest Path algorithm with an updating weight function.
However, nx.Dijkstra_path has problems finding cycles. nx.Dijkstra_path('A','A') yields A even if w(A,A)=math.inf
But one can use a trick:
- remove node
A and introduce Ai and Ao
- replace A in all its in-edges with
Ai
- replace A in all its out-edges with
Ao
- link
Ai and Ao with an edge weight equal to math.inf.
- calculate shortest path from
Ao to Ai
Here's what the graph I provided in my initial answer would look like:
import math
Gp = nx.DiGraph()
Gp.add_edges_from([('Ao', 'B'),('B', 'Ai'), ('C','D'),('G','D')], weight=50)
Gp.add_edges_from([('D','B')], weight=1)
Gp.add_edges_from([('B','C'),('F','E'),('E','Ai')], weight=2)
Gp.add_edges_from([('C','F'),('B','G'),('Ao','G')], weight=3)
# this edge is strictly speaking not needed.
Gp.add_edges_from([('Ai','Ao'),('Ao','Ai')], weight=math.inf)
edge_labels=dict([((u,v,),d['weight'])
for u,v,d in Gp.edges(data=True)])
pos=nx.drawing.layout.circular_layout(Gp,scale=10)
pos['Ai'], pos['B'] = pos['B'], pos['Ai']
nx.draw_networkx_edge_labels(Gp,pos,edge_labels=edge_labels)
nx.draw_networkx_labels(Gp,pos,font_color='white')
nx.draw(Gp,pos, node_size=1500,edge_cmap=plt.cm.Reds)

Using nx.dijkstra_path we have:
nmpath = nx.dijkstra_path(Gp,'Ao','Ai')
nmpath
[out]: ['Ao', 'B', 'C', 'F', 'E', 'Ai']
We can see the weights of that path as follows:
lennmpath=len(nmpath)
datnmpath=[Gp.get_edge_data(u, nmpath[i+1])['weight'] for u,i in zip(nmpath[:-1], range(lnmpath))]
[out]: [50, 2, 3, 2, 2]
And we can calculate nmax trivially:
maxn=100;
for w in datnmpath: maxn/=w
print(maxn)
[out] 0.08333333333333333
I've updated the notebook so you can clone it and test this approach locally.