Beispiel #1
0
def create_pes():
    global mvp
    pattern = em.EmbPattern()

    vertices = [ world_space_to_screen_space(vert) for vert in scene.vertices ]

    def to_i4(l):
        return l[0] | l[1] << 8 | l[2] << 16 | l[3] << 24

    im = list(face_fbo.read(components=1, dtype='i4'))
    visible_faces = Counter([ to_i4(im[k:k+4]) for k in range(0,len(im),4) ])
    del visible_faces[0xFFFFFFFF]
    # TODO count pixels of visible faces and prune any with fewer than some number
    print(visible_faces)

    # faces = visible_faces
    threshold = 10
    faces = [ f for f,cnt in visible_faces.items() if cnt >= threshold ]

    G = nx.Graph()

    # go through all things in scene indices
    for idx in faces:
        face = scene.mesh_list[0].faces[idx]

        verts = [ tuple(vertices[p]) for p in face ]
        edges = list(zip(verts, islice(cycle(verts), 1, None)))

        G.add_edges_from(edges)

    stitches = []
    for C in [ G.subgraph(c) for c in nx.connected_components(G) ]:
        for (p0, p1) in nx.eulerian_circuit(nx.eulerize(C)):
            # needs to be at least 2
            for t in np.linspace(0, 1, 2):
                stitches.append(((1-t)*p0[0] + t*p1[0], (1-t)*p0[1] + t*p1[1]))

    stitches = [ k for k,g in groupby(stitches) ]

    for (x, y) in stitches:
        pattern.add_stitch_absolute(em.STITCH, x, y)

    # create dst format (pes doesn't work?)
    print("Saving file...")
    em.write_dst(pattern, 'file.dst')
    em.write_pes(pattern, 'file.pes')
    em.write_txt(pattern, 'file.txt')

    print("Done.")
Beispiel #2
0
    ''' TEST ON A SIMPLE TOY '''
    print("\nHierholzer eulerian path test on toy example")
    toy = nx.Graph()
    toy.add_nodes_from(['A', 'B', 'C', 'D', 'E'])  # graph with 2 triangles
    toy.add_edges_from([('A', 'B'), ('A', 'C'), ('B', 'C'), ('C', 'D'), ('C', 'E'), ('D', 'E')])
    print(nx.is_eulerian(toy), nx.has_eulerian_path(toy))
    print(hierholzer(toy))
    ''' Eulerian Path test i made the test on R and on a toy example because eulerian path on graph of provinces 
    dosen't exist because the graph of provinces in not strongly connected'''
    time_eulerian = []
    time_eulerian_nx = []
    num_node = [3, 9, 19, 29, 39, 49]
    for test in range(len(num_node)):
        toy = nx.complete_graph(num_node[test])
        toy = nx.eulerize(toy)
        # print(nx.is_eulerian(toy))
        # print(nx.has_eulerian_path(toy))
        # print(nx.has_eulerian_path(R))
        # print(nx.has_eulerian_path(P))
        '''EULERIAN PATH ON A TOY EXAMPLE USING NETWORKX'''
        start = time.time()
        path = nx.eulerian_path(toy)
        # print(list(path))
        end = time.time()
        time_eulerian_nx.append(end - start)
        '''EULERIAN PATH ON A TOY EXAMPLE USING IMPLEMENTED FUNCTIONS'''
        start = time.time()
        path = hierholzer(toy)
        # print(path)
        end = time.time()
Beispiel #3
0
print("h) R =", vertex_cover.min_weighted_vertex_cover(G))
print()

# i) Minimum edge cover
print("i) F =", covering.min_edge_cover(G))
print()

# j) Shortest closed path (circuit) that visits every vertex
print("j) W =", end=" ")
for i in range(len(tournament.hamiltonian_path(D))):
    print(tournament.hamiltonian_path(D)[i], "-", end=" ")
print(tournament.hamiltonian_path(D)[0])
print()

# k) Shortest closed path (circuit) that visits every edge
H = nx.eulerize(G)
c = list(n for (n, d) in nx.eulerian_circuit(H))
print("k) U =", end=" ")
for i in range(len(c)):
    print(c[i], "-", end=" ")
print(c[0])
print()

# m) 2-edge-connected components
print("m) ", list(edge_kcomponents.bridge_components(G)))
print()

# o) MST
MST = nx.Graph(mst.minimum_spanning_tree(G))
print("o) MST = ", MST.nodes)
print("Weight =", sum(c for (a, b, c) in (MST.edges.data('weight'))))
Beispiel #4
0
 def test_on_complete_graph(self):
     G = nx.complete_graph(4)
     assert_true(nx.is_eulerian(nx.eulerize(G)))
     assert_true(nx.is_eulerian(nx.eulerize(nx.MultiGraph(G))))
Beispiel #5
0
 def test_on_eulerian_multigraph(self):
     G = nx.MultiGraph(nx.cycle_graph(3))
     G.add_edge(0, 1)
     H = nx.eulerize(G)
     assert_true(nx.is_eulerian(H))
Beispiel #6
0
    def _order_edges_in_block(self, block_data, drop_augmented):
        """Produce an edge sequence for all edges in the component.

        Parameters
        ----------
        block_data : pandas.DataFrame
            A DataFrame representing all the edges within a single block.

        drop_augmented : bool
            Whether or not to keep any edges that needed to be added to the source edges in order to navigate the
            network.

        Returns
        -------
        edges : pandas.DataFrame
            The same edges that were input with the edge order and route type as new columns.
        """

        logger.debug("order_edges_by_block started")

        logger.debug("Received edge data of shape %s", block_data.shape)
        # Sort the DataFrame to load right hand arcs into NetworkX first.
        # Note that Eulerian paths work in reverse order.
        block_data = block_data.sort_values(self.leftrightflag_field,
                                            ascending=False)
        block_g = nx.from_pandas_edgelist(block_data,
                                          source=self.source_field,
                                          target=self.target_field,
                                          edge_attr=True,
                                          create_using=self.graph_type)

        logger.debug("Block contains %s edges and %s nodes",
                     block_g.number_of_edges(), block_g.number_of_nodes())

        # if the graph is empty it means there is a problem with the source data
        # an error is logged, but other blocks are still processed
        if nx.is_empty(block_g):
            logger.error("Block contains no edges and cannot be sequenced")
            return

        # Scale nodes that are mid-segment by looking for duplicated ngd_str_uid values
        logger.debug(
            "Looking for nodes that fall in the middle of a road segment")
        block_data['same_ngd_str_uid'] = block_data.duplicated(
            subset=[self.struid_field], keep=False)
        mid_arc_start_nodes = set(
            block_data.loc[block_data['same_ngd_str_uid'] == True,
                           self.source_field])
        mid_arc_end_nodes = set(
            block_data.loc[block_data['same_ngd_str_uid'] == True,
                           self.target_field])
        mid_arc_nodes = mid_arc_start_nodes.intersection(mid_arc_end_nodes)
        if mid_arc_nodes:
            logger.debug("Found mid-segment nodes: %s", mid_arc_nodes)
            self._apply_node_scaling_factor(mid_arc_nodes, factor=-0.5)

        # initialize the edge sequence counter
        edge_sequence = 0

        # record what type of path was used to determine the circuit
        path_indicator_name = self.path_indicator
        path_indicator_edges = {}

        # blocks don't necessarily form fully connected graphs, so cycle through the components
        logger.debug("Block contains %s connected components",
                     nx.number_weakly_connected_components(block_g))
        for block_comp in sorted(nx.weakly_connected_components(block_g),
                                 key=len,
                                 reverse=True):
            logger.debug(
                "Creating subgraph from connected component with %s nodes",
                len(block_comp))
            block_g_comp = block_g.subgraph(block_comp)

            # determine the preferred start node for this block component
            preferred_sp = self._get_preferred_start_node(block_g_comp.nodes)
            logger.debug("Preferred start node for this block: %s",
                         preferred_sp)

            logger.debug("Component contains %s edges and %s nodes",
                         block_g_comp.number_of_edges(), len(block_g_comp))

            # Need to pick an approach to processing this component depending on what type of circuit it forms.
            # Ideally things are a Eulerian circuit that can be walked and return to start, but not all blocks form
            # these nice circuits. If no good circuit can be found, then sequence numbers are just applied but may
            # not form a logical order.

            # Track the sequence value in case the enumeration method needs to be reset. This gets used when using
            # the preferred start point fails, and also controls if the start node for this component is marked as a
            # point we want to cluster on.
            seq_val_at_start = edge_sequence

            # the preferred option is a Eulerian circuit, so try that first
            # logger.debug("Available edges: %s", block_g_comp.edges)
            if nx.is_eulerian(block_g_comp):
                logger.debug("Block component is eulerian.")
                # record all these edges as being eulerian
                indicator = dict(
                    zip(block_g_comp.edges, ['circuit'] * block_g_comp.size()))
                path_indicator_edges.update(indicator)

                # enumerate the edges and order them directly
                logger.debug("Creating Eulerian circuit from node %s",
                             preferred_sp)
                for u, v, k in nx.eulerian_circuit(block_g_comp,
                                                   source=preferred_sp,
                                                   keys=True):
                    edge_sequence += 1
                    block_g.edges[u, v, k][self.eo_name] = edge_sequence
                    # logger.debug("Sequence applied: (%s, %s, %s) = %s", u, v, k, edge_sequence)

            # next best option is a path that stops at a different location from the start point
            elif nx.has_eulerian_path(block_g_comp):
                logger.debug("Block component forms Eulerian path")

                # record all these edges as being a eulerian path
                indicator = dict(
                    zip(block_g_comp.edges, ['path'] * block_g_comp.size()))
                path_indicator_edges.update(indicator)

                try:
                    logger.debug(
                        "Trying to create path from preferred start node %s",
                        preferred_sp)
                    for u, v, k in nx.eulerian_path(block_g_comp,
                                                    source=preferred_sp,
                                                    keys=True):
                        edge_sequence += 1

                        # check if the start point is actually in the first edge
                        if edge_sequence == 1 and not (preferred_sp == u
                                                       or preferred_sp == v):
                            logger.debug(
                                "Preferred start point not present on starting edge, throwing KeyError."
                            )
                            raise KeyError("Invalid starting edge")

                        # Sometimes the preferred start point means walking over the same edge twice, which will leave
                        # a data gap (the previous edge order value will be overwritten). If this happens, throw a
                        # KeyError
                        if block_g.edges[u, v, k].get(self.eo_name):
                            logger.debug("Edge already sequenced.")
                            raise KeyError(
                                "Preferred start point results in backtracking."
                            )

                        block_g.edges[u, v, k][self.eo_name] = edge_sequence
                        # logger.debug("Sequence applied: (%s, %s, %s) = %s", u, v, k, edge_sequence)

                        if edge_sequence < block_g_comp.number_of_edges():
                            logger.debug("It looks like some edges got missed")
                            raise KeyError("Missing edges on path")

                    logger.debug(
                        "Path was created from desired start point %s",
                        preferred_sp)
                except KeyError:
                    # preferred start point failed; let networkx pick and start over
                    logger.debug(
                        "Preferred start node did not create a path. Trying a different one."
                    )

                    # reset the path listing since a new point will be picked
                    logger.debug("Reset edge_sequence value to %s",
                                 seq_val_at_start)
                    edge_sequence = seq_val_at_start

                    for u, v, k in nx.eulerian_path(block_g_comp, keys=True):
                        edge_sequence += 1
                        block_g.edges[u, v, k][self.eo_name] = edge_sequence
                        # logger.debug("Sequence applied: (%s, %s, %s) = %s", u, v, k, edge_sequence)

            # No good path exists, which means someone will have to backtrack
            else:
                logger.debug(
                    "Non-eulerian block is not easily traversable. Eulerizing it."
                )

                # Record all these edges as being augmented.
                indicator = dict(
                    zip(block_g_comp.edges,
                        ['augmented'] * block_g_comp.size()))
                path_indicator_edges.update(indicator)

                # Send this data to the anomaly folder so that it can be investigated later. It could have addressable
                # issues that operations can correct for the next run.
                logger.debug("Writing anomaly set for this block")
                bf_uid_set = list(
                    nx.get_edge_attributes(
                        block_g_comp, self.edge_uid_field).values()).pop()
                anomaly_file_name = f"anomaly_block_component.{bf_uid_set}.yaml"
                nx.write_yaml(block_g_comp, (self.anomaly_folder /
                                             anomaly_file_name).as_posix())

                # You cannot eulerize a directed graph, so create an undirected one
                logger.debug("Creating MultiGraph from directed graph.")
                temp_graph = nx.MultiGraph()
                for u, v, data in block_g_comp.edges(data=True):
                    key = temp_graph.add_edge(u, v, **data)
                    # logger.debug("Adding edge (%s, %s, %s) to temporary graph.", u, v, key)
                logger.debug("Created temporary MultiGraph with %s edges",
                             temp_graph.number_of_edges())

                # Convert the temporary graph to a proper Euler circuit so that it can be traversed.
                logger.debug("Eulerizing MultiGraph")
                euler_block = nx.eulerize(temp_graph)
                logger.debug("Added %s edges to the block",
                             (euler_block.size() - temp_graph.size()))
                logger.debug("Number of vertices in eulerized graph: %s",
                             euler_block.number_of_nodes())

                # As we try to traverse the undirected graph, we need to keep track of places already visited to make
                # sure arcs are not skipped.
                visited_edges = Counter()

                # augmented edges will throw the node weights off, so don't bother trying the preferred start node
                logger.debug("Generating path through augmented block")
                for u, v, k in nx.eulerian_circuit(euler_block,
                                                   preferred_sp,
                                                   keys=True):
                    # augmented edges have no attributes, so look for one and skip the edge if nothing is returned
                    if drop_augmented and not euler_block.edges[u, v, k].get(
                            self.edge_uid_field):
                        logger.debug("Ignoring augmented edge (%s, %s, %s)", u,
                                     v, k)
                        continue

                    # Increment the sequence value for each edge we see.
                    edge_sequence += 1

                    # Since we formed an undirected MultiGraph we need to check the orientation of the nodes on the
                    # edge to assign the sequence back to the directed graph.
                    start_node = u
                    end_node = v
                    available_edge_count = block_g.number_of_edges(
                        start_node, end_node)
                    # If no edges exist, invert the nodes and check again.
                    # This also checks to see if we've already encountered all the edges between these nodes, indicating
                    # we need to process the inverse of the start and end values
                    if available_edge_count == 0 or (
                        ((start_node, end_node) in visited_edges) and
                        (available_edge_count
                         == visited_edges[(start_node, end_node)])):
                        logger.debug(
                            "Nothing to process between (%s, %s), inverting nodes.",
                            start_node, end_node)
                        start_node = v
                        end_node = u
                        available_edge_count = block_g.number_of_edges(
                            start_node, end_node)
                    logger.debug(
                        "Number of edges available between (%s, %s): %s",
                        start_node, end_node, available_edge_count)

                    # Apply the edge_sequence to the first edge that hasn't received one yet
                    for ki in range(available_edge_count):
                        if not block_g.edges[start_node, end_node, ki].get(
                                self.eo_name):
                            logger.debug(
                                "Edge sequence applied: (%s, %s, %s) = %s",
                                start_node, end_node, ki, edge_sequence)
                            block_g.edges[start_node, end_node,
                                          ki][self.eo_name] = edge_sequence
                            visited_edges[(start_node, end_node)] += 1
                            break

            # At this point every edge should be accounted for, but in case something somehow slips through the cracks
            # it needs to be given a sequence label. The label almost certainly won't make much sense in terms of a
            # logical ordering, but this is just trying ot make sure it is counted.
            logger.debug("Looking for any missed edges in block component")
            for u, v, k in block_g_comp.edges:
                if not block_g.edges[u, v, k].get(self.eo_name):
                    edge_sequence += 1
                    block_g.edges[u, v, k][self.eo_name] = edge_sequence
                    logger.warning(
                        "Applied out of order sequence to component edge (%s, %s, %s): %s",
                        u, v, k, edge_sequence)

            # just log the last sequence value to make tracing easier
            logger.debug("Final edge sequence value for component: %s",
                         edge_sequence)

            # apply a sequence value to all the edges that were discovered
            logger.debug("Edge order results: %s",
                         nx.get_edge_attributes(block_g_comp, self.eo_name))

            # To help cluster the start nodes, mark which node was used as the start point in this block
            if seq_val_at_start == 1:
                self._mark_chosen_start_node(block_g_comp, preferred_sp)

            logger.debug("Finished processing component")

        # record that block processing is finished
        logger.debug("Block processing complete")

        # nx.set_edge_attributes(block_g, block_sequence_labels, self.eo_name)
        nx.set_edge_attributes(block_g, path_indicator_edges,
                               path_indicator_name)

        # check to see if the counts line up
        if not block_g.number_of_edges() == edge_sequence:
            logger.debug(
                "Edge sequence (%s) and edge count (%s) do not match in block",
                edge_sequence, block_g.number_of_edges())

        # help start point clustering by apply a scaling factor to all nodes that were touched
        logger.debug(
            "Applying scaling factor to nodes in this block, except start point"
        )
        nodes_in_block = set(block_g.nodes())
        nodes_in_block.remove(
            preferred_sp)  # don't scale the preferred start point
        self._apply_node_scaling_factor(nodes_in_block)
        logger.debug("Final node data for block: %s",
                     self.graph.subgraph(block_g.nodes).nodes(data=True))

        logger.debug("Returning pandas DataFrame from block graph.")
        return nx.to_pandas_edgelist(block_g,
                                     source=self.source_field,
                                     target=self.target_field)
Beispiel #7
0
 def test_on_eulerian_multigraph(self):
     G = nx.MultiGraph(nx.cycle_graph(3))
     G.add_edge(0, 1)
     H = nx.eulerize(G)
     assert nx.is_eulerian(H)
Beispiel #8
0
 def test_on_empty_graph(self):
     with pytest.raises(nx.NetworkXError):
         nx.eulerize(nx.empty_graph(3))
Beispiel #9
0
 def test_null_graph(self):
     nx.eulerize(nx.Graph())
Beispiel #10
0
 def test_disconnected(self):
     G = nx.from_edgelist([(0, 1), (2, 3)])
     nx.eulerize(G)
n = ps[0]
m = ps[1]
graph = nx.Graph()
for i in range(0, m):
    s = f.readline()
    ps = [float(i) for i in s.split()]
    v = int(ps[0])
    u = int(ps[1])
    graph.add_edge(v, u, weight = 1)
f.close()
f = open("outputPy.txt", "w")
f.write("maximum stable set = " + str(approximation.independent_set.maximum_independent_set(graph)) + '\n')
f.write("maximum matching = " + str(nx.max_weight_matching(graph)) + '\n')
f.write("minimum vertex cover = " + str(approximation.vertex_cover.min_weighted_vertex_cover(graph)) + '\n')
f.write("minimum edge cover = " + str(nx.min_edge_cover(graph)))
f.write("minimum path that visits every edge: " + str(list(nx.eulerian_circuit(nx.eulerize(graph)))))
dists = dict(nx.all_pairs_shortest_path_length(graph))
paths = dict(nx.all_pairs_shortest_path(graph))
distsArr = []
listsCnt = 0
for i in range(1, n + 1):
    if i == 9 or i == 27 or i == 19 or i == 46 or i == 18:
        continue
    distsArr.append([])
    listsCnt += 1
    for j in range(1, n + 1):
        if j == 9 or j == 27 or j == 19 or j == 46 or j == 18:
            continue
        distsArr[listsCnt - 1].append(dists[i][j])
vertexes = []
for i in range(1, n + 1):
Beispiel #12
0
                       pos,
                       edgelist=esmall,
                       width=2,
                       alpha=0.5,
                       edge_color='b',
                       style='dashed')

# labels
nx.draw_networkx_labels(G,
                        pos,
                        font_size=11,
                        font_family='sans-serif',
                        font_color='blue')
nx.draw_networkx_edge_labels(G, pos=nx.spectral_layout(G), font_size=5)

nx.eulerize(G)

plt.axis('off')
plt.savefig("weighted_graph.png")  # save as png
plt.tight_layout(True)
plt.suptitle('Eulerized Graph, Distance Model (miles)')
plt.show()  # display

print(
    startGreen +
    '-------------                           Algorithmic Path Experiments post-Eulerian Graph'
    + '                      -------------' + endColor, '\n')

print(
    startBlue +
    '\nShortest path from Pensacola to Phoenix, Eulerized Graph:\n' + endColor,
Beispiel #13
0
fin_country = open("europe.txt")
fin_edges = open("distances.txt")
country = []  # список стран
edges = []  # список рёбер
G = nx.Graph()  # граф
matrix = [[0] * V for i in range(V)]
for i in range(V):
    pars_one = fin_country.readline().split('.')
    if i != V - 1:
        num, name = pars_one[0], pars_one[1][:-1]
    else:
        num, name = pars_one[0], pars_one[1]
    country.append(name)

for i in range(E):
    pars_two = fin_edges.readline().split()
    a, b = int(pars_two[0]), int(pars_two[1])
    matrix[a][b] = matrix[b][a] = 1
    edges.append([a, b])

# создадим граф
for i in range(E):
    a, b = edges[i]
    G.add_edge(country[a], country[b])

# Построим кратчайший замкнутый путь, с помощью функции либы networkx
a = list(nx.eulerian_circuit(nx.eulerize(G)))
for i in a:
    v1, v2 = i
    print('(', v1, '-->', v2, end=') ')
Beispiel #14
0
 def test_disconnected(self):
     with pytest.raises(nx.NetworkXError):
         G = nx.from_edgelist([(0, 1), (2, 3)])
         nx.eulerize(G)
Beispiel #15
0
 def test_null_multigraph(self):
     nx.eulerize(nx.MultiGraph())
Beispiel #16
0
 def test_null_multigraph(self):
     with pytest.raises(nx.NetworkXPointlessConcept):
         nx.eulerize(nx.MultiGraph())
Beispiel #17
0
 def test_on_empty_graph(self):
     nx.eulerize(nx.empty_graph(3))
Beispiel #18
0
 def test_on_eulerian(self):
     G = nx.cycle_graph(3)
     H = nx.eulerize(G)
     assert nx.is_isomorphic(G, H)
Beispiel #19
0
 def test_on_eulerian(self):
     G = nx.cycle_graph(3)
     H = nx.eulerize(G)
     assert_true(nx.is_isomorphic(G, H))
Beispiel #20
0
 def test_on_complete_graph(self):
     G = nx.complete_graph(4)
     assert nx.is_eulerian(nx.eulerize(G))
     assert nx.is_eulerian(nx.eulerize(nx.MultiGraph(G)))
Beispiel #21
0
G.add_edge('B', 'G', weight=35)
G.add_edge('C', 'D', weight=70)
G.add_edge('C', 'F', weight=28)
G.add_edge('D', 'E', weight=80)
G.add_edge('E', 'F', weight=62)
G.add_edge('F', 'G', weight=40)

posicoes = {
    'A': (0, 3),
    'B': (3, 2),
    'C': (6, 1),
    'D': (10, 0),
    'E': (9, 5),
    'F': (7, 3),
    'G': (2, 5)
}

# rotulos = nx.get_edge_attributes(G, 'weight')
nx.draw(G, posicoes, with_labels=True)
# nx.draw_networkx_edge_labels(G, posicoes, edge_labels=rotulos)

print("É Euleriano?", nx.is_eulerian(G))
print("Arestas:", G.edges(data=True))
print("# de arestas:", G.number_of_edges())
print("Soma total dos pesos:", G.size(weight='weight'))

G_eulerizado = nx.eulerize(G)
print("\nÉ Euleriano?", nx.is_eulerian(G_eulerizado))
print("Arestas:", G_eulerizado.edges(data=True))
print("# de arestas:", G_eulerizado.number_of_edges())
print("Soma total dos pesos:", G_eulerizado.size(weight='weight'))