Reputation: 3
I need an advise how to calculate all possible paths from start node to end node with a program (Programatically) , I can use either C#, Python, or Matlab, but I dont know which one is easy and faster for coding and less effort , also I do not know from where to start, I need also to draw the edges between nodes automatically and calculate more formulas later. I have the following data
Node Date Data
A 2020-01-01 2.09
B 2020-01-05 0.89
C 2020-01-08 3.17
D 2020-01-08 1.15
E 2020-01-15 3.65
I want to do the following:
Create path from any node to another (one way and from lower date to higher date only) and must pass through all nodes between dates in the path, for example:
1.1 from (A) to (E) should extract the following paths:
since C and D are on the same date, so we have 2 different paths.
List item
Upvotes: 0
Views: 273
Reputation: 17166
Using Python groupby and product from Python itertools module
Code
from itertools import groupby, product
def all_paths(s):
# Convert string to list of node triplets
nodes = [n.strip().split() for n in s.split('\n')]
# Skip header and sort by time
# (since time is padded, no need to convert to datetime object to sort)
nodes = sorted(nodes[1:], key=lambda n: n[1]) # sorting by time which is second item in list (n[1])
# Group nodes by time (i.e. list of list, with nodes with same time in same sublist)
# Just keeping the node field of each item in sublist (i.e. node[0] is Node field)
labels = [[node[0] for node in v] for k, v in groupby(nodes, lambda n:n[1])]
# Path is the product of the labels (list of lists)
return list(product(*labels))
Usage
Example 1: Data in string
data = '''Node Date Data
A 2020-01-01 2.09
B 2020-01-05 0.89
C 2020-01-08 3.17
D 2020-01-08 1.15
E 2020-01-15 3.65'''
print(all_paths(data))
Example 2: Data in file data.txt
with open('data.txt', 'r') as fin:
print(all_paths(fin.read()))
Output (for both cases):
[('A', 'B', 'C', 'E'), ('A', 'B', 'D', 'E')]
Upvotes: 1
Reputation: 268
This will generate a list of chains of nodes for every path. It uses python lists and a dictionary to hash - so it will be very slow if you're working with large data sets. If this is the case, look into the pandas library (groupby). The same logic will work, but you will definitely save time in the nodes_by_date function. There may also be other tools in that library to generate the paths you need.
nodes = [('E',15,3.65), ('A',1,2.09), ('B',5,.89), ('C',8,3.17), ('D',8,1.15)]
#nodes = [('E',15,3.65), ('A',1,2.09), ('B',5,.89), ('C',8,3.17), ('D',8,1.15), ('F', 16, 100), ('G', 16, 200), ('H', 17, 1000)]
def all_paths(nodes):
nbd = nodes_by_date(nodes)
return get_chains(nbd, 0)
def nodes_by_date(nodes):
# sort by date (not sure what format your data is in, but might be easier to convert to a datenum/utc time)
nodes = sorted(nodes, key=lambda x: x[1])
# build a list of lists, each containing all of the nodes with a certain date
# if your data is larger, look into the pandas library's groupby operation
dates = {}
for n in nodes:
d = dates.get(n[1], [])
d.append(n)
dates[n[1]]=d
return list(dates.values())
def get_chains(nbd, i):
if i == len(nbd):
return []
# depth-first recursion so tails are only generated once
tails = get_chains(nbd, i+1)
chains = []
for n in nbd[i]:
if len(tails):
for t in tails:
newchain = [n]
# only performant for smaller data
newchain.extend(t)
chains.append(newchain)
# end of recursion
else:
chains.append([n])
return chains
Upvotes: 0