commit lab1
This commit is contained in:
parent
bf5842d489
commit
67c2869323
134
oop.py
134
oop.py
|
@ -1,11 +1,14 @@
|
||||||
import copy
|
import copy
|
||||||
import heapq
|
import heapq
|
||||||
import re
|
import re
|
||||||
from math import isinf,inf
|
import sys
|
||||||
|
import time
|
||||||
|
from math import isinf, inf
|
||||||
|
|
||||||
import matplotlib.patches
|
import matplotlib.patches
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from typing import Dict, Generator, List, Optional, cast
|
from typing import Dict, Generator, List, Optional, cast, Tuple
|
||||||
import random
|
import random
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -14,11 +17,12 @@ def main():
|
||||||
# print("Welcome to Lab1")
|
# print("Welcome to Lab1")
|
||||||
print("功能5中输入@停止功能")
|
print("功能5中输入@停止功能")
|
||||||
tu = None
|
tu = None
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
i = input("请输入操作(q:退出, 0:读入文件, 1:展示图形, 2:查找桥接词, 3:生成新文本, 4:计算最短路径, 5:随机游走):")
|
i = input("请输入操作(q:退出, 0:读入文件, 1:展示图形, 2:查找桥接词, 3:生成新文本, 4:计算最短路径, 5:随机游走):")
|
||||||
if i == "q" :
|
if i == "q" :
|
||||||
exit(0)
|
sys.exit()
|
||||||
if i == "0": #shengchengTu
|
if i == "0": #shengchengTu
|
||||||
tu=Tu()
|
tu=Tu()
|
||||||
|
|
||||||
|
@ -63,7 +67,7 @@ class Tu :
|
||||||
|
|
||||||
def read_text_file(self,filename):
|
def read_text_file(self,filename):
|
||||||
try:
|
try:
|
||||||
with open(filename, 'r') as file:
|
with open(filename, 'r',"UTF-8") as file:
|
||||||
text = file.read()
|
text = file.read()
|
||||||
# 用正则表达式将非字母字符替换为空格,并将换行符也替换为空格
|
# 用正则表达式将非字母字符替换为空格,并将换行符也替换为空格
|
||||||
text = re.sub(r'[^a-zA-Z\n]+', ' ', text)
|
text = re.sub(r'[^a-zA-Z\n]+', ' ', text)
|
||||||
|
@ -109,9 +113,10 @@ class Tu :
|
||||||
def draw_directed_graph(self):
|
def draw_directed_graph(self):
|
||||||
G=self.graph
|
G=self.graph
|
||||||
pos = nx.spring_layout(G)
|
pos = nx.spring_layout(G)
|
||||||
|
plt.rcParams['figure.figsize'] = (12.8, 7.2)
|
||||||
nx.draw_networkx(G, pos, with_labels=True, node_size=1000, node_color="skyblue",edge_color="black", font_size=10, font_weight="bold",
|
nx.draw_networkx(G, pos, with_labels=True, node_size=1000,
|
||||||
arrows=True, connectionstyle='arc3,rad=0.2')
|
node_color="skyblue",edge_color="black", font_size=10,
|
||||||
|
font_weight="bold",arrows=True, connectionstyle='arc3,rad=0.2')
|
||||||
edge_labels = nx.get_edge_attributes(G, 'weight')
|
edge_labels = nx.get_edge_attributes(G, 'weight')
|
||||||
# 调整箭头位置
|
# 调整箭头位置
|
||||||
for edge, weight in edge_labels.items():
|
for edge, weight in edge_labels.items():
|
||||||
|
@ -119,9 +124,11 @@ class Tu :
|
||||||
dx = pos[edge[0]][0] - pos[edge[1]][0]
|
dx = pos[edge[0]][0] - pos[edge[1]][0]
|
||||||
dy = pos[edge[0]][1] - pos[edge[1]][1]
|
dy = pos[edge[0]][1] - pos[edge[1]][1]
|
||||||
plt.annotate(weight, (
|
plt.annotate(weight, (
|
||||||
(pos[edge[0]][0] + pos[edge[1]][0]) / 2 + dy * 0.1, (pos[edge[0]][1] + pos[edge[1]][1]) / 2 - dx * 0.1))
|
(pos[edge[0]][0] + pos[edge[1]][0]) / 2 + dy * 0.1,
|
||||||
|
(pos[edge[0]][1] + pos[edge[1]][1]) / 2 - dx * 0.1))
|
||||||
else: # 反向边不存在
|
else: # 反向边不存在
|
||||||
plt.annotate(weight, ((pos[edge[0]][0] + pos[edge[1]][0]) / 2, (pos[edge[0]][1] + pos[edge[1]][1]) / 2))
|
plt.annotate(weight, ((pos[edge[0]][0] + pos[edge[1]][0]) / 2,
|
||||||
|
(pos[edge[0]][1] + pos[edge[1]][1]) / 2))
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
def drawDirectedGraph(self):
|
def drawDirectedGraph(self):
|
||||||
|
@ -134,23 +141,10 @@ class Tu :
|
||||||
print("No", word1, "or", word2, "in the graph!")
|
print("No", word1, "or", word2, "in the graph!")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
bridge_words = []
|
bridge_words = [
|
||||||
bridge_words_origin = []
|
word for word in graph[word1]
|
||||||
for bridge_word in graph:
|
if word2 in graph.get(word, {})
|
||||||
if word1 == bridge_word:
|
]
|
||||||
bridge_words = list(graph[bridge_word].keys())
|
|
||||||
bridge_words_origin = copy.deepcopy(bridge_words)
|
|
||||||
|
|
||||||
for wordi in bridge_words_origin:
|
|
||||||
|
|
||||||
|
|
||||||
if graph.get(wordi) != None:
|
|
||||||
|
|
||||||
if word2 not in graph[wordi].keys():
|
|
||||||
bridge_words.remove(wordi)
|
|
||||||
|
|
||||||
else:
|
|
||||||
bridge_words.remove(wordi)
|
|
||||||
|
|
||||||
return bridge_words
|
return bridge_words
|
||||||
|
|
||||||
|
@ -202,24 +196,42 @@ class Tu :
|
||||||
print("There are upper characters in your input")
|
print("There are upper characters in your input")
|
||||||
print(self.insert_bridge_words(text_re))
|
print(self.insert_bridge_words(text_re))
|
||||||
|
|
||||||
|
def find_shortest_path_old(self,word1, word2):
|
||||||
|
|
||||||
|
graph=self.graph
|
||||||
|
try:
|
||||||
|
shortest_path_generator = (
|
||||||
|
nx.all_shortest_paths(graph, source=word1, target=word2, weight='weight'))
|
||||||
|
shortest_length = (
|
||||||
|
nx.shortest_path_length(graph, source=word1, target=word2, weight='weight'))
|
||||||
|
return shortest_path_generator, shortest_length
|
||||||
|
except nx.NetworkXNoPath:
|
||||||
|
return None, None
|
||||||
def find_shortest_path(self,word1, word2):
|
def find_shortest_path(self,word1, word2):
|
||||||
|
|
||||||
graph=self.graph
|
|
||||||
try:
|
try:
|
||||||
shortest_path_generator = nx.all_shortest_paths(graph, source=word1, target=word2, weight='weight')
|
|
||||||
shortest_length = nx.shortest_path_length(graph, source=word1, target=word2, weight='weight')
|
|
||||||
return shortest_path_generator, shortest_length
|
|
||||||
except nx.NetworkXNoPath:
|
|
||||||
return None, None
|
|
||||||
def find_shortest_path_re(self,word1, word2):
|
|
||||||
graph=self.graph
|
|
||||||
try:
|
|
||||||
shortest_path_generator = self.all_simple_paths_graph(word1, word2)
|
|
||||||
shortest_length=self.calc_shortest_path_len(word1,word2)
|
|
||||||
return shortest_path_generator, shortest_length
|
|
||||||
except nx.NetworkXNoPath:
|
|
||||||
return None, None
|
|
||||||
|
|
||||||
|
(shortest_path_list,shortest_length)=self.calc_shortest_path_len(word1,word2)
|
||||||
|
return shortest_path_list, shortest_length
|
||||||
|
except nx.NetworkXNoPath:
|
||||||
|
return None, None
|
||||||
|
def find_shortest_path_ex(self,word1, word2):
|
||||||
|
|
||||||
|
try:
|
||||||
|
shortest_path_generator=self.all_simple_paths_graph(word1,word2)
|
||||||
|
shortest_length=self.calc_shortest_path_len(word1,word2)
|
||||||
|
|
||||||
|
shortest_path_list = []
|
||||||
|
|
||||||
|
for shortest_path in shortest_path_generator:
|
||||||
|
|
||||||
|
if shortest_path.__len__()==shortest_length:
|
||||||
|
shortest_path_list.append(shortest_path)
|
||||||
|
return(shortest_path_list,shortest_length)
|
||||||
|
|
||||||
|
|
||||||
|
except nx.NetworkXNoPath:
|
||||||
|
return None, None
|
||||||
|
|
||||||
def draw_shortest_path(self, shortest_path_list):
|
def draw_shortest_path(self, shortest_path_list):
|
||||||
graph=self.graph
|
graph=self.graph
|
||||||
|
@ -242,17 +254,22 @@ class Tu :
|
||||||
|
|
||||||
#print(shortest_path)
|
#print(shortest_path)
|
||||||
|
|
||||||
if edge in zip(shortest_path[:-1], shortest_path[1:]) or edge in zip(shortest_path[1:], shortest_path[:-1]):
|
if (edge in zip(shortest_path[:-1], shortest_path[1:]) or
|
||||||
|
edge in zip(shortest_path[1:], shortest_path[:-1])):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nx.draw_networkx_edges(graph, pos, edgelist=[edge], width=2.0, edge_color=num, arrows=True,arrowstyle="->",arrowsize=30
|
nx.draw_networkx_edges(graph, pos, edgelist=[edge], width=2.0, edge_color=num,
|
||||||
|
arrows=True,arrowstyle="->",arrowsize=30
|
||||||
,connectionstyle='arc3,rad=0.2')
|
,connectionstyle='arc3,rad=0.2')
|
||||||
else:
|
else:
|
||||||
nx.draw_networkx_edges(graph, pos, edgelist=[edge], width=1.0, edge_color="black", arrows=True,arrowstyle="->",arrowsize=30
|
nx.draw_networkx_edges(graph, pos, edgelist=[edge], width=1.0,
|
||||||
|
edge_color="black",
|
||||||
|
arrows=True,arrowstyle="->",arrowsize=30
|
||||||
,connectionstyle='arc3,rad=0.2')
|
,connectionstyle='arc3,rad=0.2')
|
||||||
plt.show()
|
plt.show()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
def calcShortestPath(self,word1, word2):
|
def calcShortestPath(self,word1, word2):
|
||||||
|
@ -272,9 +289,9 @@ class Tu :
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def calc_shortest_path(self,word1, word2):
|
def calc_shortest_path_old(self,word1, word2):
|
||||||
|
|
||||||
shortest_path_generator, shortest_length = self.find_shortest_path_re(word1, word2)
|
shortest_path_generator, shortest_length = self.find_shortest_path_old(word1, word2)
|
||||||
shortest_path_list=[]
|
shortest_path_list=[]
|
||||||
|
|
||||||
for shortest_path in shortest_path_generator:
|
for shortest_path in shortest_path_generator:
|
||||||
|
@ -288,6 +305,24 @@ class Tu :
|
||||||
else:
|
else:
|
||||||
print("No path exists between", word1, "and", word2)
|
print("No path exists between", word1, "and", word2)
|
||||||
|
|
||||||
|
|
||||||
|
def calc_shortest_path(self,word1, word2):
|
||||||
|
|
||||||
|
shortest_path_list, shortest_length = self.find_shortest_path_ex(word1, word2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for shortest_path in shortest_path_list:
|
||||||
|
|
||||||
|
if shortest_path:
|
||||||
|
print("Shortest path:", '→'.join(shortest_path))
|
||||||
|
print("Length of shortest path:", shortest_length)
|
||||||
|
|
||||||
|
if shortest_path_list.__len__()>0:
|
||||||
|
self.draw_shortest_path(shortest_path_list)
|
||||||
|
else:
|
||||||
|
print("No path exists between", word1, "and", word2)
|
||||||
|
|
||||||
def random_traversal(self):
|
def random_traversal(self):
|
||||||
|
|
||||||
# 用户输入文件名
|
# 用户输入文件名
|
||||||
|
@ -374,12 +409,13 @@ class Tu :
|
||||||
stack.pop()
|
stack.pop()
|
||||||
visited.popitem()
|
visited.popitem()
|
||||||
|
|
||||||
def calc_shortest_path_len(self, word1: str, word2: str) -> str:
|
def calc_shortest_path_len(self, word1: str, word2: str) -> str | tuple[str, int]:
|
||||||
|
|
||||||
if word1 not in self.graph.nodes or word2 not in self.graph.nodes:
|
if word1 not in self.graph.nodes or word2 not in self.graph.nodes:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
distances = {node: inf for node in self.graph.nodes} # 存储word1到所有结点的距离,初始化为无穷大
|
distances = {node: inf for node in self.graph.nodes}
|
||||||
|
# 存储word1到所有结点的距离,初始化为无穷大
|
||||||
previous_nodes: Dict[str, Optional[str]] = {node: None for node in self.graph.nodes} # 存储每个节点最短路径中的前一个节点,初始化为None
|
previous_nodes: Dict[str, Optional[str]] = {node: None for node in self.graph.nodes} # 存储每个节点最短路径中的前一个节点,初始化为None
|
||||||
distances[word1] = 0 # 距离初始化为0
|
distances[word1] = 0 # 距离初始化为0
|
||||||
priority_queue = [(0, word1)] # 优先级队列,用于按照从小到大获取节点
|
priority_queue = [(0, word1)] # 优先级队列,用于按照从小到大获取节点
|
||||||
|
@ -412,9 +448,9 @@ class Tu :
|
||||||
path.insert(0, current_node)
|
path.insert(0, current_node)
|
||||||
|
|
||||||
if isinf(distances[word2]): # 目标节点不可达
|
if isinf(distances[word2]): # 目标节点不可达
|
||||||
return ""
|
return ("",0)
|
||||||
return path.__len__()
|
return path.__len__()
|
||||||
return ' '.join(path)
|
#return (' '.join(path),path.__len__())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in New Issue