示例#1
0
    def build_path(self):
        if self.G is None:
            self.build_graph()

        self.path, _ = cpp(self.G)
        self.path = [(e1, e2) for e1, e2, _, _ in self.path]
        return self.path
示例#2
0
def eulerCicle(graph):
    edgelist = nx.to_pandas_edgelist(graph, source='_node1', target='_node2') 
    edgelist_file = create_mock_csv_from_dataframe(edgelist)
    circuit_cpp_req, _ = cpp(edgelist_file)
    print('Print the CPP solution:')
    
    # solve chinese postman problem on graph
    # result circuit_cpp_req is in the form ('6.0', '2.0', 0, {'distance': 1.05144, 'id': 6, 'augmented': True})
    #                                   node1_|       |_node2 index 
    # keep only the nodes
    circuit_edges = []
    for e in circuit_cpp_req:
        circuit_edges.append((int(float(e[0])), int(float(e[1]))))

    return circuit_edges
示例#3
0
def postman(osm_data):
    Settings = IngestSettings(
        max_distance=Distance(km=50),
        max_segments=300,
        max_concurrent=40,
        quality_settings=DefaultQualitySettings,
        location_filter=None,
    )
    loader = OSMIngestor(Settings)
    loader.load_osm(osm_data, extra_links=[(885729040, 827103027)])
    # s = datetime.now()
    # data = write_gpickle(loader.global_graph, 'test.pickle') #nx_yaml.write_yaml(loader.global_graph, 'test.yaml')
    # e = datetime.now()
    # print(e-s)

    # s = datetime.now()
    # graph = read_gpickle('test.pickle')
    # e = datetime.now()
    # print(e-s)
    # import pdb; pdb.set_trace()
    for i, network in enumerate(loader.trail_networks()):
        print(network.name, network.total_length().mi)
        print(network.trail_names())
        gmap = gmplot.GoogleMapPlotter(42.385, -71.083, 13)
        edge_map = {}
        for segment in network.trail_segments():
            segment.draw(gmap)
            edge_map[segment.id] = segment.nodes
        clean_name = (network.name or f'no-name-{i}').replace(' ', '').replace("\'", '')
        gmap.draw(f"{clean_name}-{i}.html")
        with open('edges.csv', 'w') as csv_file:
            writer = csv.DictWriter(csv_file, fieldnames=['start', 'end', 'id', 'distance'])
            writer.writeheader()
            for segment in network.trail_segments():
                writer.writerow(dict(start=segment.nodes[0].id, end=segment.nodes[-1].id, id=segment.id,
                                     distance=segment.length_m()))

        try:
            s = datetime.now()
            circuit, graph = cpp('edges.csv')
            e = datetime.now()
            print(f'Time: {e-s}')
            for k, v in calculate_postman_solution_stats(circuit).items():
                print(k, v)
            with open(f"{clean_name}-{i}.gpx", "w") as f:
                f.write(circuit_to_gpx(circuit, edge_map).to_xml())
        except Exception as ex:
            print(ex)
示例#4
0
def test_sleeping_giant_cpp_solution():
    cpp_solution, graph = cpp(edgelist_filename=EDGELIST,
                              start_node=START_NODE)

    # make number of edges in solution is correct
    assert len(cpp_solution) == 155

    # make sure our total mileage is correct
    cpp_solution_distance = sum([edge[3]['distance'] for edge in cpp_solution])
    assert math.isclose(cpp_solution_distance, 33.25)

    # make sure our circuit begins and ends at the same place
    assert cpp_solution[0][0] == cpp_solution[-1][1] == START_NODE

    # make sure original graph is properly returned
    assert len(graph.edges()) == 121
    [e[2].get('augmented') for e in graph.edges(data=True)].count(True) == 35
示例#5
0
def solvePostmanProblem(name, write=True, write_minimal=True):
    filename = "graphs_in_csv/" + name + ".csv"
    # find CPP solution
    circuit, graph = cpp(edgelist_filename=filename)
    if write:
        print(circuit)
    if write_minimal:
        print("\tNumber of edges walked: " + str(len(circuit)))
    """
    # print solution route
    for e in circuit:
        print(e)
    """

    if write:
        # print solution summary stats
        for k, v in calculate_postman_solution_stats(circuit).items():
            print(k, v)

    createCsvFromCircuit(circuit, name)
