commit lab1-stylefixed

This commit is contained in:
qasw-987 2024-06-03 16:28:31 +08:00
parent 67c2869323
commit 6c411c416b
1 changed files with 79 additions and 92 deletions

171
oop.py
View File

@ -4,13 +4,10 @@ import re
import sys
import time
from math import isinf, inf
import matplotlib.patches
import networkx as nx
import matplotlib.pyplot as plt
from typing import Dict, Generator, List, Optional, cast, Tuple
from typing import Dict, Generator, List, Optional
import random
import os
def main():
@ -21,53 +18,53 @@ def main():
while True:
i = input("请输入操作q:退出, 0:读入文件, 1:展示图形, 2:查找桥接词, 3:生成新文本, 4:计算最短路径, 5:随机游走):")
if i == "q" :
if i == "q":
sys.exit()
if i == "0": #shengchengTu
tu=Tu()
if i == "0":
tu = Tu()
file_name=input("请输入文件名称:")
file_name = input("请输入文件名称:")
tu.generate_directed_dict(tu.read_text_file(file_name))
tu.generate_directed_graph()
continue
if tu is None :
if tu is None:
print("未找到有效的图")
continue
if i == "1":
tu.drawDirectedGraph()
elif i == "2" :
elif i == "2":
word1 = input("Enter the word1:")
word2 = input("Enter the word2:")
tu.queryBridgeWords(word1,word2)
elif i == "3" :
tu.queryBridgeWords(word1, word2)
elif i == "3":
text = input("Enter the text:")
tu.generateNewText(text)
elif i== "4" :
elif i == "4":
word1 = input("Enter the word1:")
word2 = input("Enter the word2,just '' is all")
tu.calcShortestPath(word1,word2)
tu.calcShortestPath(word1, word2)
elif i == "5" :
elif i == "5":
tu.randomWalk()
else:
print("Invalid input")
class Tu :
class Tu:
def __init__(self):
self.dict={}
self.graph=nx.MultiDiGraph()
self.dict = {}
self.graph = nx.MultiDiGraph()
def read_text_file(self,filename):
@staticmethod
def read_text_file(filename):
try:
with open(filename, 'r',"UTF-8") as file:
with open(filename, 'r', encoding="utf-8") as file:
text = file.read()
# 用正则表达式将非字母字符替换为空格,并将换行符也替换为空格
text = re.sub(r'[^a-zA-Z\n]+', ' ', text)
@ -79,8 +76,8 @@ class Tu :
print("File not found.")
return []
def generate_directed_dict(self,word_sequence):
graph = self.dict #chunfuzhi,yiqigai
def generate_directed_dict(self, word_sequence):
graph = self.dict
for i in range(len(word_sequence) - 1):
current_word = word_sequence[i]
next_word = word_sequence[i + 1]
@ -99,7 +96,7 @@ class Tu :
return graph
def generate_directed_graph(self):
G = self.graph #wufuzhi,yiqigai
G = self.graph # wufuzhi,yiqigai
graph = self.dict
# 添加节点和边
for node, neighbors in graph.items():
@ -111,12 +108,12 @@ class Tu :
return G
def draw_directed_graph(self):
G=self.graph
G = self.graph
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",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')
# 调整箭头位置
for edge, weight in edge_labels.items():
@ -124,9 +121,9 @@ class Tu :
dx = pos[edge[0]][0] - pos[edge[1]][0]
dy = pos[edge[0]][1] - pos[edge[1]][1]
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))
else: # 反向边不存在
(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: # 反向边不存在
plt.annotate(weight, ((pos[edge[0]][0] + pos[edge[1]][0]) / 2,
(pos[edge[0]][1] + pos[edge[1]][1]) / 2))
plt.show()
@ -148,7 +145,8 @@ class Tu :
return bridge_words
def print_bridge_words(self,bridge_words,word1,word2):
@staticmethod
def print_bridge_words(bridge_words, word1, word2):
if not bridge_words:
print("No bridge words from", word1, "to", word2, "!")
@ -159,11 +157,11 @@ class Tu :
return bridge_words
def queryBridgeWords(self,word1, word2):
def queryBridgeWords(self, word1, word2):
word1 = self.input_check(word1)
word2 = self.input_check(word2)
bridge_words = self.find_bridge_words(word1, word2)
self.print_bridge_words(bridge_words,word1,word2)
self.print_bridge_words(bridge_words, word1, word2)
def insert_bridge_words(self, text):
@ -177,7 +175,7 @@ class Tu :
word2 = words[i + 1].lower()
new_text.append(words[i])
bridge_words = self.find_bridge_words( word1, word2)
bridge_words = self.find_bridge_words(word1, word2)
if len(bridge_words) > 0:
random_bridge_word = random.choice(bridge_words)
@ -187,18 +185,18 @@ class Tu :
return ' '.join(new_text)
def generateNewText(self,text):
def generateNewText(self, text):
(text_re,text_ren)=re.subn(r'[^a-zA-Z\n]+', ' ', text)
if text_ren>0 :
(text_re, text_ren) = re.subn(r'[^a-zA-Z\n]+', ' ', text)
if text_ren > 0:
print("There are illegal signs in your input")
if not text_re.islower():
print("There are upper characters in your input")
print(self.insert_bridge_words(text_re))
def find_shortest_path_old(self,word1, word2):
def find_shortest_path_old(self, word1, word2):
graph=self.graph
graph = self.graph
try:
shortest_path_generator = (
nx.all_shortest_paths(graph, source=word1, target=word2, weight='weight'))
@ -207,39 +205,38 @@ class Tu :
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):
try:
(shortest_path_list,shortest_length)=self.calc_shortest_path_len(word1,word2)
(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):
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_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:
if shortest_path.__len__() == shortest_length:
shortest_path_list.append(shortest_path)
return(shortest_path_list,shortest_length)
return shortest_path_list, shortest_length
except nx.NetworkXNoPath:
return None, None
def draw_shortest_path(self, shortest_path_list):
graph=self.graph
graph = self.graph
plt.figure(figsize=(10, 6))
# !!! HUATU ROLL YANSE
pos = nx.spring_layout(graph)
nx.draw_networkx_nodes(graph, pos, node_size=1000, node_color="skyblue")
nx.draw_networkx_labels(graph, pos, font_size=10, font_weight="bold")
@ -252,47 +249,42 @@ class Tu :
for edge in graph.edges():
#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])):
nx.draw_networkx_edges(graph, pos, edgelist=[edge], width=2.0, edge_color=num,
arrows=True,arrowstyle="->",arrowsize=30
,connectionstyle='arc3,rad=0.2')
arrows=True, arrowstyle="->", arrowsize=30,
connectionstyle='arc3,rad=0.2')
else:
nx.draw_networkx_edges(graph, pos, edgelist=[edge], width=1.0,
edge_color="black",
arrows=True,arrowstyle="->",arrowsize=30
,connectionstyle='arc3,rad=0.2')
arrows=True, arrowstyle="->", arrowsize=30,
connectionstyle='arc3,rad=0.2')
plt.show()
time.sleep(1)
def calcShortestPath(self,word1, word2):
def calcShortestPath(self, word1, word2):
if word2 == "":
word1 = self.input_check(word1)
for wordtmp in self.dict :
if wordtmp == word1 :
for wordtmp in self.dict:
if wordtmp == word1:
continue
else:
self.calc_shortest_path(word1,wordtmp)
self.calc_shortest_path(word1, wordtmp)
pass
else:
word1 = self.input_check(word1)
word2 = self.input_check(word2)
self.calc_shortest_path(word1,word2)
self.calc_shortest_path(word1, word2)
pass
def calc_shortest_path_old(self,word1, word2):
def calc_shortest_path_old(self, 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:
@ -300,25 +292,22 @@ class Tu :
print("Shortest path:", ''.join(shortest_path))
print("Length of shortest path:", shortest_length)
shortest_path_list.append(shortest_path)
if shortest_path_list.__len__()>0:
if shortest_path_list.__len__() > 0:
self.draw_shortest_path(shortest_path_list)
else:
print("No path exists between", word1, "and", word2)
def calc_shortest_path(self,word1, 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:
if shortest_path_list.__len__() > 0:
self.draw_shortest_path(shortest_path_list)
else:
print("No path exists between", word1, "and", word2)
@ -327,10 +316,9 @@ class Tu :
# 用户输入文件名
filename = input("Enter the filename to save traversal results: ")
filename+=".txt"
filename += ".txt"
graph=copy.deepcopy(self.dict)
graph = copy.deepcopy(self.dict)
start_node = random.choice(list(graph.keys()))
visited_nodes = set()
visited_edges = []
@ -341,10 +329,10 @@ class Tu :
visited_nodes.add(current_node)
file.write(current_node + '\n')
print(current_node)
if input()=="@":
if input() == "@":
file.close()
break
if graph.get(current_node) != None:
if graph.get(current_node) is not None:
pass
else:
break
@ -364,23 +352,21 @@ class Tu :
def randomWalk(self):
self.random_traversal()
@staticmethod
def input_check(input_word):
(input_word_re, input_word_ren) = re.subn(r'[^a-zA-Z\n]', ' ', input_word)
def input_check(self, input_word):
(input_word_re,input_word_ren)=re.subn(r'[^a-zA-Z\n]', ' ', input_word)
if input_word_ren>0 :
print("There are illegal signs in your input,the amount is "+str(input_word_ren))
if input_word_ren > 0:
print("There are illegal signs in your input,the amount is " + str(input_word_ren))
if not input_word_re.islower():
print("There are upper characters in your input")
tmp=input_word_re.lower().split()
if len(tmp)>1 :
tmp = input_word_re.lower().split()
if len(tmp) > 1:
print("There are more than one word in your input")
return tmp[0]
def all_simple_paths_graph(self, source: str, targets: str) -> Generator[List[str], None, None]:
G = self.graph
cutoff = len(G) - 1 # 设置路径的最大深度,防止无限循环。
@ -409,14 +395,15 @@ class Tu :
stack.pop()
visited.popitem()
def calc_shortest_path_len(self, word1: str, word2: str) -> str | tuple[str, int]:
def calc_shortest_path_len(self, word1: str, word2: str) -> int:
if word1 not in self.graph.nodes or word2 not in self.graph.nodes:
return ""
return 0
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
priority_queue = [(0, word1)] # 优先级队列,用于按照从小到大获取节点
@ -448,9 +435,9 @@ class Tu :
path.insert(0, current_node)
if isinf(distances[word2]): # 目标节点不可达
return ("",0)
return 0
return path.__len__()
#return (' '.join(path),path.__len__())
# return (' '.join(path),path.__len__())
if __name__ == '__main__':