Compare commits
No commits in common. "master" and "2021112105" have entirely different histories.
master
...
2021112105
|
@ -1,8 +0,0 @@
|
||||||
# 默认忽略的文件
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# 基于编辑器的 HTTP 客户端请求
|
|
||||||
/httpRequests/
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="PYTHON_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="jdk" jdkName="C:\Users\Gao42H\miniconda3" jdkType="Python SDK" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
|
@ -1,6 +0,0 @@
|
||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<settings>
|
|
||||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
|
||||||
<version value="1.0" />
|
|
||||||
</settings>
|
|
||||||
</component>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Black">
|
|
||||||
<option name="sdkName" value="Python 3.12" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="C:\Users\Gao42H\miniconda3" project-jdk-type="Python SDK" />
|
|
||||||
</project>
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/SELab1.iml" filepath="$PROJECT_DIR$/.idea/SELab1.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="PySciProjectComponent">
|
|
||||||
<option name="PY_INTERACTIVE_PLOTS_SUGGESTED" value="true" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
1
1.txt
1
1.txt
|
@ -1 +0,0 @@
|
||||||
The sunlight filtered through the dense canopy, casting intricate patterns on the forest floor. Birds chirped melodiously, creating a symphony of nature finest sounds. Amidst the greenery, a small stream gurgled, its waters crystal clear and refreshing. Suddenly, a deer darted past, startling.To @ explore strange new worlds and worlds and seek strange,To seek out new life and new worlds and new civilizations?
|
|
BIN
Lab1实验报告.doc
BIN
Lab1实验报告.doc
Binary file not shown.
BIN
SEreport1.docx
BIN
SEreport1.docx
Binary file not shown.
Binary file not shown.
Binary file not shown.
272
oop.py
272
oop.py
|
@ -1,70 +1,69 @@
|
||||||
import copy
|
import copy
|
||||||
import heapq
|
import heapq
|
||||||
import re
|
import re
|
||||||
import sys
|
from math import isinf,inf
|
||||||
import time
|
import matplotlib.patches
|
||||||
from math import isinf, inf
|
|
||||||
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
|
from typing import Dict, Generator, List, Optional, cast
|
||||||
import random
|
import random
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
def main():
|
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" :
|
||||||
sys.exit()
|
exit(0)
|
||||||
if i == "0":
|
if i == "0": #shengchengTu
|
||||||
tu = Tu()
|
tu=Tu()
|
||||||
|
|
||||||
file_name = input("请输入文件名称:")
|
file_name=input("请输入文件名称:")
|
||||||
|
|
||||||
tu.generate_directed_dict(tu.read_text_file(file_name))
|
tu.generate_directed_dict(tu.read_text_file(file_name))
|
||||||
tu.generate_directed_graph()
|
tu.generate_directed_graph()
|
||||||
continue
|
continue
|
||||||
if tu is None:
|
if tu is None :
|
||||||
print("未找到有效的图")
|
print("未找到有效的图")
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if i == "1":
|
if i == "1":
|
||||||
tu.drawDirectedGraph()
|
tu.drawDirectedGraph()
|
||||||
elif i == "2":
|
elif i == "2" :
|
||||||
word1 = input("Enter the word1:")
|
word1 = input("Enter the word1:")
|
||||||
word2 = input("Enter the word2:")
|
word2 = input("Enter the word2:")
|
||||||
|
|
||||||
tu.queryBridgeWords(word1, word2)
|
tu.queryBridgeWords(word1,word2)
|
||||||
elif i == "3":
|
elif i == "3" :
|
||||||
text = input("Enter the text:")
|
text = input("Enter the text:")
|
||||||
tu.generateNewText(text)
|
tu.generateNewText(text)
|
||||||
|
|
||||||
elif i == "4":
|
elif i== "4" :
|
||||||
word1 = input("Enter the word1:")
|
word1 = input("Enter the word1:")
|
||||||
word2 = input("Enter the word2,just '' is all")
|
word2 = input("Enter the word2,just '' is all")
|
||||||
tu.calcShortestPath(word1, word2)
|
tu.calcShortestPath(word1,word2)
|
||||||
|
|
||||||
elif i == "5":
|
elif i == "5" :
|
||||||
tu.randomWalk()
|
tu.randomWalk()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("Invalid input")
|
print("Invalid input")
|
||||||
|
|
||||||
|
|
||||||
class Tu:
|
|
||||||
def __init__(self):
|
|
||||||
self.dict = {}
|
|
||||||
self.graph = nx.MultiDiGraph()
|
|
||||||
|
|
||||||
@staticmethod
|
class Tu :
|
||||||
def read_text_file(filename):
|
def __init__(self):
|
||||||
|
self.dict={}
|
||||||
|
self.graph=nx.MultiDiGraph()
|
||||||
|
|
||||||
|
def read_text_file(self,filename):
|
||||||
try:
|
try:
|
||||||
with open(filename, 'r', encoding="utf-8") as file:
|
with open(filename, 'r') 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)
|
||||||
|
@ -76,8 +75,8 @@ class Tu:
|
||||||
print("File not found.")
|
print("File not found.")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def generate_directed_dict(self, word_sequence):
|
def generate_directed_dict(self,word_sequence):
|
||||||
graph = self.dict
|
graph = self.dict #chunfuzhi,yiqigai
|
||||||
for i in range(len(word_sequence) - 1):
|
for i in range(len(word_sequence) - 1):
|
||||||
current_word = word_sequence[i]
|
current_word = word_sequence[i]
|
||||||
next_word = word_sequence[i + 1]
|
next_word = word_sequence[i + 1]
|
||||||
|
@ -96,7 +95,7 @@ class Tu:
|
||||||
return graph
|
return graph
|
||||||
|
|
||||||
def generate_directed_graph(self):
|
def generate_directed_graph(self):
|
||||||
G = self.graph # wufuzhi,yiqigai
|
G = self.graph #wufuzhi,yiqigai
|
||||||
graph = self.dict
|
graph = self.dict
|
||||||
# 添加节点和边
|
# 添加节点和边
|
||||||
for node, neighbors in graph.items():
|
for node, neighbors in graph.items():
|
||||||
|
@ -108,12 +107,11 @@ class Tu:
|
||||||
return G
|
return G
|
||||||
|
|
||||||
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,
|
nx.draw_networkx(G, pos, with_labels=True, node_size=1000, node_color="skyblue",edge_color="black", font_size=10, font_weight="bold",
|
||||||
node_color="skyblue", edge_color="black", font_size=10,
|
arrows=True, connectionstyle='arc3,rad=0.2')
|
||||||
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():
|
||||||
|
@ -121,11 +119,9 @@ 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]][0] + pos[edge[1]][0]) / 2 + dy * 0.1, (pos[edge[0]][1] + pos[edge[1]][1]) / 2 - dx * 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):
|
||||||
|
@ -138,15 +134,27 @@ class Tu:
|
||||||
print("No", word1, "or", word2, "in the graph!")
|
print("No", word1, "or", word2, "in the graph!")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
bridge_words = [
|
bridge_words = []
|
||||||
word for word in graph[word1]
|
bridge_words_origin = []
|
||||||
if word2 in graph.get(word, {})
|
for bridge_word in graph:
|
||||||
]
|
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
|
||||||
|
|
||||||
@staticmethod
|
def print_bridge_words(self,bridge_words,word1,word2):
|
||||||
def print_bridge_words(bridge_words, word1, word2):
|
|
||||||
|
|
||||||
if not bridge_words:
|
if not bridge_words:
|
||||||
print("No bridge words from", word1, "to", word2, "!")
|
print("No bridge words from", word1, "to", word2, "!")
|
||||||
|
@ -157,15 +165,11 @@ class Tu:
|
||||||
|
|
||||||
return bridge_words
|
return bridge_words
|
||||||
|
|
||||||
def queryBridgeWords(self, word1, word2):
|
def queryBridgeWords(self,word1, word2):
|
||||||
word1 = self.input_check(word1)
|
word1 = self.input_check(word1)
|
||||||
word2 = self.input_check(word2)
|
word2 = self.input_check(word2)
|
||||||
bridge_words = self.find_bridge_words(word1, word2)
|
bridge_words = self.find_bridge_words(word1, word2)
|
||||||
if bridge_words:
|
self.print_bridge_words(bridge_words,word1,word2)
|
||||||
self.print_bridge_words(bridge_words, word1, word2)
|
|
||||||
return bridge_words
|
|
||||||
else:
|
|
||||||
return bridge_words
|
|
||||||
|
|
||||||
def insert_bridge_words(self, text):
|
def insert_bridge_words(self, text):
|
||||||
|
|
||||||
|
@ -179,7 +183,7 @@ class Tu:
|
||||||
word2 = words[i + 1].lower()
|
word2 = words[i + 1].lower()
|
||||||
|
|
||||||
new_text.append(words[i])
|
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:
|
if len(bridge_words) > 0:
|
||||||
random_bridge_word = random.choice(bridge_words)
|
random_bridge_word = random.choice(bridge_words)
|
||||||
|
@ -189,58 +193,41 @@ class Tu:
|
||||||
|
|
||||||
return ' '.join(new_text)
|
return ' '.join(new_text)
|
||||||
|
|
||||||
def generateNewText(self, text):
|
def generateNewText(self,text):
|
||||||
|
|
||||||
(text_re, text_ren) = re.subn(r'[^a-zA-Z\n]+', ' ', text)
|
(text_re,text_ren)=re.subn(r'[^a-zA-Z\n]+', ' ', text)
|
||||||
if text_ren > 0:
|
if text_ren>0 :
|
||||||
print("There are illegal signs in your input")
|
print("There are illegal signs in your input")
|
||||||
if not text_re.islower():
|
if not text_re.islower():
|
||||||
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):
|
def find_shortest_path(self,word1, word2):
|
||||||
|
|
||||||
graph = self.graph
|
graph=self.graph
|
||||||
try:
|
try:
|
||||||
shortest_path_generator = (
|
shortest_path_generator = nx.all_shortest_paths(graph, source=word1, target=word2, weight='weight')
|
||||||
nx.all_shortest_paths(graph, source=word1, target=word2, weight='weight'))
|
shortest_length = nx.shortest_path_length(graph, source=word1, target=word2, weight='weight')
|
||||||
shortest_length = (
|
return shortest_path_generator, shortest_length
|
||||||
nx.shortest_path_length(graph, source=word1, target=word2, weight='weight'))
|
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
|
return shortest_path_generator, shortest_length
|
||||||
except nx.NetworkXNoPath:
|
except nx.NetworkXNoPath:
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
def find_shortest_path(self, word1, word2):
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
(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
|
||||||
plt.figure(figsize=(10, 6))
|
plt.figure(figsize=(10, 6))
|
||||||
|
|
||||||
# !!! HUATU ROLL YANSE
|
# !!! HUATU ROLL YANSE
|
||||||
|
|
||||||
|
|
||||||
pos = nx.spring_layout(graph)
|
pos = nx.spring_layout(graph)
|
||||||
nx.draw_networkx_nodes(graph, pos, node_size=1000, node_color="skyblue")
|
nx.draw_networkx_nodes(graph, pos, node_size=1000, node_color="skyblue")
|
||||||
nx.draw_networkx_labels(graph, pos, font_size=10, font_weight="bold")
|
nx.draw_networkx_labels(graph, pos, font_size=10, font_weight="bold")
|
||||||
|
@ -253,60 +240,42 @@ class Tu:
|
||||||
|
|
||||||
for edge in graph.edges():
|
for edge in graph.edges():
|
||||||
|
|
||||||
# print(shortest_path)
|
#print(shortest_path)
|
||||||
|
|
||||||
if (edge in zip(shortest_path[:-1], shortest_path[1:]) or
|
if edge in zip(shortest_path[:-1], shortest_path[1:]) or edge in zip(shortest_path[1:], shortest_path[:-1]):
|
||||||
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')
|
|
||||||
|
nx.draw_networkx_edges(graph, pos, edgelist=[edge], width=2.0, edge_color=num, arrows=True,arrowstyle="->",arrowsize=30
|
||||||
|
,connectionstyle='arc3,rad=0.2')
|
||||||
else:
|
else:
|
||||||
nx.draw_networkx_edges(graph, pos, edgelist=[edge], width=1.0,
|
nx.draw_networkx_edges(graph, pos, edgelist=[edge], width=1.0, edge_color="black", arrows=True,arrowstyle="->",arrowsize=30
|
||||||
edge_color="black",
|
,connectionstyle='arc3,rad=0.2')
|
||||||
arrows=True, arrowstyle="->", arrowsize=30,
|
|
||||||
connectionstyle='arc3,rad=0.2')
|
|
||||||
plt.show()
|
plt.show()
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
def calcShortestPath(self, word1, word2):
|
|
||||||
|
|
||||||
|
|
||||||
|
def calcShortestPath(self,word1, word2):
|
||||||
if word2 == "":
|
if word2 == "":
|
||||||
word1 = self.input_check(word1)
|
word1 = self.input_check(word1)
|
||||||
if word1 not in self.graph :
|
for wordtmp in self.dict :
|
||||||
print("No", word1, "or", word2, "in the graph!")
|
if wordtmp == word1 :
|
||||||
return [], 0
|
|
||||||
for wordtmp in self.dict:
|
|
||||||
if wordtmp == word1:
|
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
result=self.calc_shortest_path(word1, wordtmp)
|
self.calc_shortest_path(word1,wordtmp)
|
||||||
if result == []:
|
|
||||||
print("No path exists between", word1, "and", word2)
|
|
||||||
else:
|
|
||||||
print(result)
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if word1 not in self.graph or word2 not in self.graph:
|
|
||||||
print("No", word1, "or", word2, "in the graph!")
|
|
||||||
return [], 0
|
|
||||||
word1 = self.input_check(word1)
|
word1 = self.input_check(word1)
|
||||||
word2 = self.input_check(word2)
|
word2 = self.input_check(word2)
|
||||||
result = self.calc_shortest_path(word1, word2)
|
self.calc_shortest_path(word1,word2)
|
||||||
pass
|
pass
|
||||||
if result==[] :
|
|
||||||
print("No path exists between", word1, "and", word2)
|
|
||||||
else:
|
|
||||||
print(result)
|
|
||||||
result_len = 0 if result==[] or result is None else len(result[0])-1
|
|
||||||
return result,result_len
|
|
||||||
|
|
||||||
def calc_shortest_path_old(self, word1, word2):
|
|
||||||
|
|
||||||
shortest_path_generator, shortest_length = self.find_shortest_path_old(word1, word2)
|
def calc_shortest_path(self,word1, word2):
|
||||||
shortest_path_list = []
|
|
||||||
|
shortest_path_generator, shortest_length = self.find_shortest_path_re(word1, word2)
|
||||||
|
shortest_path_list=[]
|
||||||
|
|
||||||
for shortest_path in shortest_path_generator:
|
for shortest_path in shortest_path_generator:
|
||||||
|
|
||||||
|
@ -314,38 +283,19 @@ class Tu:
|
||||||
print("Shortest path:", '→'.join(shortest_path))
|
print("Shortest path:", '→'.join(shortest_path))
|
||||||
print("Length of shortest path:", shortest_length)
|
print("Length of shortest path:", shortest_length)
|
||||||
shortest_path_list.append(shortest_path)
|
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)
|
self.draw_shortest_path(shortest_path_list)
|
||||||
return shortest_path_list
|
|
||||||
else:
|
else:
|
||||||
return []
|
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)
|
|
||||||
return shortest_path_list
|
|
||||||
else:
|
|
||||||
return []
|
|
||||||
|
|
||||||
#print("No path exists between", word1, "and", word2)
|
|
||||||
|
|
||||||
def random_traversal(self):
|
def random_traversal(self):
|
||||||
|
|
||||||
# 用户输入文件名
|
# 用户输入文件名
|
||||||
filename = input("Enter the filename to save traversal results: ")
|
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()))
|
start_node = random.choice(list(graph.keys()))
|
||||||
visited_nodes = set()
|
visited_nodes = set()
|
||||||
visited_edges = []
|
visited_edges = []
|
||||||
|
@ -356,10 +306,10 @@ class Tu:
|
||||||
visited_nodes.add(current_node)
|
visited_nodes.add(current_node)
|
||||||
file.write(current_node + '\n')
|
file.write(current_node + '\n')
|
||||||
print(current_node)
|
print(current_node)
|
||||||
if input() == "@":
|
if input()=="@":
|
||||||
file.close()
|
file.close()
|
||||||
break
|
break
|
||||||
if graph.get(current_node) is not None:
|
if graph.get(current_node) != None:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
@ -379,21 +329,23 @@ class Tu:
|
||||||
def randomWalk(self):
|
def randomWalk(self):
|
||||||
self.random_traversal()
|
self.random_traversal()
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def input_check(input_word):
|
|
||||||
(input_word_re, input_word_ren) = re.subn(r'[^a-zA-Z\n]', ' ', input_word)
|
|
||||||
|
|
||||||
if input_word_ren > 0:
|
def input_check(self, input_word):
|
||||||
print("There are illegal signs in your input,the amount is " + str(input_word_ren))
|
(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 not input_word_re.islower():
|
if not input_word_re.islower():
|
||||||
print("There are upper characters in your input")
|
print("There are upper characters in your input")
|
||||||
tmp = input_word_re.lower().split()
|
tmp=input_word_re.lower().split()
|
||||||
if len(tmp) > 1:
|
if len(tmp)>1 :
|
||||||
print("There are more than one word in your input")
|
print("There are more than one word in your input")
|
||||||
|
|
||||||
return tmp[0]
|
return tmp[0]
|
||||||
|
|
||||||
|
|
||||||
def all_simple_paths_graph(self, source: str, targets: str) -> Generator[List[str], None, None]:
|
def all_simple_paths_graph(self, source: str, targets: str) -> Generator[List[str], None, None]:
|
||||||
G = self.graph
|
G = self.graph
|
||||||
cutoff = len(G) - 1 # 设置路径的最大深度,防止无限循环。
|
cutoff = len(G) - 1 # 设置路径的最大深度,防止无限循环。
|
||||||
|
@ -422,15 +374,13 @@ class Tu:
|
||||||
stack.pop()
|
stack.pop()
|
||||||
visited.popitem()
|
visited.popitem()
|
||||||
|
|
||||||
def calc_shortest_path_len(self, word1: str, word2: str) -> int:
|
def calc_shortest_path_len(self, word1: str, word2: str) -> str:
|
||||||
|
|
||||||
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 0
|
return ""
|
||||||
|
|
||||||
distances = {node: inf for node in self.graph.nodes}
|
distances = {node: inf for node in self.graph.nodes} # 存储word1到所有结点的距离,初始化为无穷大
|
||||||
# 存储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)] # 优先级队列,用于按照从小到大获取节点
|
||||||
|
|
||||||
|
@ -462,9 +412,9 @@ class Tu:
|
||||||
path.insert(0, current_node)
|
path.insert(0, current_node)
|
||||||
|
|
||||||
if isinf(distances[word2]): # 目标节点不可达
|
if isinf(distances[word2]): # 目标节点不可达
|
||||||
return 0
|
return ""
|
||||||
return path.__len__()
|
return path.__len__()
|
||||||
# return (' '.join(path),path.__len__())
|
return ' '.join(path)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
28
t2.txt
28
t2.txt
|
@ -1,28 +0,0 @@
|
||||||
melodiously
|
|
||||||
creating
|
|
||||||
a
|
|
||||||
small
|
|
||||||
stream
|
|
||||||
gurgled
|
|
||||||
its
|
|
||||||
waters
|
|
||||||
crystal
|
|
||||||
clear
|
|
||||||
and
|
|
||||||
refreshing
|
|
||||||
suddenly
|
|
||||||
a
|
|
||||||
deer
|
|
||||||
darted
|
|
||||||
past
|
|
||||||
startling
|
|
||||||
to
|
|
||||||
seek
|
|
||||||
out
|
|
||||||
new
|
|
||||||
worlds
|
|
||||||
and
|
|
||||||
new
|
|
||||||
life
|
|
||||||
and
|
|
||||||
worlds
|
|
34
t3.txt
34
t3.txt
|
@ -1,34 +0,0 @@
|
||||||
and
|
|
||||||
seek
|
|
||||||
out
|
|
||||||
new
|
|
||||||
life
|
|
||||||
and
|
|
||||||
refreshing
|
|
||||||
suddenly
|
|
||||||
a
|
|
||||||
symphony
|
|
||||||
of
|
|
||||||
nature
|
|
||||||
finest
|
|
||||||
sounds
|
|
||||||
amidst
|
|
||||||
the
|
|
||||||
forest
|
|
||||||
floor
|
|
||||||
birds
|
|
||||||
chirped
|
|
||||||
melodiously
|
|
||||||
creating
|
|
||||||
a
|
|
||||||
deer
|
|
||||||
darted
|
|
||||||
past
|
|
||||||
startling
|
|
||||||
to
|
|
||||||
explore
|
|
||||||
strange
|
|
||||||
new
|
|
||||||
worlds
|
|
||||||
and
|
|
||||||
worlds
|
|
24
t4.txt
24
t4.txt
|
@ -1,24 +0,0 @@
|
||||||
nature
|
|
||||||
finest
|
|
||||||
sounds
|
|
||||||
amidst
|
|
||||||
the
|
|
||||||
greenery
|
|
||||||
a
|
|
||||||
deer
|
|
||||||
darted
|
|
||||||
past
|
|
||||||
startling
|
|
||||||
to
|
|
||||||
seek
|
|
||||||
strange
|
|
||||||
new
|
|
||||||
life
|
|
||||||
and
|
|
||||||
seek
|
|
||||||
out
|
|
||||||
new
|
|
||||||
worlds
|
|
||||||
and
|
|
||||||
new
|
|
||||||
civilizations
|
|
130
test.py
130
test.py
|
@ -1,130 +0,0 @@
|
||||||
import unittest
|
|
||||||
|
|
||||||
from oop import Tu
|
|
||||||
class TextProcessor(Tu):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
class TestQueryBridgeWords(unittest.TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
# Initialize a graph for testing
|
|
||||||
self.graph = {
|
|
||||||
'a': {'b': 1, 'c': 2},
|
|
||||||
'b': {'c': 1, 'd': 2},
|
|
||||||
'c': {'d': 1},
|
|
||||||
'x': {},
|
|
||||||
'z': {}
|
|
||||||
}
|
|
||||||
self.processor = TextProcessor()
|
|
||||||
self.processor.generate_directed_dict(self.processor.read_text_file("1.txt"))
|
|
||||||
self.processor.generate_directed_graph()
|
|
||||||
def test_normal_path1(self):
|
|
||||||
# 正常情况:存在路径
|
|
||||||
word1 = 'to'
|
|
||||||
word2 = 'out'
|
|
||||||
expected_path = ['to', 'seek', 'out']
|
|
||||||
expected_length = 2
|
|
||||||
path,length = self.processor.calcShortestPath(word1, word2)
|
|
||||||
|
|
||||||
self.assertEqual(path, [expected_path])
|
|
||||||
self.assertEqual(length, expected_length)
|
|
||||||
|
|
||||||
"""def test_normal_path2(self):
|
|
||||||
# 正常情况:存在路径
|
|
||||||
word1 = 'to'
|
|
||||||
word2 = 'new'
|
|
||||||
expected_path = ['to', 'seek', 'out',"new"],['to', 'seek', "strange",'new'],['to', 'explore', "strange",'new']
|
|
||||||
expected_length = 3
|
|
||||||
path, length = self.processor.calcShortestPath(word1, word2)
|
|
||||||
path_set=set([])
|
|
||||||
for i in path :
|
|
||||||
path_set.add(i)
|
|
||||||
self.assertSetEqual(path_set, set(expected_path))
|
|
||||||
self.assertEqual(length, expected_length)"""
|
|
||||||
|
|
||||||
def test_no_path(self):
|
|
||||||
# 无路径情况
|
|
||||||
word1 = 'civilizations'
|
|
||||||
word2 = 'to'
|
|
||||||
expected_path = []
|
|
||||||
expected_length = 0
|
|
||||||
|
|
||||||
path, length = self.processor.calcShortestPath(word1, word2)
|
|
||||||
self.assertEqual(path, expected_path)
|
|
||||||
self.assertEqual(length, expected_length)
|
|
||||||
|
|
||||||
def test_node_not_exists(self):
|
|
||||||
# 节点不存在情况
|
|
||||||
word1 = 'now'
|
|
||||||
word2 = 'lod'
|
|
||||||
expected_path = []
|
|
||||||
expected_length = 0
|
|
||||||
|
|
||||||
path, length = self.processor.calcShortestPath(word1, word2)
|
|
||||||
self.assertEqual(path, expected_path)
|
|
||||||
self.assertEqual(length, expected_length)
|
|
||||||
|
|
||||||
def test_same_node(self):
|
|
||||||
# 同一节点情况
|
|
||||||
word1 = 'to'
|
|
||||||
word2 = 'to'
|
|
||||||
expected_path = []
|
|
||||||
expected_length = 0
|
|
||||||
|
|
||||||
path, length = self.processor.calcShortestPath(word1, word2)
|
|
||||||
self.assertEqual(path, expected_path)
|
|
||||||
self.assertEqual(length, expected_length)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_valid_bridge_words_exist(self):
|
|
||||||
# Valid equivalence class: bridge words exist
|
|
||||||
result = self.processor.queryBridgeWords('the', 'floor')
|
|
||||||
self.assertIn('forest', result)
|
|
||||||
|
|
||||||
def test_valid_bridge_words_not_exist(self):
|
|
||||||
# Valid equivalence class: no bridge words
|
|
||||||
result = self.processor.queryBridgeWords('on', 'the')
|
|
||||||
self.assertEqual(result, [])
|
|
||||||
|
|
||||||
def test_invalid_word1_not_in_graph(self):
|
|
||||||
# Invalid equivalence class: word1 not in graph
|
|
||||||
result = self.processor.queryBridgeWords('an', 'a')
|
|
||||||
self.assertEqual(result, [])
|
|
||||||
|
|
||||||
def test_invalid_word2_not_in_graph(self):
|
|
||||||
# Invalid equivalence class: word2 not in graph
|
|
||||||
result = self.processor.queryBridgeWords('a', 'an')
|
|
||||||
self.assertEqual(result, [])
|
|
||||||
|
|
||||||
def test_invalid_both_words_not_in_graph(self):
|
|
||||||
# Invalid equivalence class: both words not in graph
|
|
||||||
result = self.processor.queryBridgeWords('now', 'lod')
|
|
||||||
self.assertEqual(result, [])
|
|
||||||
|
|
||||||
def test_edge_case_min_word(self):
|
|
||||||
# Edge case: minimum word
|
|
||||||
result = self.processor.queryBridgeWords('a', 'b')
|
|
||||||
self.assertEqual(result, [])
|
|
||||||
|
|
||||||
def test_edge_case_max_word(self):
|
|
||||||
# Edge case: maximum word
|
|
||||||
result = self.processor.queryBridgeWords('x', 'z')
|
|
||||||
self.assertEqual(result, [])
|
|
||||||
|
|
||||||
def test_edge_case_no_bridge_words(self):
|
|
||||||
# Edge case: no bridge words
|
|
||||||
result = self.processor.queryBridgeWords('new', 'worlds')
|
|
||||||
self.assertEqual(result, [])
|
|
||||||
|
|
||||||
def test_edge_case_single_bridge_word(self):
|
|
||||||
# Edge case: single bridge word
|
|
||||||
result = self.processor.queryBridgeWords('the', 'floor')
|
|
||||||
self.assertIn('forest', result)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.main()
|
|
Loading…
Reference in New Issue