简体   繁体   中英

Calculating number of edges between tuples in Python

Trying to calculate the number of edges between the tuples in case if I have tuple a and b

For example, if a = ((0,1),(0,2),(0,3)) and b = (((0),(1,2,3)), ((0,1),(2,3)), ((0,1,2),(3)))

Desirable output is [3,2,1] because a - representing all edges that we have and b - all the possible cuts of graph that we have.

Came to the solution that calculates the overall amount of such edges (in our example - 6):

def cnt_edges(a,b):
   edge_cnt = 0
   
   for i in range(len(a)):
       node1 = a[i][0]
       node2 = a[i][1]
       
       for j in range(len(b)):
           inner_node1 = b[j][0]
           inner_node2 = b[j][1]
           
           if (node1 in inner_node1 and node2 in inner_node2) or (node1 in inner_node2 and node2 in inner_node1):
               edge_cnt += 1
   return edge_cnt

a = ((0, 1),(0, 2), (0,3))
b = (((0),(1,2,3)), ((0,1),(2,3)), ((0,1,2),(3)))

cnt_edges(a,b)

How can I calucalate it for each particular tuple in b?

You are describing a graph, that you want to partition in different ways, then count how many edges there is between partitions.

So I wrote a compute_partitions function, which given some edges, will give you the different way to partition them according to your rules. Then calling a method to count the "crossings" between the two partitions.

from typing import List, Tuple


Edge = Tuple[int, int]
Edges = List[Edge]

edges: Edges = [
    (0, 1),
    (0, 2),
    (0, 3),
]

Nodes = List[int]


def compute_partitions(edges: Edges) -> List[Tuple[Nodes, Nodes]]:
    # we want to list all the nodes
    all_unique_nodes = set(node for edge in edges for node in edge)
    # then sort them in ascending order
    sorted_nodes = sorted(all_unique_nodes)
    # and return a sliding partition
    for left_count in range(1, len(sorted_nodes)):  # from 1 to len()-1 inclusive
        left_nodes = sorted_nodes[0:left_count]  # include up to left_count exclusive
        right_nodes = sorted_nodes[left_count:]  # the rest
        yield left_nodes, right_nodes  # could be appended into a list otherwise


def count_edges_between(left_nodes: Nodes, right_nodes: Nodes, edges: Edges) -> int:
    crossings = 0
    for node_a, node_b in edges:
        if node_a in left_nodes:
            if node_b in left_nodes:
                pass
            elif node_b in right_nodes:
                crossings += 1
            else:
                raise ValueError("node not in edges")
        elif node_a in right_nodes:
            if node_b in left_nodes:
                crossings += 1
            elif node_b in right_nodes:
                pass
            else:
                raise ValueError("node not in edges")
        else:
            raise ValueError("node not in edges")
    return crossings

print(list(compute_partitions(edges)))

for nodes_left, nodes_right in compute_partitions(edges):
    print(count_edges_between(nodes_left, nodes_right, edges), nodes_left, nodes_right)
[([0], [1, 2, 3]), ([0, 1], [2, 3]), ([0, 1, 2], [3])]
3 [0] [1, 2, 3]
2 [0, 1] [2, 3]
1 [0, 1, 2] [3]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM