Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 35 additions & 17 deletions pyHON/BuildNetwork.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
### This file: line-by-line translation from Algorithm 2
### in the paper "Representing higher-order dependencies in networks"
### Code written by Jian Xu, Jan 2017

### Technical questions? Please contact i[at]jianxu[dot]net
### Demo of HON: please visit http://www.HigherOrderNetwork.com
### Latest code: please visit https://github.com/xyjprc/hon

### Call BuildNetwork()
### Input: Higher-order dependency rules
### Output: HON network
### See details in README
'''
This version resolved the count issues after rewiring for freq mode.
e.g. if a->b has been changed as a->b|a, then count[b][*]-=count[b|a][*]
if a|q->b has been changed as a|q->b|a, then count[b][*]-=count[b|a][*]
'''


from collections import defaultdict, Counter
Expand All @@ -23,27 +16,43 @@ def Initialize():

def BuildNetwork(Rules):
VPrint('Building network')
Initialize()
# Initialize()
Graph.clear()
SortedSource = sorted(Rules, key=lambda x: len(x))
ToAdd = []
ToRemove = []
for source in SortedSource:
for target in Rules[source]:
Graph[source][(target,)] = Rules[source][target]
# following operations are destructive to Rules
if len(source) > 1:
Rewire(source, (target,))
Rewire(source, (target,), ToAdd, ToRemove)
for (source, target, weight) in ToAdd:
Graph[source][target] = weight
for (source, target) in ToRemove:
del(Graph[source][target])
RewireTails()
return Graph

def Rewire(source, target):
def Rewire(source, target, ToAdd, ToRemove):
PrevSource = source[:-1]
PrevTarget = (source[-1],)
if not PrevSource in Graph or not source in Graph[PrevSource]:
Graph[PrevSource][source] = Graph[PrevSource][PrevTarget]
del(Graph[PrevSource][PrevTarget])
if (PrevSource, source, Graph[PrevSource][PrevTarget]) not in ToAdd:
ToAdd.append((PrevSource, source, Graph[PrevSource][PrevTarget]))
if (PrevSource, PrevTarget) not in ToRemove:
ToRemove.append((PrevSource, PrevTarget))
# remove the counts for the wired nodes
# e.g. if a->b has been changed as a->b|a, then count[b][*]-=count[b|a][*]
if target in Graph[PrevTarget]:
Graph[PrevTarget][target] -= Graph[source][target]
if Graph[PrevTarget][target] == 0:
del(Graph[PrevTarget][target])

def RewireTails():
ToAdd = []
ToRemove = []
ToReduce = []
for source in Graph:
for target in Graph[source]:
if len(target) == 1:
Expand All @@ -52,13 +61,22 @@ def RewireTails():
if NewTarget in Graph:
ToAdd.append((source, NewTarget, Graph[source][target]))
ToRemove.append((source, target))
ToReduce.append((target, NewTarget))
break
else:
NewTarget = NewTarget[1:]
for (source, target, weight) in ToAdd:
Graph[source][target] = weight
for (source, target) in ToRemove:
del(Graph[source][target])
# reduce the counts for the retailed nodes
# e.g. if a|q->b has been changed as a|q->b|a, then count[b][*]-=count[b|a][*]
for (target, NewTarget) in ToReduce:
for NextStep in Graph[NewTarget]:
if NextStep in Graph[target]:
Graph[target][NextStep] -= Graph[NewTarget][NextStep]
if Graph[target][NextStep] == 0:
del(Graph[target][NextStep])


###########################################
Expand Down