人工智能原理实验2(2)——罗马尼亚问题(贪婪搜索、A*搜索、BFS、DFS)

🧡🧡实验内容🧡🧡

在这里插入图片描述
根据上图以Zerind为初始状态,Bucharest为目标状态实现搜索,分别以贪婪搜索(只考虑直线距离)和A算法求解最短路径。 按顺序列出贪婪算法探索的扩展节点和其估价函数值,A算法探索的扩展节点和其估计值。

🧡🧡相关数据结构定义🧡🧡

状态表示的数据结构

每个城市代表一个状态,每个状态的属性主要包括:

  • 当前城市可从哪里来
  • 从起点到当前城市总花费的实际代价(代价函数g(x)
  • 当前城市到终点的直线距离(启发函数h(x)
    -在这里插入图片描述

状态扩展规则的表示

定义实际距离
主要是根据设定好的字典类型的变量,选择下一个城市,如下,例如Arad城市可以到达Zerind、Sibiu、Timisoara,后面数值为Arad到达它们的实际路程(也即图中线段上的数值)。
在这里插入图片描述
在这里插入图片描述

定义理想直线距离
直接用字典表示即可
在这里插入图片描述在这里插入图片描述

🧡🧡贪婪搜索求解🧡🧡

思想

首先了解估价函数f (x)=g(x)+h(x) 中,

  • f(x)为估价函数
  • g(x)为代价函数,代表从起点到当前x点的所花费的代价(距离)
  • h(x)为启发函数,代表当前x点到终点的估计代价(距离)
    当 不采用h(x)即g(x)=0时,f(x)=h(x),此时搜索为贪婪搜索,即每一次扩展均选择与终点离得最近(本题中h(x)为两城市的直线理想距离,而非线段上的真实距离)的城市

代码

# 贪婪搜索
import queue

class GBFS:
    def __init__(self, graph, heuristic, start, goal):
        self.graph = graph # 图
        self.heuristic = heuristic # 启发函数hn
        self.start = start # 起点
        self.goal = goal # 终点
        self.came_from = {} # 记录每个城市可以从哪里来(父节点)
        self.cost_so_far = {} # 从起点到该点总共花费的实际代价
        
    # 输出路径 和 对应的估计函数值
    def __show_path(self):
        current = self.goal
        path = [current] # 先导入终点city
        while current != self.start:  # 从终点回溯到起点city,加入所经city
            current = self.came_from[current]
            path.append(current)
        path = path[::-1]
        
        for i in range(len(path)-1):
            #\033[1;91m.....\033[0m为红色加粗的ANSI转义码
            print(f"=====================↓↓↓cur city: \033[1;91m{path[i]}\033[0m↓↓↓=====================") 
            for can_to_city in self.graph[path[i]].keys():
                print(f"can_to_city: \033[94m{can_to_city}\033[0m\t\t fn=\033[1;93m{self.heuristic[can_to_city]}\033[0m")
            print(f"选择fn最小的city: \033[1;92m{path[i+1]}\033[0m\n")
            
    
    def solve(self):
        frontier = queue.PriorityQueue()
        frontier.put((0, self.start)) # 将起点优先级设置为0,越小越优先
        self.came_from[self.start] = None # 父节点
        self.cost_so_far[self.start] = 0 # 从起点到cur city总共花费的fn
        close_=[]
        open_=[self.start]
        while not frontier.empty():

            current = frontier.get()[1]
            # 打印open_和close_表
#             print(f"open: {open_}  \nclose: {close_} \n")
#             open_.extend(list(self.graph[current].keys()))
#             open_.remove(current)
#             close_.append(current)
            
            if current == self.goal:
                self.__show_path()
                break

            for next in self.graph[current]: # 遍历current city 的next city
                new_cost = self.cost_so_far[current] + self.heuristic[next]
                if next not in self.cost_so_far or new_cost < self.cost_so_far[next]:
                    self.cost_so_far[next] = new_cost
                    priority = new_cost
                    frontier.put((priority, next))
                    self.came_from[next] = current


# 定义罗马尼亚地图
graph = {
    'Arad': {'Zerind': 75, 'Sibiu': 140, 'Timisoara': 118},
    'Zerind': {'Arad': 75, 'Oradea': 71},
    'Sibiu': {'Arad': 140, 'Oradea': 151, 'Fagaras': 99, 'Rimnicu Vilcea': 80},
    'Timisoara': {'Arad': 118, 'Lugoj': 111},
    'Oradea': {'Zerind': 71, 'Sibiu': 151},
    'Fagaras': {'Sibiu': 99, 'Bucharest': 211},
    'Rimnicu Vilcea': {'Sibiu': 80, 'Pitesti': 97, 'Craiova': 146},
    'Lugoj': {'Timisoara': 111, 'Mehadia': 70},
    'Mehadia': {'Lugoj': 70, 'Drobeta': 75},
    'Drobeta': {'Mehadia': 75, 'Craiova': 120},
    'Craiova': {'Drobeta': 120, 'Rimnicu Vilcea': 146, 'Pitesti': 138},
    'Pitesti': {'Rimnicu Vilcea': 97, 'Craiova': 138, 'Bucharest': 101},
    'Bucharest': {'Fagaras': 211, 'Pitesti': 101, 'Giurgiu': 90, 'Urziceni': 85},
    'Giurgiu': {'Bucharest': 90},
    'Urziceni': {'Bucharest': 85, 'Hirsova': 98, 'Vaslui': 142},
    'Hirsova': {'Urziceni': 98, 'Eforie': 86},
    'Eforie': {'Hirsova': 86},
    'Vaslui': {'Urziceni': 142, 'Iasi': 92},
    'Iasi': {'Vaslui': 92, 'Neamt': 87},
    'Neamt': {'Iasi': 87}
}

#  各城市到终点B的直线距离
heuristic = {
    'Arad': 366,
    'Zerind': 374,
    'Sibiu': 253,
    'Timisoara': 329,
    'Oradea': 380,
    'Fagaras': 176,
    'Rimnicu Vilcea': 193,
    'Lugoj': 244,
    'Mehadia': 241,
    'Drobeta': 242,
    'Craiova': 160,
    'Pitesti': 100,
    'Bucharest': 0,
    'Giurgiu': 77,
    'Urziceni': 80,
    'Hirsova': 151,
    'Eforie': 161,
    'Vaslui': 199,
    'Iasi': 226,
    'Neamt': 234
}

start = 'Zerind'
goal = 'Bucharest'

gbfs = GBFS(graph, heuristic, start, goal)
gbfs.solve()


运行结果

在这里插入图片描述
每次均选择h(x)(理想直线距离)小的城市,最终得出通过贪婪搜索算法搜出的最短路径为Zerind–>Arad–>Sibiu–>Fagaras

🧡🧡A*搜索求解🧡🧡

思想

估价函数:f(x) = g(x) + h(x)
即每一次扩展时,除了考虑选择离终点最近(直线距离h(x))的城市外,还考虑从起点城市到当前城市的实际距离(路段的真实权值g(x))

代码

# A*
import queue

class A_search:
    def __init__(self, graph, heuristic, start, goal):
        self.graph = graph # 图
        self.heuristic = heuristic # 启发函数hn
        self.start = start # 起点
        self.goal = goal # 终点
        self.came_from = {} # 记录每个城市可以从哪里来(父节点)
        self.cost_so_far = {} # 从起点到该点总共花费的实际代价

    # 输出路径 和 对应的估计函数值
    def __show_path(self):
        current = self.goal
        path = [current] # 先导入终点city
        while current != self.start:  # 从终点回溯到起点city,加入所经city
            current = self.came_from[current]
            path.append(current)
        path = path[::-1]
        
        for i in range(len(path)-1):
            #\033[1;91m.....\033[0m为红色加粗的ANSI转义码
            print(f"=====================↓↓↓cur city: \033[1;91m{path[i]}\033[0m↓↓↓=====================") 
            for can_to_city,cost in self.graph[path[i]].items():
                gn=self.cost_so_far[path[i]]  # 起点到cur city的实际代价
                c=cost  # cur city到next city的路途权值
                hn=self.heuristic[can_to_city] # next city到终点的直线距离
                fn=gn+c+hn
                print(f"can_to_city: \033[94m{can_to_city}\033[0m\t\t fn={gn}+{c}+{hn}=\033[1;93m{fn}\033[0m")
            print(f"选择fn最小的city: \033[1;92m{path[i+1]}\033[0m\n")
    
    def solve(self):
        frontier = queue.PriorityQueue()
        frontier.put((0, self.start)) # 将起点优先级设置为0,越小越优先
        self.came_from[self.start] = None # 父节点
        self.cost_so_far[self.start] = 0 # 从起点到该点总共花费的fn
        close_=[]
        open_=[self.start]
        while not frontier.empty():
            current = frontier.get()[1]
            # 打印open_和close_表
#             print(f"open: {open_}  \nclose: {close_} \n")
#             open_.extend(list(self.graph[current].keys()))
#             open_.remove(current)
#             close_.append(current)

            if current == self.goal:
                self.__show_path()
                break

            for next in self.graph[current]: # 遍历current city 的next city
                new_cost = self.cost_so_far[current] + self.graph[current][next] # 实际代价
                if next not in self.cost_so_far or new_cost < self.cost_so_far[next]:
                    self.cost_so_far[next] = new_cost
                    priority = new_cost + self.heuristic[next]  # 修改优先级为实际代价加上启发式函数值
                    frontier.put((priority, next))
                    self.came_from[next] = current


# 定义罗马尼亚地图
graph = {
    'Arad': {'Zerind': 75, 'Sibiu': 140, 'Timisoara': 118},
    'Zerind': {'Arad': 75, 'Oradea': 71},
    'Sibiu': {'Arad': 140, 'Oradea': 151, 'Fagaras': 99, 'Rimnicu Vilcea': 80},
    'Timisoara': {'Arad': 118, 'Lugoj': 111},
    'Oradea': {'Zerind': 71, 'Sibiu': 151},
    'Fagaras': {'Sibiu': 99, 'Bucharest': 211},
    'Rimnicu Vilcea': {'Sibiu': 80, 'Pitesti': 97, 'Craiova': 146},
    'Lugoj': {'Timisoara': 111, 'Mehadia': 70},
    'Mehadia': {'Lugoj': 70, 'Drobeta': 75},
    'Drobeta': {'Mehadia': 75, 'Craiova': 120},
    'Craiova': {'Drobeta': 120, 'Rimnicu Vilcea': 146, 'Pitesti': 138},
    'Pitesti': {'Rimnicu Vilcea': 97, 'Craiova': 138, 'Bucharest': 101},
    'Bucharest': {'Fagaras': 211, 'Pitesti': 101, 'Giurgiu': 90, 'Urziceni': 85},
    'Giurgiu': {'Bucharest': 90},
    'Urziceni': {'Bucharest': 85, 'Hirsova': 98, 'Vaslui': 142},
    'Hirsova': {'Urziceni': 98, 'Eforie': 86},
    'Eforie': {'Hirsova': 86},
    'Vaslui': {'Urziceni': 142, 'Iasi': 92},
    'Iasi': {'Vaslui': 92, 'Neamt': 87},
    'Neamt': {'Iasi': 87}
}

#  各城市到终点B的直线距离
heuristic = {
    'Arad': 366,
    'Zerind': 374,
    'Sibiu': 253,
    'Timisoara': 329,
    'Oradea': 380,
    'Fagaras': 176,
    'Rimnicu Vilcea': 192,
    'Lugoj': 244,
    'Mehadia': 241,
    'Drobeta': 242,
    'Craiova': 160,
    'Pitesti': 100,
    'Bucharest': 0,
    'Giurgiu': 77,
    'Urziceni': 80,
    'Hirsova': 151,
    'Eforie': 161,
    'Vaslui': 199,
    'Iasi': 226,
    'Neamt': 234
}

start = 'Zerind'
goal = 'Bucharest'

a = A_search(graph, heuristic, start, goal)
a.solve()

运行结果

在这里插入图片描述
每次考虑已花费的代价g和未来的估计代价h
解释一下 f 的计算
当前城市为Zerind时,到达Arad的估价代价f(Arad)=g(Arad)+h(Arad),而其中g(Arad)=g(Zerind)+cost(Zerind,Arad),因此f(Arad)=g(Zerind)+cost(Zerind,Arad)+h(Arad),又因为是起点,所以g(Zerind)为0。其中:g(Zerind)为到达Zerind已经走过的距离,cost(Zerind,Arad)为图中线段权值,即Zerind到Arad的实际距离,h(Arad)为Arad到终点的理想直线距离(上面的路径图中右侧的表格),同理对于城市Oradea也是一样的计算。
当前城市为Arad时,这里没有设置close表,因此它仍然可以选择返回到Zerind,这时由城市Arad到达Zerind城市的估计代价为 f(Zerind)=g(Zerind)+h(Zerind)=g(Arad)+cost(Arad,Zerind)+h(Zerind)。其他同理。

🧡🧡BFS、DFS求解🧡🧡

原理不多赘述了,直接上代码

BFS

# bfs
import queue

class BreadthFirstSearch:
    def __init__(self, graph, start, goal):
        self.graph = graph
        self.start = start
        self.goal = goal
        self.came_from = {}
    
    def __show_path(self):
        current = self.goal
        path = [current]
        while current != self.start:
            current = self.came_from[current]
            path.append(current)
        path = path[::-1]
        print("Path: ", " -> ".join(path))
    
    def solve(self):
        frontier = queue.Queue()
        frontier.put(self.start)
        self.came_from[self.start] = None
        
        while not frontier.empty():
            current = frontier.get()
            
            if current == self.goal:
                self.__show_path()
                break
            
            for next in self.graph[current]:
                if next not in self.came_from:
                    frontier.put(next)
                    self.came_from[next] = current


# 定义罗马尼亚地图
graph = {
    'Arad': {'Zerind': 75, 'Sibiu': 140, 'Timisoara': 118},
    'Zerind': {'Arad': 75, 'Oradea': 71},
    'Sibiu': {'Arad': 140, 'Oradea': 151, 'Fagaras': 99, 'Rimnicu Vilcea': 80},
    'Timisoara': {'Arad': 118, 'Lugoj': 111},
    'Oradea': {'Zerind': 71, 'Sibiu': 151},
    'Fagaras': {'Sibiu': 99, 'Bucharest': 211},
    'Rimnicu Vilcea': {'Sibiu': 80, 'Pitesti': 97, 'Craiova': 146},
    'Lugoj': {'Timisoara': 111, 'Mehadia': 70},
    'Mehadia': {'Lugoj': 70, 'Drobeta': 75},
    'Drobeta': {'Mehadia': 75, 'Craiova': 120},
    'Craiova': {'Drobeta': 120, 'Rimnicu Vilcea': 146, 'Pitesti': 138},
    'Pitesti': {'Rimnicu Vilcea': 97, 'Craiova': 138, 'Bucharest': 101},
    'Bucharest': {'Fagaras': 211, 'Pitesti': 101, 'Giurgiu': 90, 'Urziceni': 85},
    'Giurgiu': {'Bucharest': 90},
    'Urziceni': {'Bucharest': 85, 'Hirsova': 98, 'Vaslui': 142},
    'Hirsova': {'Urziceni': 98, 'Eforie': 86},
    'Eforie': {'Hirsova': 86},
    'Vaslui': {'Urziceni': 142, 'Iasi': 92},
    'Iasi': {'Vaslui': 92, 'Neamt': 87},
    'Neamt': {'Iasi': 87}
}

start = 'Zerind'
goal = 'Bucharest'

bfs = BreadthFirstSearch(graph, start, goal)
bfs.solve()

DFS

# dfs
class DepthFirstSearch:
    def __init__(self, graph, start, goal):
        self.graph = graph
        self.start = start
        self.goal = goal
        self.came_from = {}
    
    def __dfs(self, current):
        if current == self.goal:
            return [current]
        
        for next in self.graph[current]:
            if next not in self.came_from:
                self.came_from[next] = current
                path = self.__dfs(next)
                if path:
                    return [current] + path
        
        return None
    
    def __show_path(self, path):
        path = path[::-1]
        print("Path: ", " -> ".join(path))
    
    def solve(self):
        self.came_from[self.start] = None
        path = self.__dfs(self.start)
        if path:
            self.__show_path(path)
#         else:
#             print("No path found.")


# 定义罗马尼亚地图
graph = {
    'Arad': {'Zerind': 75, 'Sibiu': 140, 'Timisoara': 118},
    'Zerind': {'Arad': 75, 'Oradea': 71},
    'Sibiu': {'Arad': 140, 'Oradea': 151, 'Fagaras': 99, 'Rimnicu Vilcea': 80},
    'Timisoara': {'Arad': 118, 'Lugoj': 111},
    'Oradea': {'Zerind': 71, 'Sibiu': 151},
    'Fagaras': {'Sibiu': 99, 'Bucharest': 211},
    'Rimnicu Vilcea': {'Sibiu': 80, 'Pitesti': 97, 'Craiova': 146},
    'Lugoj': {'Timisoara': 111, 'Mehadia': 70},
    'Mehadia': {'Lugoj': 70, 'Drobeta': 75},
    'Drobeta': {'Mehadia': 75, 'Craiova': 120},
    'Craiova': {'Drobeta': 120, 'Rimnicu Vilcea': 146, 'Pitesti': 138},
    'Pitesti': {'Rimnicu Vilcea': 97, 'Craiova': 138, 'Bucharest': 101},
    'Bucharest': {'Fagaras': 211, 'Pitesti': 101, 'Giurgiu': 90, 'Urziceni': 85},
    'Giurgiu': {'Bucharest': 90},
    'Urziceni': {'Bucharest': 85, 'Hirsova': 98, 'Vaslui': 142},
    'Hirsova': {'Urziceni': 98, 'Eforie': 86},
    'Eforie': {'Hirsova': 86},
    'Vaslui': {'Urziceni': 142, 'Iasi': 92},
    'Iasi': {'Vaslui': 92, 'Neamt': 87},
    'Neamt': {'Iasi': 87}
}

start = 'Zerind'
goal = 'Bucharest'

dfs = DepthFirstSearch(graph, start, goal)
dfs.solve()

🧡🧡总结🧡🧡

比较运行效率

# cal_time
import time
import matplotlib.pyplot as plt
solve_list=['bfs','dfs','gbfs','a']
run_n=10000
show_time=[]
for solve in solve_list:
    cost_times=[]
    for i in range(run_n):
        start_time=time.time()
        globals()[solve].solve()
        end_time=time.time()
        cost_times.append(end_time - start_time)
    show_time.append(sum(cost_times)*1000/run_n)
    print(f"{solve} 算法的平均运行时间:{sum(cost_times)*1000/run_n} ms")
    

plt.bar(solve_list,show_time)

将程序运行10000次,统计BFS、DFS、贪婪算法、A*算法的平均运行时间如下:可以看见dfs在问题规模一般的情况的下效率非常高。
在这里插入图片描述

扩展思考:设计一个新的启发式函数,并分析该函数的可采纳性和优势(与启发式函数定义为“Zerind到Bucharest的直线距离”相比较)。
假设我们知道每个城市的人口数量,我们可以设计一个启发式函数,该函数将当前节点到目标节点的直线距离与两个城市的人口数量之比作为启发式值。即:fn = 当前节点和目标节点的人口数量之和/目标节点到当前节点的直线距离。

  • 可采纳性:这个启发式函数的可采纳性取决于实际问题的特征。如果人口密度对路径规划有重要影响,那么这个启发式函数是可采纳的。例如,人口密度可能会影响交通拥堵程度,从而影响出现体验。
  • 优势:与简单的直线距离相比,考虑人口数量可以使得搜索算法更倾向于经过人口稀疏的地区,从而在某些情况下找到更符合实际的路径。例如,如果把油费、乘车体验等等也作为路径选择的依据,那么可以避开人口密集的区域以减少交通拥堵,从而能更快更舒适地到达目的地点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/337676.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

两个bbox的IoU计算步骤分析

IoU&#xff1a;交并比&#xff0c;数值上等于交集面积除以并集面积。 两个bbox的位置关系无外乎以上三种情况&#xff1a;&#xff08;1&#xff09;部分相交。&#xff08;2&#xff09;不相交。&#xff08;3&#xff09;包含。 计算步骤&#xff1a; 计算交集&#xff08…

亚像素边缘检测——基于模糊边缘模型的亚像素圆检测方法

论文&#xff1a;A Novel Subpixel Circle Detection Method Based on the Blurred Edge Model 期刊&#xff1a;IEEE Transactions on Instrumentation and Measurement, 71:1-11, 2021. 作者&#xff1a;Weihua Liu, Xianqiang Yang, Xuebo Yang, Hao Sun, Xinghu Yu, Huij…

【实战】SpringBoot自定义 starter及使用

文章目录 前言技术积累SpringBoot starter简介starter的开发步骤 实战演示自定义starter的使用写在最后 前言 各位大佬在使用springboot或者springcloud的时候都会根据需求引入各种starter&#xff0c;比如gateway、feign、web、test等等的插件。当然&#xff0c;在实际的业务…

Find My卡片正成为消费电子香饽饽,伦茨科技ST17H6x可以帮到您

今年CES许多公司发布支持苹果Find My的卡片产品&#xff0c;这种产品轻薄可充电&#xff0c;放在钱包、背包或者手提包可以防丢查找&#xff0c;在智能化加持下&#xff0c;防丢卡片使得人们日益关心自行车的去向。最新的防丢卡片与苹果Find My结合&#xff0c;智能防丢&#x…

AI绘画Stable Diffusion进阶使用

本文讲解&#xff0c;模型底模&#xff0c;VAE美化模型&#xff0c;Lora模型&#xff0c;hypernetwork。 文本Stable Diffusion 简称sd 欢迎关注 使用模型 C站&#xff1a;https://civitai.com/ huggingface&#xff1a;https://huggingface.co/models?pipeline_tagtext-to-…

单体架构、微服务和无服务器架构

前言 在这篇文章中&#xff0c;我将演示在决定使用单体架构、微服务架构和无服务器架构时的权衡的简化心智模型。目标是突显每种风格的固有优势和缺陷&#xff0c;并提供关于何时选择哪种架构风格的指导。 单体架构 对于小团队或项目来说是理想的入门架构。它简单易上手&…

hot100:07接雨水

题目链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 算法思想&#xff1a; 这里采取的是暴力解法和双指针的解法&#xff0c;但是这个题目还有其他的两种解法&#xff08;单调栈和动态规划&#xff0c;同学可以自行了解&#xff…

万界星空科技mes系统可以为企业带来什么好处

随着信息技术的不断发展&#xff0c;MES生产制造系统的作用不断凸显。万界星空科技MES生产制造可以为企业带来四个方面的好处&#xff1a;提升生产效率、降低生产成本、优化生产过程、提高生产质量。本文将从这四个方面分别进行详细阐述&#xff0c;旨在通过对MES生产制造系统的…

2024最新 8 款电脑数据恢复软件推荐分享

数据恢复是一个涉及从设备硬盘驱动器检索已删除文件的过程。这可能需要存储在工作站、笔记本电脑、移动设备、服务器、相机、闪存驱动器上的数据——任何在独立或镜像/阵列驱动器上存储数据的东西&#xff0c;无论是内部还是外部。 在某些情况下&#xff0c;文件可能被意外或故…

[安全警报] Npm木马利用“Oscompatible“包悄然安装AnyDesk

最近&#xff0c;一个名为OsCompatible的恶意包被上传到npm 。该包被发现包含一个针对 Windows 的远程访问木马。 这个名为OsCompatible的软件包于2024年1月9日发布&#xff0c;在被撤下之前共吸引了380次下载。 据了解&#xff0c;OsCompatible包含“几个奇怪的二进制文件”…

力扣hot100 反转链表 指针 递归 一题多解

Problem: 206. 反转链表 文章目录 思路&#x1f496; 迭代 双指针&#x1f496; 递归 思路 &#x1f468;‍&#x1f3eb; 大佬题解 &#x1f496; 迭代 双指针 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( 1 ) O(1) O(1) /*** Definition for …

【llm 微调code-llama 训练自己的数据集 一个小案例】

这也是一个通用的方案&#xff0c;使用peft微调LLM。 准备自己的数据集 根据情况改就行了&#xff0c;jsonl格式&#xff0c;三个字段&#xff1a;context, answer, question import pandas as pd import random import jsondata pd.read_csv(dataset.csv) train_data data…

安装MySQL8.0

安装MySQL8.0 第一步我们先把MySQL8.0的镜像拉一下&#xff08;建议在网络好的情况下 下拉镜像&#xff09; 之后我们在创造一个容器 conf目录 必须提前上传my.cnf文件到/data/conf目录 并且它与window中的配置文件my.ini后缀名是不一样 data目录 数据保存到宿主机中&#x…

Centos7 如何设置开机启动某个程序

以设置自动启动sentinel-dashboard作为案例 要在CentOS 7上设置开机启动一个Java程序&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1. 进入应用程序的目录 cd /usr/localvim sentinel-dashboard.sh 2. 在sentinel-dashboard.sh 文件中 输入启动脚本 nohup java -D…

ORB-SLAM策略思考之优化器策略

ORB-SLAM策略思考之优化器策略 1 跟踪线程中的优化策略 地图初始化阶段&#xff1a;BA优化&#xff08;初始化帧位姿固定&#xff0c;优化地图点位姿和第二帧位姿&#xff09; 当ORB-SLAM判断地图初始化的地图点足以进入地图点位置和第二帧位姿优化阶段时&#xff0c;以初始化…

如何使用GPU租用平台AutoDL

AutoDL算力云 | 弹性、好用、省钱。租GPU就上AutoDL 1.价格 截取的部分&#xff0c;价格可以说是非常的优惠了&#xff0c;比其他很多平台都要低&#xff0c;如果是学生党还可以享受到会员价格 2.申请学生认证 只需要有在学校申请的邮箱即可 3.租用GPU 点击右上角控制台 点击…

【网络安全】【密码学】【北京航空航天大学】实验五、古典密码(中)【C语言实现】

实验五、古典密码&#xff08;中&#xff09; 实验目的和原理简介参见博客&#xff1a;古典密码&#xff08;上&#xff09; 一、实验内容 1、弗纳姆密码&#xff08;Vernam Cipher&#xff09; &#xff08;1&#xff09;、算法原理 加密原理&#xff1a; 加密过程可以用…

多线程-Thread类及常见方法

目录 1.什么是Thread类 1.1Thread 的常⻅构造⽅法 1.2 Thread 的⼏个常⻅属性 2.启动⼀个线程 - start() 经典面试题&#xff1a;start 和run 区别 3.中断⼀个线程 方法一&#xff1a; 方法二: 4.等待⼀个线程 - join() 5. 获取当前线程引用 方法一&#xff1a; 方法二…

【Linux】—— 命名管道详解

命名管道是一种在操作系统中用于进程间通信的机制&#xff0c;它允许不同的进程之间通过管道进行数据交换。与匿名管道相比&#xff0c;命名管道具有更多的灵活性和功能。在本博客中&#xff0c;我们将深入探讨命名管道的概念、用途以及如何在编程中使用它们。 目录 &#xff…

多线程(看这一篇就够了,超详细,满满的干货)

多线程 一.认识线程&#xff08;Thread&#xff09;1. 1) 线程是什么1. 2) 为啥要有线程1.3) 进程和线程的区别标题1.4) Java的线程和操作系统线程的关系 二.创建线程方法1:继承Thread类方法2:实现Runnable接口方法3:匿名内部类创建Thread子类对象标题方法4:匿名内部类创建Runn…