示例#6
0
文件: postman.py 项目: rcoh/trails
def create_circuit(self, network_id: str, circuit_id: str):
    network = TrailNetwork.objects.get(id=network_id)
    circuit = Circuit.objects.get(id=circuit_id)
    circuit.status = InProgress
    circuit.error = ""
    circuit.save()
    try:
        graph = read_gpickle(BytesIO(network.graph.tobytes()))
        with NamedTemporaryFile(suffix='.csv', mode='w') as f:
            writer = csv.DictWriter(
                f, fieldnames=['start', 'end', 'id', 'distance'])
            writer.writeheader()
            edge_map = {}
            for segment in segments_for_graph(graph):
                writer.writerow(
                    dict(start=segment.nodes[0].derived_id,
                         end=segment.nodes[-1].derived_id,
                         id=segment.id,
                         distance=segment.length_m()))
                edge_map[segment.id] = segment.nodes
            f.flush()
            circuit_nodes, _ = solver.cpp(f.name)
            stats = calculate_postman_solution_stats(circuit_nodes)
            walked_twice = Distance(m=stats['distance_doublebacked'])
            walked_total = Distance(m=stats['distance_walked_required'])

            line_string = circuit_to_line_string(circuit_nodes, edge_map)
            circuit.route = line_string
            circuit.total_length = walked_total
            circuit.status = Complete
            circuit.error = ""
    except Exception as ex:
        circuit.status = Error
        circuit.error = ex
        raise
    finally:
        circuit.save()
示例#7
0
from postman_problems.solver import cpp
from postman_problems.stats import calculate_postman_solution_stats

# find CPP solution
circuit, graph = cpp(edgelist_filename='graph.csv', start_node='A')

# print solution route
for e in circuit:
    print(e)

# print solution summary stats
for k, v in calculate_postman_solution_stats(circuit).items():
    print(k, v)
