Skip to content

Instantly share code, notes, and snippets.

Created January 29, 2013 16:46
def loop_copy(loop_inp):
""" Will return a copy of a loop list
Used when a change needs to be made."""
loop_op=[]
for c1 in range(len(loop_inp)):
row_vector=[]
for c2 in range(len(loop_inp[c1])):
row_vector.append(loop_inp[c1][c2])
loop_op.append(row_vector)
return loop_op
def check_loop_repeat(lp_iter, lp_list):
""" Will return 1 if the loop already
exists if the loop_list found so far."""
# Make a copy of the entire loop list
# found so far. Just in case.
list_cmp=loop_copy(lp_list)
# As a default, loop is not repeated
# A single instance of repitition will
# set it to 1.
lp_repeat=0
# Go through every loop found
# so far
for c1 in range(len(list_cmp)):
# Make a copy of the loop being checked
iter_cmp=loop_copy(lp_iter)
# Move in the reverse direction of the loop
# This is because elements are deleted
# as they are found.
for c2 in range(len(iter_cmp)-1, -1, -1):
# Check if the element is found or if the
# symmetrical element is found in any of
# the loops found so far.
# Because they are the same.
if ([iter_cmp[c2][0], iter_cmp[c2][1]] in list_cmp[c1]) or \
([iter_cmp[c2][1], iter_cmp[c2][0]] in list_cmp[c1]):
# If so, remove the element
iter_cmp.remove(iter_cmp[c2])
# If all element have been deleted
# it means the loop exists
if not iter_cmp:
lp_repeat=1
return lp_repeat
def loop_addition(br_map, nd_list, lp_list, curr_lp_iter, lp_update, curr_elem, all_loops, main_loops):
""" Take a new element of br_map in any direction.
Check for a parallel branch at that element.
Add that element if not already there in the temporary loop."""
row=curr_elem[0]
col=curr_elem[1]
# Check if there is an element
if br_map[row][col]:
# Check for parallel branches
if len(br_map[row][col])>1:
if (br_map[row][col][0][0] in nd_list) or \
(br_map[row][col][0][-1] in nd_list):
del nd_list[nd_list.index(br_map[row][col][0][-1])]
del nd_list[nd_list.index(br_map[row][col][0][0])]
# Check if the parallel branch exists already
# in lp_list
if not check_loop_repeat([[row, col], [row, col]], lp_list):
lp_list.append([[row, col], [row, col]])
# Update the all_loops counter
all_loops+=len(br_map[row][col])-1
# Temp list to make copies
# of loops found
row_vec=[]
for item in curr_lp_iter:
row_vec.append(item)
# Check if an element has been
# encountered before
# not going back and forth that is
if not (([row, col] in row_vec) or [col, row] in row_vec):
# Add the element found
lp_update.append(row_vec)
lp_update[main_loops].append([row, col])
# Update the main loops counter
main_loops+=1
# If an element has not been found
# or is a duplicate, lp_update
# won't contain it.
return [all_loops, main_loops]
def loop_closing(br_map, lp_list, nd_list, lp_update, c1, lp_count):
""" After a loop has been indentified. That is
the first node and the last node are the same.
It is checked whether the loop passes through
nodes that have not been passed through. If not,
loop is directly added. If it does, another
additional check is is the loop has the same elements
as any other loops already found in lp_list. """
# Default is that all nodes have been "found"
# or passed through. A single exception will
# produce a new loop.
nd_exist="found"
for c5 in range(len(lp_update[c1])):
# Go through every branch in the loop
# Take the first and last node of every branch
st_node=br_map[lp_update[c1][c5][0]][lp_update[c1][c5][1]][0][0]
end_node=br_map[lp_update[c1][c5][0]][lp_update[c1][c5][1]][0][-1]
# Check if either are there in nd_list
# Nodes are deleted from nd_list as they are
# found. So if the node is in nd_list
# it means it has not been passed through
if (st_node in nd_list):
nd_exist="not_found"
nd_idx=nd_list.index(st_node)
del nd_list[nd_idx]
if (end_node in nd_list):
nd_exist="not_found"
nd_idx=nd_list.index(end_node)
del nd_list[nd_idx]
if nd_exist=="not_found":
# Add that loop to loop list
lp_list.append(lp_update[c1])
# Remove the loop from the temp
# variable.
del lp_update[c1]
lp_count+=1
else:
# Check if the loop is new even
# if all nodes have been passed through.
lp_exist="found"
if not check_loop_repeat(lp_update[c1], lp_list):
lp_exist="not_found"
if lp_exist=="not_found":
# Add that loop to loop list
lp_list.append(lp_update[c1])
# Remove the loop from the temp
# variable.
del lp_update[c1]
lp_count+=1
return lp_count
def loop_horiz(br_map, nd_list, lp_list, lp_iter, elem, lp_count):
""" Moves horizontally in a loop find.
Looks for every element in a particular column of br_map.
Each element is added onto the exiting loops. """
# lp_list is the loops found.
# lp_iter is the list of loops as they are being identified.
# Those that are loops will be added to lp_list.
no_nodes=len(br_map)
start_row=elem[0]
start_col=elem[1]
# Temp list to make copies
# of exisiting lists
# if elements exist on that row
lp_update=[]
# Counter for number
# of elements found in the row
c2=0
for c1 in range(len(lp_iter)):
# Set loop row and counter
# to the latest element
# in lp_iter
loop_row=lp_iter[c1][-1][0]
loop_column=lp_iter[c1][-1][1]
# Start from element in next column
# to end of matrix
#for c3 in range(loop_column+1, no_nodes):
for c3 in range(0, no_nodes):
curr_elem=[loop_row, c3]
lp_count,c2=loop_addition(br_map, nd_list, lp_list, \
lp_iter[c1], lp_update, curr_elem, lp_count, c2)
for c1 in range(len(lp_update)-1, -1, -1):
# End condition
# Latest element has ending or starting node
# Same as last element of first branch
last_elem_frst=br_map[start_row][start_col][0][-1]
frst_elem_curr=br_map[lp_update[c1][-1][0]][lp_update[c1][-1][1]][0][0]
last_elem_curr=br_map[lp_update[c1][-1][0]][lp_update[c1][-1][1]][0][-1]
if (frst_elem_curr==last_elem_frst or \
last_elem_curr==last_elem_frst):
lp_count=loop_closing(br_map, lp_list, nd_list, lp_update, c1, lp_count)
# lp_iter will be the same as lp_update
lp_iter=[]
for c1 in range(len(lp_update)):
lp_iter.append(lp_update[c1])
# lp_iter contains ongoing loops
# Closed loops are moved to lp_list
# Broken loops are dropped
#print lp_update, "Check"
#print lp_iter, "End"
return [lp_count, lp_iter]
def loop_vert(br_map, nd_list, lp_list, lp_iter, elem, lp_count):
""" Moves vertically in a loop find.
Looks for every element in a particular column of br_map.
Each element is added onto the exiting loops. """
# lp_list is the loops found.
# lp_iter is the list of loops as they are being identified.
# Those that are loops will be added to lp_list.
no_nodes=len(br_map)
start_row=elem[0]
start_col=elem[1]
# Temp list to make copies
# of exisiting lists
# if elements exist on that column
lp_update=[]
# Counter for number
# of elements found in the column
c2=0
for c1 in range(len(lp_iter)):
# Set loop row and counter
# to the latest element
# in lp_iter
loop_row=lp_iter[c1][-1][0]
loop_column=lp_iter[c1][-1][1]
# Start from element from first row
# to end of column
for c3 in range(0, no_nodes):
curr_elem=[c3, loop_column]
lp_count,c2=loop_addition(br_map, nd_list, lp_list, \
lp_iter[c1], lp_update, curr_elem, lp_count, c2)
for c1 in range(len(lp_update)-1, -1, -1):
# End condition
# Latest element has ending or starting node
# Same as last element of first branch
last_elem_frst=br_map[start_row][start_col][0][-1]
frst_elem_curr=br_map[lp_update[c1][-1][0]][lp_update[c1][-1][1]][0][0]
last_elem_curr=br_map[lp_update[c1][-1][0]][lp_update[c1][-1][1]][0][-1]
if (frst_elem_curr==last_elem_frst or \
last_elem_curr==last_elem_frst):
lp_count=loop_closing(br_map, lp_list, nd_list, lp_update, c1, lp_count)
# lp_iter will be the same as lp_update
lp_iter=[]
for c1 in range(len(lp_update)):
lp_iter.append(lp_update[c1])
# lp_iter contains ongoing loops
# Closed loops are moved to lp_list
# Broken loops are dropped
return [lp_count, lp_iter]
def find_loop(br_map, nd_list, lp_list, lp_iter, elem, lp_count, lp_limit):
"""Find the loops from info on branches and
nodes. The starting point is the first branch in br_map.
The loops found need not be independent loops."""
no_nodes=len(br_map)
# First branch
start_row=elem[0]
start_col=elem[1]
# Move right from that element
# This is the first element
# In a general sense, the direction is horiz
loop_dir="horiz"
# The termination condition is
# that there should not be any element
# in the nd_list. The nodes are deleted
# as a completed loop contains them.
# This is to ensure that all the nodes
# are included in the loops found.
# To ensure that parallel loops between
# a few pair of nodes, do not cause
# loops to be left out, additionally,
# it is checked whether
# Loops < Branches - Nodes + 1
while (nd_list or lp_count<lp_limit):
# Will be executed if we are moving horizontally
if (loop_dir == "horiz"):
lp_count, lp_iter=loop_horiz(br_map, nd_list, lp_list, lp_iter, elem, lp_count)
# Change direction to vertical
loop_dir="vert"
# Will be executed if we are moving vertically
if (loop_dir == "vert"):
lp_count, lp_iter=loop_vert(br_map, nd_list, lp_list, lp_iter, elem, lp_count)
# Change direction to horizontal
loop_dir="horiz"
return lp_count
# Determining the loops
loop_list=[]
loop_count=0
loop_nodes=[]
# Making a copy of node_list
# for finding the loops
for c1 in range(len(node_list)):
loop_nodes.append(node_list[c1])
# Pick a row
for c1 in range(number_of_nodes-1):
# Diagonal elements are null
# So choose the column next to diagonal
for c2 in range(c1+1, number_of_nodes):
#check if it exists
if branch_map[c1][c2]:
# Starting branch found
if len(branch_map[c1][c2])>1:
if not check_loop_repeat([[c1, c2], [c1, c2]], loop_list):
loop_list.append([[c1, c2], [c1, c2]])
# Check for parallel branches again.
if (branch_map[c1][c2][0][0] in loop_nodes):
del loop_nodes[loop_nodes.index(branch_map[c1][c2][0][0])]
if (branch_map[c1][c2][0][-1] in loop_nodes):
del loop_nodes[loop_nodes.index(branch_map[c1][c2][0][-1])]
# Check is there are parallel branches between the nodes
loop_list.append([[c1, c2], [c1, c2]])
loop_count+=len(branch_map[c1][c2])-1
# Initialize the loop iterator list with the first element.
loop_iter=[]
loop_iter.append([[c1, c2]])
loop_count=find_loop(branch_map, loop_nodes, loop_list, loop_iter, \
[c1, c2], loop_count, number_of_branches-number_of_nodes+1)
# Remove any repitions in loop_list
for c1 in range(len(loop_list)-1):
for c2 in range(len(loop_list)-1, c1, -1):
if loop_list[c1]==loop_list[c2]:
del loop_list[c2]
# The actual elements from the branches
# to be entered into the loops
loop_branches=[]
# Go through every element in loop_list
for c1 in range(len(loop_list)):
# If the loop has two elements
# it means it is a group of
# parallel branches between nodes
if len(loop_list[c1])==2:
curr_br=loop_list[c1][0]
# Get every permutation of branch pairs possible
for c2 in range(len(branch_map[curr_br[0]][curr_br[1]])-1):
for c3 in range(c2+1, len(branch_map[curr_br[0]][curr_br[1]])):
loop_updt=[]
# Iterate in the forward direction
for c4 in range(len(branch_map[curr_br[0]][curr_br[1]][c2])):
loop_updt.append(branch_map[curr_br[0]][curr_br[1]][c2][c4])
# Iterate in the reverse direction
for c4 in range(len(branch_map[curr_br[0]][curr_br[1]][c3])-2, -1, -1):
loop_updt.append(branch_map[curr_br[0]][curr_br[1]][c3][c4])
loop_branches.append(loop_updt)
else:
loop_updt=[]
# Go through all elements in the loop
for c2 in range(0, len(loop_list[c1])-1):
# Mark two elements in the loop
# The current and the next element
curr_br=loop_list[c1][c2]
curr_br_beg=branch_map[curr_br[0]][curr_br[1]][0][0]
curr_br_end=branch_map[curr_br[0]][curr_br[1]][0][-1]
next_br=loop_list[c1][c2+1]
next_br_beg=branch_map[next_br[0]][next_br[1]][0][0]
next_br_end=branch_map[next_br[0]][next_br[1]][0][-1]
curr_dir="forward"
# Start stringing the branches together
# So if it is the first branch
# Check if the beginning element of the branch
# is the same as the beginning or ending element
# if the next branch
# In that case, the first/current branch
# is to be reversed
if not loop_updt:
if curr_br_beg==next_br_beg or curr_br_beg==next_br_end:
curr_dir="reverse"
# If the loop update is in progress
# check how the current element is linked to
# the last element on the updated loop
else:
if curr_br_end==loop_updt[-1]:
curr_dir="reverse"
# Depending on the direction in which
# an element is to be added to
# the loop.
if curr_dir=="forward":
for c3 in range(len(branch_map[curr_br[0]][curr_br[1]][0])):
loop_updt.append(branch_map[curr_br[0]][curr_br[1]][0][c3])
else:
for c3 in range(len(branch_map[curr_br[0]][curr_br[1]][0])-1, -1, -1):
loop_updt.append(branch_map[curr_br[0]][curr_br[1]][0][c3])
# Repeat for the last element
next_dir="forward"
if next_br_end==loop_updt[-1]:
next_dir="reverse"
if next_dir=="forward":
for c3 in range(len(branch_map[next_br[0]][next_br[1]][0])):
loop_updt.append(branch_map[next_br[0]][next_br[1]][0][c3])
else:
for c3 in range(len(branch_map[next_br[0]][next_br[1]][0])-1, -1, -1):
loop_updt.append(branch_map[next_br[0]][next_br[1]][0][c3])
# Remove any repitions in the elements
# in consecutive elements only
for c3 in range(len(loop_updt)-1, 0, -1):
if loop_updt[c3]==loop_updt[c3-1]:
del loop_updt[c3]
loop_branches.append(loop_updt)
#loop_count=len(loop_branches)
print "Number of nodes",
print number_of_nodes
print "Number of branches",
print number_of_branches
print "Number of loops",
print loop_count
print "*"*50
excel_col="A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"
excel_dict={}
excel_col_list=excel_col.split(" ")
for c1 in range(26):
excel_dict[c1]=excel_col_list[c1]
for item in loop_branches:
for c1 in range(len(item)):
print str(item[c1][0]+1) + excel_dict[item[c1][1]],
print
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment