如何基于矩形坐标文本文件在Python中构建节点为矩形、边为距离的无向图?
1. Building a Graph with Nodes and Edges in Python
You’ve got two solid approaches here: rolling your own custom implementation for full control, or using a tried-and-true library like networkx to handle the heavy lifting.
Option 1: Manual Implementation (Custom Classes)
If you want to dig into the underlying structure, define Node and Graph classes from scratch:
class Node: def __init__(self, node_id, **attributes): self.id = node_id self.attributes = attributes # Store extra data like rectangle parameters class Graph: def __init__(self, is_directed=False): self.nodes = {} # Key: node_id, Value: Node object self.edges = {} # Key: node_id, Value: dict of {neighbor_id: edge_weight} self.is_directed = is_directed def add_node(self, node): if node.id not in self.nodes: self.nodes[node.id] = node self.edges[node.id] = {} def add_edge(self, from_node_id, to_node_id, weight=1.0): # Add edge in both directions if undirected if from_node_id in self.nodes and to_node_id in self.nodes: self.edges[from_node_id][to_node_id] = weight if not self.is_directed: self.edges[to_node_id][from_node_id] = weight
Option 2: Using networkx (Recommended for Most Cases)
networkx is a go-to library that eliminates boilerplate and simplifies complex graph operations. Perfect for quick prototyping:
import networkx as nx # Create an undirected graph G = nx.Graph() # Add nodes with attached attributes G.add_node(0, x_center=0.568, y_center=0.394, width=0.177, height=0.346) G.add_node(1, x_center=0.392, y_center=0.393, width=0.172, height=0.327) # Add an edge with a weight (e.g., distance between nodes) G.add_edge(0, 1, weight=0.177) # Check the graph structure print("Nodes:", G.nodes(data=True)) print("Edges:", G.edges(data=True))
2. Creating an Undirected Graph from Your Rectangle TXT File
Let’s turn your rectangle data into a graph where nodes represent rectangles, and edges represent the Euclidean distance between their centers. Here’s a complete step-by-step solution:
Step 1: Parse the TXT File
First, read and extract the rectangle parameters from your file (skip the header line, then parse each row of Xcenter Ycenter width height):
import math import networkx as nx def parse_rectangles(file_path): rectangles = [] with open(file_path, 'r') as f: next(f) # Skip the header line for line in f: line = line.strip() if not line: continue x_center, y_center, width, height = map(float, line.split()) rectangles.append({ 'x_center': x_center, 'y_center': y_center, 'width': width, 'height': height }) return rectangles
Step 2: Calculate Distance Between Rectangles
We’ll use the Euclidean distance between the centers of two rectangles:
Distance = √[(x₁ - x₂)² + (y₁ - y₂)²]
def calculate_distance(rect1, rect2): dx = rect1['x_center'] - rect2['x_center'] dy = rect1['y_center'] - rect2['y_center'] return math.hypot(dx, dy) # Equivalent to sqrt(dx² + dy²)
Step 3: Build the Undirected Graph
Create the graph, add nodes with rectangle attributes, and connect every pair of nodes with an edge weighted by their distance:
def build_rectangle_graph(rectangles): G = nx.Graph() # Add nodes with rectangle attributes for idx, rect in enumerate(rectangles): G.add_node(idx, **rect) # Add edges between all unique pairs (undirected, so no duplicate edges) for i in range(len(rectangles)): for j in range(i + 1, len(rectangles)): distance = calculate_distance(rectangles[i], rectangles[j]) G.add_edge(i, j, weight=round(distance, 6)) # Round for readability return G
Step 4: Put It All Together and Verify
# Usage example (replace with your file path) rect_file_path = 'your_rectangles.txt' rectangles = parse_rectangles(rect_file_path) rect_graph = build_rectangle_graph(rectangles) # Print basic graph info print("Number of nodes:", rect_graph.number_of_nodes()) print("Number of edges:", rect_graph.number_of_edges()) # Print edges with their distance weights print("\nEdges and their distances:") for u, v, data in rect_graph.edges(data=True): print(f"Rectangle {u} ↔ Rectangle {v}: Distance = {data['weight']}")
Optional: Visualize the Graph
If you want to see the graph visually, install matplotlib (pip install matplotlib) and use this code:
import matplotlib.pyplot as plt pos = nx.spring_layout(rect_graph) # Position nodes for clarity nx.draw(rect_graph, pos, with_labels=True, node_size=1000, node_color='lightblue') edge_labels = nx.get_edge_attributes(rect_graph, 'weight') nx.draw_networkx_edge_labels(rect_graph, pos, edge_labels=edge_labels) plt.title("Undirected Graph of Rectangles (Edge Weight = Center Distance)") plt.show()
内容的提问来源于stack exchange,提问作者walid