示例#8
0
def main():
    """Solve the RPP and save visualizations of the solution"""

    # PARAMS / DATA ---------------------------------------------------------------------

    # inputs
    START_NODE = 'a'
    N_NODES = 13

    # filepaths
    CPP_REQUIRED_SVG_FILENAME = pkg_resources.resource_filename(
        'postman_problems', 'examples/star/output/cpp_graph_req')
    CPP_OPTIONAL_SVG_FILENAME = pkg_resources.resource_filename(
        'postman_problems', 'examples/star/output/cpp_graph_opt')
    RPP_SVG_FILENAME = pkg_resources.resource_filename(
        'postman_problems', 'examples/star/output/rpp_graph')
    RPP_BASE_SVG_FILENAME = pkg_resources.resource_filename(
        'postman_problems', 'examples/star/output/base_rpp_graph')
    PNG_PATH = pkg_resources.resource_filename('postman_problems',
                                               'examples/star/output/png/')
    RPP_GIF_FILENAME = pkg_resources.resource_filename(
        'postman_problems', 'examples/star/output/rpp_graph.gif')

    # setup logging
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)

    # CREATE GRAPH ----------------------------------------------------------------------

    logger.info('Solve RPP')
    graph_base = create_star_graph(N_NODES)
    edgelist = nx.to_pandas_edgelist(graph_base,
                                     source='_node1',
                                     target='_node2')

    # SOLVE CPP -------------------------------------------------------------------------

    # with required edges only
    edgelist_file = create_mock_csv_from_dataframe(edgelist)
    circuit_cpp_req, graph_cpp_req = cpp(edgelist_file, start_node=START_NODE)
    logger.info('Print the CPP solution (required edges only):')
    for e in circuit_cpp_req:
        logger.info(e)

    # with required and optional edges as required
    edgelist_all_req = edgelist.copy()
    edgelist_all_req.drop(['required'], axis=1, inplace=True)
    edgelist_file = create_mock_csv_from_dataframe(edgelist_all_req)
    circuit_cpp_opt, graph_cpp_opt = cpp(edgelist_file, start_node=START_NODE)
    logger.info('Print the CPP solution (optional and required edges):')
    for e in circuit_cpp_opt:
        logger.info(e)

    # SOLVE RPP -------------------------------------------------------------------------

    edgelist_file = create_mock_csv_from_dataframe(
        edgelist)  # need to regenerate
    circuit_rpp, graph_rpp = rpp(edgelist_file, start_node=START_NODE)

    logger.info('Print the RPP solution:')
    for e in circuit_rpp:
        logger.info(e)

    logger.info('Solution summary stats:')
    for k, v in calculate_postman_solution_stats(circuit_rpp).items():
        logger.info(str(k) + ' : ' + str(v))

    # VIZ -------------------------------------------------------------------------------

    try:
        from postman_problems.viz import plot_circuit_graphviz, plot_graphviz, make_circuit_images, make_circuit_video

        logger.info('Creating single SVG of base graph')
        plot_graphviz(graph=graph_base,
                      filename=RPP_BASE_SVG_FILENAME,
                      edge_label_attr='distance',
                      format='svg',
                      engine='circo',
                      graph_attr={
                          'label': 'Base Graph: Distances',
                          'labelloc': 't'
                      })

        logger.info(
            'Creating single SVG of CPP solution (required edges only)')
        plot_circuit_graphviz(
            circuit=circuit_cpp_req,
            graph=graph_cpp_req,
            filename=CPP_REQUIRED_SVG_FILENAME,
            format='svg',
            engine='circo',
            graph_attr={
                'label':
                'Base Graph: Chinese Postman Solution (required edges only)',
                'labelloc': 't'
            })

        logger.info(
            'Creating single SVG of CPP solution (required & optional edges)')
        plot_circuit_graphviz(
            circuit=circuit_cpp_opt,
            graph=graph_cpp_opt,
            filename=CPP_OPTIONAL_SVG_FILENAME,
            format='svg',
            engine='circo',
            graph_attr={
                'label':
                'Base Graph: Chinese Postman Solution (required & optional edges)',
                'labelloc': 't'
            })

        logger.info('Creating single SVG of RPP solution')
        plot_circuit_graphviz(circuit=circuit_rpp,
                              graph=graph_rpp,
                              filename=RPP_SVG_FILENAME,
                              format='svg',
                              engine='circo',
                              graph_attr={
                                  'label':
                                  'Base Graph: Rural Postman Solution',
                                  'labelloc': 't'
                              })

        logger.info('Creating PNG files for GIF')
        make_circuit_images(circuit=circuit_rpp,
                            graph=graph_rpp,
                            outfile_dir=PNG_PATH,
                            format='png',
                            engine='circo')

        logger.info('Creating GIF')
        make_circuit_video(infile_dir_images=PNG_PATH,
                           outfile_movie=RPP_GIF_FILENAME,
                           fps=1)

    except FileNotFoundError(OSError) as e:
        print(e)
        print(
            "Sorry, looks like you don't have all the needed visualization dependencies."
        )
    G.add_edges_from(edges)
    G.remove_nodes_from(list(nx.isolates(G)))
    # Get largest connected component
    G = max(nx.connected_component_subgraphs(G), key=len)

    # ### -------TEST ---
    # nodes = list(G.nodes())
    # poses = [(x, 255 - y) for x, y in nodes]
    # pos = dict(zip(nodes, poses))
    # ax = plt.axes(aspect='equal')
    # nx.draw_networkx(G, pos=pos, ax=ax,
    #                  with_labels=False, nodelist=[], node_size=15,
    #                  edge_color='black', width=2)
    # plt.show()
    # ### -- END TEST --
    path, _ = cpp(G)
    path = [(e1, e2) for e1, e2, _, _ in path]

    ## ADD STOPS
    # Add start
    stops_nodes = [path[0][0]]
    dist = 0
    for e in path:
        d = G.get_edge_data(e[0], e[1])[0]['distance']
        dist += d
        if dist >= 300:
            stops_nodes.append(e[1])
            dist = 0

    # Remove last item if we are less than 150 from start
    if dist < 150:
示例#10
0
def test_cpp_graph_1(GRAPH_1_EDGELIST_CSV):
    circuit, graph = cpp(GRAPH_1_EDGELIST_CSV, start_node='a')
    assert len(circuit) == 7

    # Re-use the test for the summary_stats function to ensure CPP solution is correct
    test_stats_on_simple_graph_required_edges_only(circuit)
示例#11
0
tmp = []
for e in g_tc.edges(data=True):
    tmpi = e[2].copy()  # so we don't mess w original graph
    tmpi['start_node'] = e[0]
    tmpi['end_node'] = e[1]
    tmp.append(tmpi)

# create dataframe with node1 and node2 in order
eldf = pd.DataFrame(tmp)
eldf = eldf[['start_node', 'end_node'] +
            list(set(eldf.columns) - {'start_node', 'end_node'})]

# create edgelist mock CSV
elfn = create_mock_csv_from_dataframe(eldf)

circuit, graph = cpp(elfn, start_node='735393342')

print("----------- CPP Solutions -----------")
# print solution route
for e in circuit:
    print(e)

print("----------- CPP Summary -----------")
# print solution summary stats
for k, v in calculate_postman_solution_stats(circuit).items():
    print(k, v)

# convert 'path' from string back to list.  Caused by `create_mock_csv_from_dataframe`
for e in circuit:
    if type(e[3]['path']) == str:
        exec('e[3]["path"]=' + e[3]["path"])
def main():
    """Solve the CPP and save visualizations of the solution"""

    # PARAMS / DATA ---------------------------------------------------------------------

    # inputs
    EDGELIST = pkg_resources.resource_filename(
        'postman_problems',
        'examples/sleeping_giant/edgelist_sleeping_giant.csv')
    NODELIST = pkg_resources.resource_filename(
        'postman_problems',
        'examples/sleeping_giant/nodelist_sleeping_giant.csv')
    START_NODE = "b_end_east"

    # outputs
    GRAPH_ATTR = {'dpi': '65'}
    EDGE_ATTR = {'fontsize': '20'}
    NODE_ATTR = {
        'shape': 'point',
        'color': 'black',
        'width': '0.1',
        'fixedsize': 'true'
    }

    PNG_PATH = pkg_resources.resource_filename(
        'postman_problems', 'examples/sleeping_giant/output/png/')
    CPP_SVG_FILENAME = pkg_resources.resource_filename(
        'postman_problems', 'examples/sleeping_giant/output/cpp_graph')
    CPP_GIF_FILENAME = pkg_resources.resource_filename(
        'postman_problems', 'examples/sleeping_giant/output/cpp_graph.gif')

    # setup logging
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)

    # SOLVE CPP -------------------------------------------------------------------------

    logger.info('Solve CPP')
    circuit, graph = cpp(EDGELIST, START_NODE)

    logger.info('Print the CPP solution:')
    for e in circuit:
        logger.info(e)

    logger.info('Solution summary stats:')
    for k, v in calculate_postman_solution_stats(circuit).items():
        logger.info(str(k) + ' : ' + str(v))

    # VIZ -------------------------------------------------------------------------------

    try:
        from postman_problems.viz import (add_pos_node_attribute,
                                          add_node_attributes,
                                          plot_circuit_graphviz,
                                          make_circuit_images,
                                          make_circuit_video)

        logger.info('Add node attributes to graph')
        nodelist_df = pd.read_csv(NODELIST)
        graph = add_node_attributes(graph, nodelist_df)  # add attributes
        graph = add_pos_node_attribute(
            graph,
            origin='topleft')  # add X,Y positions in format for graphviz

        logger.info('Creating single SVG of CPP solution')
        plot_circuit_graphviz(circuit=circuit,
                              graph=graph,
                              filename=CPP_SVG_FILENAME,
                              format='svg',
                              engine='neato',
                              graph_attr=GRAPH_ATTR,
                              edge_attr=EDGE_ATTR,
                              node_attr=NODE_ATTR)

    except FileNotFoundError(OSError) as e:
        print(e)
        print(
            "Sorry, looks like you don't have all the needed visualization dependencies."
        )
示例#13
0
def main():
    """Solve the CPP and save visualizations of the solution"""

    # PARAMS / DATA ---------------------------------------------------------------------

    # inputs
    EDGELIST = pkg_resources.resource_filename(
        'postman_problems',
        'examples/seven_bridges/edgelist_seven_bridges.csv')
    START_NODE = 'D'

    # outputs
    PNG_PATH = pkg_resources.resource_filename(
        'postman_problems', 'examples/seven_bridges/output/png/')
    CPP_VIZ_FILENAME = pkg_resources.resource_filename(
        'postman_problems', 'examples/seven_bridges/output/cpp_graph')
    CPP_BASE_VIZ_FILENAME = pkg_resources.resource_filename(
        'postman_problems', 'examples/seven_bridges/output/base_cpp_graph')
    CPP_GIF_FILENAME = pkg_resources.resource_filename(
        'postman_problems', 'examples/seven_bridges/output/cpp_graph.gif')

    # setup logging
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)

    # SOLVE CPP -------------------------------------------------------------------------

    logger.info('Solve CPP')
    circuit, graph = cpp(edgelist_filename=EDGELIST, start_node=START_NODE)

    logger.info('Print the CPP solution:')
    for e in circuit:
        logger.info(e)

    logger.info('Solution summary stats:')
    for k, v in calculate_postman_solution_stats(circuit).items():
        logger.info(str(k) + ' : ' + str(v))

    # VIZ -------------------------------------------------------------------------------

    try:
        from postman_problems.viz import plot_circuit_graphviz, make_circuit_images, make_circuit_video

        logger.info('Creating single SVG of base graph')
        plot_circuit_graphviz(circuit=circuit,
                              graph=graph,
                              filename=CPP_BASE_VIZ_FILENAME,
                              edge_label_attr='distance',
                              format='svg',
                              engine='circo',
                              graph_attr={
                                  'label': 'Base Graph: Distances',
                                  'labelloc': 't'
                              })

        logger.info('Creating single SVG of CPP solution')
        plot_circuit_graphviz(circuit=circuit,
                              graph=graph,
                              filename=CPP_VIZ_FILENAME,
                              format='svg',
                              engine='circo',
                              graph_attr={
                                  'label':
                                  'Base Graph: Chinese Postman Solution',
                                  'labelloc': 't'
                              })

        logger.info('Creating PNG files for GIF')
        make_circuit_images(circuit=circuit,
                            graph=graph,
                            outfile_dir=PNG_PATH,
                            format='png',
                            engine='circo',
                            graph_attr={
                                'label':
                                'Base Graph: Chinese Postman Solution',
                                'labelloc': 't'
                            })

        logger.info('Creating GIF')
        video_message = make_circuit_video(infile_dir_images=PNG_PATH,
                                           outfile_movie=CPP_GIF_FILENAME,
                                           fps=0.5)

        logger.info(video_message)
        logger.info("and that's a wrap, checkout the output!")

    except FileNotFoundError(OSError) as e:
        print(e)
        print(
            "Sorry, looks like you don't have all the needed visualization dependencies."
        )
示例#14
0
def chinese_postman(csv):
    # find CPP solution
    circuit, graph = cpp(edgelist_filename=csv, start_node='0')
    return circuit
    for node, deg in G.degree():
        if deg > 0:
            x, y = node
            img[y, x] = 255

    return img

from postman_problems.solver import cpp

for e in list(G.edges()):
    G.remove_edge(*e)
    G.add_edge(*e, distance=1, id=str(e))

G.remove_nodes_from(list(nx.isolates(G)))
c, g = cpp(G)
edgelist = [(e1, e2) for e1, e2, _, _ in c]

#TODO: somehow avoid the last stop being too close to the first one?
stops = [n1 for n1, n2 in edgelist[::60]]

# pos is {(0,0): (0,255), (0,1): (0,254), (0,2): (0,253), ...,
# (255,254): (255,1), (255,255): (255,0)}
# Need to reverse order of y in the positions since img has origin top left
# and pyplot has origin bottom left
# nodes = list(G.nodes())
# poses = [(x, 255-y) for x,y in nodes]
# pos = dict(zip(nodes, poses))#list(product(range(w), range(h)[::-1]))))
# nx.draw_networkx(G, pos=pos, with_labels=False, node_size=1, node_color='w', width=2)
# nx.draw_networkx(G, pos=pos, edgelist=c, with_labels=False, node_size=1, node_color='w', edge_color ='r', width=2)
# #plt.show()
示例#16
0
# -*- coding: utf-8 -*-
"""
Created on Thu Jun 21 19:17:20 2018

@author: weing
"""

import postman_problems
from postman_problems.solver import cpp
from postman_problems.stats import calculate_postman_solution_stats

# find CPP solution
circuitSmall, graphSmall = cpp(
    edgelist_filename='component-connections-edgelist-reduced-degree-2.csv',
    start_node='1')
circuit, graph = cpp(edgelist_filename='component-connections-edgelist.csv',
                     start_node='1')

# print solution route
for e in circuit:
    print(e)

# print solution route
for e in circuitSmall:
    print(e)

# print solution summary stats
for k, v in calculate_postman_solution_stats(circuitSmall).items():
    print(k, v)

for k, v in calculate_postman_solution_stats(circuit).items():