基于A*的网格地图最短路径问题求解

基于A*的网格地图最短路径问题求解

  • 一、A*算法介绍、原理及步骤
  • 二、Dijkstra算法和A*的区别
  • 三、A*算法应用场景
  • 四、启发函数
  • 五、距离
  • 六、基于A*的网格地图最短路径问题求解
    • 实例分析
    • 完整代码
  • 七、A*算法的改进思路

一、A*算法介绍、原理及步骤

A*搜索算法(A star algorithm)是用于寻路和图遍历的最佳和流行的技术之一。A*搜索算法,不像其他传统算法,它有“大脑”,是一个真正的智能算法将它与其他传统算法区分开来,A*算法作为Dijkstra算法和BFS的结合算法,其与这两种算法的区别就是采用了启发函数,这也是这个算法的核心。

许多游戏和基于web的地图都使用这种算法来非常有效地找到最短路径(近似)。为了在现实生活中接近最短路径,比如在地图中,有很多障碍的游戏中。我们可以考虑一个有几个障碍的二维网格,我们从一个起点(下图红色)开始,寻找到达终点(下图绿色)的最短路径问题。

A*算法思想:
A*搜索算法所做的是,从起点开始,根据一个值 f f f选择下一步移动的网格, f = g + h f=g+h f=g+h。在每一步中,它选择具有最低 f f f的节点进行处理。
其中:

  • g g g为从起始点移动到给定方格的移动成本
  • h h h为从给定方格移动到最终目的地的估计移动成本,通常被称为启发式函数,是一种猜测或者估算。在找到路径之前,不可能知道实际的距离,因为各种各样的东西都可能挡在路上(墙壁、水等)。计算 h h h的方法有很多。

算法步骤如下:
输入:图,起点 src \text{src} src,终点 tgt \text{tgt} tgt, 每个点的父节点 node_parent \text{node\_parent} node_parent用于保存最有路径。
输出:起点到终点的最短路径。
step1. \text{step1.} step1. 初始化open listclosed list,将起点加入open list,并设置优先级为0(优先级最高)。【注】open list可以是一个优先队列。
step2. \text{step2.} step2. while open list is not empty: \text {while open list is not empty}: while open list is not empty
    a)查找open list中 f f f值最小的节点,把它作为当前要处理的节点cur_node,将cur_node从open list中删除。
    b) if cur_node == tgt \text {if cur\_node == tgt} if cur_node == tgt,跳出 while \text {while} while循环,停止搜索
    c) else: \text {else:} else:
        i)获取 cur_node \text{cur\_node} cur_node的相邻8个方格 successors \text{successors} successors
        ii)将 cur_node \text{cur\_node} cur_node加入 close list \text{close list} close list
        iii)遍历 successors \text{successors} successors,对于每个 successor \text{successor} successor
            1)若 successor \text{successor} successor在close list中,跳过本次循环(continue)
            2)若 successor \text{successor} successor不在open list中,计算 successor \text{successor} successor的g、h和f值。
                ① succesor.g=cur_node.g+cur_node \text{succesor.g=cur\_node.g+cur\_node} succesor.g=cur_node.g+cur_node successor \text{successor} successor的欧几里得距离;
                ② succesor.h \text{succesor.h} succesor.h=从 successor \text{successor} successor到终点的曼哈顿距离。
                ③ succesor.f=succesor.g+succesor.h。 \text{succesor.f=succesor.g+succesor.h。} succesor.f=succesor.g+succesor.h
                ④ 将 succesor \text{succesor} succesor加入 open list \text{open list} open list
            3)若 successor \text{successor} successor在open list中,判断从 cur_node \text{cur\_node} cur_node到successor的距离是否>succesor.g,若是则
                ① succersor.g=cur_node.g; \text{succersor.g=cur\_node.g;} succersor.g=cur_node.g;
                ② succesor.f=succesor.g + succesor.h; \text{succesor.f=succesor.g + succesor.h;} succesor.f=succesor.g + succesor.h;
                ③ node_parent[neighbor] = node \text{node\_parent[neighbor] = node} node_parent[neighbor] = node

二、Dijkstra算法和A*的区别

  1. Dijkstra算法计算源点到其他所有点的最短路径长度,A*关注点到点的最短路径(包括具体路径)。
  2. A*可以轻松地用在比如无人机航路规划、游戏地图寻路中(grid),而Dijkstra建立在较为抽象的图论层面(graph)。
  3. Dijkstra算法的实质是广度优先搜索,是一种发散式的搜索,所以空间复杂度和时间复杂度都比较高。对路径上的当前点,A*算法不但记录其到源点的代价,还计算当前点到目标点的期望代价,是一种启发式算法,也可以认为是一种深度优先的算法。
  4. 由第一点,当目标点很多时,A*算法会带入大量重复数据和复杂的估价函数,所以如果不要求获得具体路径而只比较路径长度时,Dijkstra算法会成为更好的选择。

三、A*算法应用场景

What if the search space is not a grid and is a graph ?
The same rules applies there also. The example of grid is taken for the simplicity of understanding. So we can find the shortest path between the source node and the target node in a graph using this A* Search Algorithm, just like we did for a 2D Grid.

应该使用哪种算法在图上查找路径?
1.如果要查找从所有位置起始或到所有位置的路径,使用广度优先搜索或Dijkstra算法。如果移动成本相同,使用广度优先搜索;如果移动成本不同,使用Dijkstra算法。
2.如果想找到通往一个位置或几个目标中最接近的位置的路径,使用Greedy Best First Search或A*。大多数情况下选择A*。当使用贪婪最佳优先搜索时,可以考虑使用带有“不可接受”启发式的A*。

图形搜索算法可以用于任何类型的图。图上的移动成本变成在图边上的权重。启发式距离不容易转化到不同的图中,必须为每种类型的图设计一个启发式距离。

四、启发函数

上面已经提到,启发函数h(n)会影响A算法的行为。在极端情况下,当启发函数h(n)始终为0,则将由g(n)决定节点的优先级,此时算法就退化成了Dijkstra算法。如果h(n)始终小于等于节点n到终点的代价,则A算法保证一定能够找到最短路径。但是当h(n)的值越小,算法将遍历越多的节点,也就导致算法越慢。如果h(n)完全等于节点n到终点的代价,则A算法将找到最佳路径,并且速度很快。可惜的是,并非所有场景下都能做到这一点。因为在没有达到终点之前,我们很难确切算出距离终点还有多远。
如果h(n)的值比节点n到终点的代价要大,则A
算法不能保证找到最短路径,不过此时会很快。
在另外一个极端情况下,如果h()n相较于g(n)大很多,则此时只有h(n)产生效果,这也就变成了最佳优先搜索。
由上面这些信息我们可以知道,通过调节启发函数我们可以控制算法的速度和精确度。因为在一些情况,我们可能未必需要最短路径,而是希望能够尽快找到一个路径即可。这也是A*算法比较灵活的地方。

对于网格形式的图,有以下这些启发函数可以使用:

如果图形中只允许朝上下左右四个方向移动,则可以使用曼哈顿距离(Manhattan distance)。
如果图形中允许朝八个方向移动,则可以使用对角距离。
如果图形中允许朝任何方向移动,则可以使用欧几里得距离(Euclidean distance)。

五、距离

  • 如果图形中只允许朝上下左右四个方向移动,则启发函数可以使用曼哈顿距离;
  • 如果图形中允许斜着朝邻近的节点移动,则启发函数可以使用对角距离。

六、基于A*的网格地图最短路径问题求解

实例分析

1、计算grid中从从起点(2,2)到终点(3,6)的最短路。初始化open list,close list,将起点(2,2)加入到open list中,其优先级为0(最高),这里可以看出open list可以用优先队列。
图片
2、open list不为空,遍历 open list ,查找F值最小的节点q,此时q为起点,获取对当前方格q的 8 个相邻方格(successors),[(1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2), (3, 3)],遍历successors,对于每一个successor,计算G ,H,和F值,F=G+H,G通过欧几里得距离计算,如(2,2)和(1,1)之间的G值为 ( 2 − 1 ) 2 + ( 2 − 1 ) 2 = 2 = 1.4 \sqrt{(2-1)^2+(2-1)^2}=\sqrt 2 = 1.4 (21)2+(21)2 =2 =1.4,计算机中浮点数运算会产生容差(tolerance),这里记为14。H值为当前successor到终点的曼哈顿距离,是一个估计距离,因为还没找到最短路,不可能直接计算出确切值。如(1,1)和(3,6)之间的H值为70,故(1,1)的F值=G+H=84。同理可计算起点的其它successors的F值。最后将8个相邻方格加入open list,第一次迭代结束,将q加入close list。

点(x1,y1)和(x2,y2)间的欧几里得距离为 ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 \sqrt{(x_1-x_2)^2+(y_1-y_2)^2} (x1x2)2+(y1y2)2
点(x1,y1)和(x2,y2)间的曼哈顿距离为 ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ |x_1-x_2|+|y_1-y_2| x1x2+y1y2

在这里插入图片描述
3、重复上一步,open list不为空,遍历 open list ,查找F值最小的节点q,此时q为(3,3),F=44最小,获取q=(3,3)的相邻方格,successors=[(2, 2), (2, 3), (3, 2), (4, 2), (4, 3), (4, 4)],由于(2,4)和(3,4)为障碍,所以不算相邻方格。此时,(2,2)和(3,3)在close list中,遍历相邻方格F值,需要跳过。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

完整代码

图片
将实例分析中的网格地图映射为二维矩阵,其中1表示该网格可以通过,0表示为障碍。src=(2,2),tgt=(3,6)

          [1, 1, 1, 1, 0, 1, 1, 1],[1, 1, 1, 1, 0, 1, 1, 1],[1, 1, 1, 1, 0, 1, 1, 1],[1, 1, 1, 1, 1, 1, 1, 1],[1, 1, 1, 1, 1, 1, 1, 1],`

创建一个节点类Node,表示网格地图中的每一个网格(节点),Node类有4个属性值,分别是坐标、f值、g值、h值。将Node节点加入open list(优先队列)中,每次按优先级(f越小优先级越高)进行出队。重写equals方法和哈希方法,用坐标唯一标志一个Node。重写__lt__()方法使Node按f值比较大小。

完整代码如下:

from collections import defaultdict
from typing import Tuple
from queue import PriorityQueueimport numpy as np
import pandas as pd
import logginglogging.basicConfig(level=logging.DEBUG, format='%(message)s')# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
# 不换行打印
pd.set_option('display.width', 5000)class Node:def __init__(self, coord, priority=0):self.coord = coordself.f = priorityself.g = 0self.h = 0def __eq__(self, other):return self.coord == other.coorddef __hash__(self):return hash(self.coord)def __lt__(self, other):return self.f < other.fdef __getitem__(self, item):return self.coorddef __repr__(self):return str({'坐标': self.coord, 'f': self.f})class Grid:def __init__(self, ):# self.grid = np.asarray([#     [1, 0, 1, 1, 1, 1, 0, 1, 1, 1],#     [1, 1, 1, 0, 1, 1, 1, 0, 1, 1],#     [1, 1, 1, 0, 1, 1, 0, 1, 0, 1],#     [0, 0, 1, 0, 1, 0, 0, 0, 0, 1],#     [1, 1, 1, 0, 1, 1, 1, 0, 1, 0],#     [1, 0, 1, 1, 1, 1, 0, 1, 0, 0],#     [1, 0, 0, 0, 0, 1, 0, 0, 0, 1],#     [1, 0, 1, 1, 1, 1, 0, 1, 1, 1],#     [1, 1, 1, 0, 0, 0, 1, 0, 0, 1]]# )# // Driver program to test above function# /* Description of the Grid-#  1--> The cell is not blocked#  0--> The cell is blocked    */self.grid = np.asarray([[1, 1, 1, 1, 1, 1, 1, 1],[1, 1, 1, 1, 0, 1, 1, 1],[1, 1, 1, 1, 0, 1, 1, 1],[1, 1, 1, 1, 0, 1, 1, 1],[1, 1, 1, 1, 1, 1, 1, 1],[1, 1, 1, 1, 1, 1, 1, 1],])self.nodes = []logging.info(self.grid)for x in range(self.grid.shape[0]):for y in range(self.grid.shape[1]):coord = (x, y)node = Node(coord)self.nodes.append(node)def is_valid(self, node):x, y = nodeif x < 0 or x > self.grid.shape[0] - 1 or y < 0 or y > self.grid.shape[1] - 1:return Falseif self.grid[x][y] == 0:return Falsereturn Truedef get_neighbors(self, node: Node):x, y = node.coordneighbors = [(x - 1, y - 1), (x - 1, y), (x - 1, y + 1),(x, y - 1), (x, y + 1),(x + 1, y - 1), (x + 1, y), (x + 1, y + 1)]valid_neighbors = [neighbor for neighbor in neighbors if self.is_valid(neighbor)]valid_neighbors = [Node(neighbor) for neighbor in valid_neighbors]return valid_neighborsdef manhattan_distance(self, node_i, node_j):x1, y1 = node_i.coordx2, y2 = node_j.coordreturn np.abs(x1 - x2) + np.abs(y1 - y2)def euclidean_distance(self, node_i, node_j):x1, y1 = node_i.coordx2, y2 = node_j.coordreturn np.sqrt(np.power((x1 - x2), 2) + np.power((y1 - y2), 2))def a_star_algorithm(grid, src, tgt):src = Node(src)tgt = Node(tgt)shortest_path = [tgt]open_list = PriorityQueue()closed_list = set()open_list.put(src)node_parent = {}while not open_list.empty():node = open_list.get()if node == tgt:  # 若为终点,cur = node_parent[tgt]while cur != src:shortest_path.append(cur)cur = node_parent[cur]shortest_path.append(src)shortest_path.reverse()breakelse:  # 不是终点,neighbors = grid.get_neighbors(node)closed_list.add(node)for neighbor in neighbors:if neighbor in closed_list:continueif neighbor not in open_list.queue:node_parent[neighbor] = node  # 将当前邻接点neighbor的父节点为node,k=父节点,v=子节点neighbor.g = node.g + grid.euclidean_distance(node, neighbor)neighbor.h = grid.manhattan_distance(neighbor, tgt)neighbor.f = neighbor.g + neighbor.hopen_list.put(neighbor)if neighbor in open_list.queue:if node.g + grid.euclidean_distance(node, neighbor) > neighbor.g:neighbor.g = node.gneighbor.f = neighbor.g + neighbor.hnode_parent[neighbor] = node# 打印地图每个点的f值df = pd.DataFrame(index=np.arange(0, 6), columns=np.arange(0, 8), dtype=np.float_)for node in node_parent.keys():x, y = node.coorddf.loc[x, y] = node.fprint(df)return shortest_pathif __name__ == "__main__":grid = Grid()shortest_path = a_star_algorithm(grid, (2, 2), (3, 6))logging.info(f'最优路径:{shortest_path}')

程序运行结果如下:

[[1 1 1 1 1 1 1 1][1 1 1 1 0 1 1 1][1 1 1 1 0 1 1 1][1 1 1 1 0 1 1 1][1 1 1 1 1 1 1 1][1 1 1 1 1 1 1 1]]
最优路径:[{'坐标': (2, 2), 'f': 0}, {'坐标': (3, 3), 'f': 4.414213562373095}, {'坐标': (4, 4), 'f': 5.82842712474619}, {'坐标': (3, 5), 'f': 5.242640687119286}, {'坐标': (3, 6), 'f': 0}]0         1         2         3         4         5         6   7
0 NaN       NaN       NaN       NaN       NaN       NaN       NaN NaN
1 NaN  8.414214  7.000000  6.414214       NaN       NaN       NaN NaN
2 NaN  7.000000       NaN  5.000000       NaN  7.242641  6.656854 NaN
3 NaN  6.414214  5.000000  4.414214       NaN  5.242641  5.242641 NaN
4 NaN  8.414214  7.828427  6.414214  5.828427  5.828427  6.656854 NaN
5 NaN       NaN       NaN  9.242641  7.828427  7.242641       NaN NaNProcess finished with exit code 0

七、A*算法的改进思路

【路径规划】A*算法方法改进思路简析

参考:

  • A*算法详解(个人认为最详细,最通俗易懂的一个版本)

  • 路径规划之 A* 算法

  • 寻路算法——A*算法详解并附带实现代码

  • 【路径规划】A*算法方法改进思路简析

  • https://www.geeksforgeeks.org/a-search-algorithm/

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Echarts大屏可视化_03 定制柱状图

柱状图模块引入 1.找到合适的图表 在echarts中寻找与目标样式相近的图表 Examples - Apache ECharts 2. 引入柱状图 使用立即执行函数构建&#xff0c;防止变量全局污染 实例化对象 将官网中提供的option复制到代码中&#xff0c;并且构建图表 // 柱状图模块1 (function () {/…

WEB渗透—反序列化(十)

Web渗透—反序列化 课程学习分享&#xff08;课程非本人制作&#xff0c;仅提供学习分享&#xff09; 靶场下载地址&#xff1a;GitHub - mcc0624/php_ser_Class: php反序列化靶场课程&#xff0c;基于课程制作的靶场 课程地址&#xff1a;PHP反序列化漏洞学习_哔哩哔_…

【Linux】vim-多模式的文本编辑器

本篇文章内容和干货较多&#xff0c;希望对大家有所帮助&#x1f44d; 目录 一、vim的介绍 1.1 vi 与 vim的概念1.2 Vim 和 Vi 的一些对比 二、vim 模式之间的切换 2.1 进入vim2.2 [正常模式]切换到[插入模式]2.3 [插入模式]切换至[正常模式]2.4 [正常模式]切换至[底行模式…

C/C++---------------LeetCode第876. 链表的中间结点

链表的中间结点 题目及要求双指针在main内使用 题目及要求 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 示例 2&#xff1a; 双指针 思路&#xff1a;分别定义快慢指针…

STM32CubeMx+MATLAB Simulink点灯程序

STM32CubeMxMATLAB点灯程序 ✨要想实现在MATLAB Simulink环境下使用STM32&#xff0c;前提是已经搭建好MATLAB环境并且安装了必要的Simulink插件&#xff0c;以及对应的STM32支持包。 &#x1f33f;需要准备一块所安装支持包支持的STM32开发板. &#x1f516;具体支持包详情页…

LeetCode(45)最长连续序列【哈希表】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 最长连续序列 1.题目 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1&a…

公网穿透和RTC

RTC RTC 是 Real-Time Communication 的简写&#xff0c;正如其中文名称 “即时通讯” 的意思一样&#xff0c;RTC 协议被广泛用于各种即时通讯领域&#xff0c;诸如&#xff1a; 在线教育&#xff1b;直播中的主播连麦 PK&#xff1b;日常生活的音视频电话&#xff1b;.....…

【开源】基于Vue+SpringBoot的服装店库存管理系统

项目编号&#xff1a; S 052 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S052&#xff0c;文末获取源码。} 项目编号&#xff1a;S052&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 服…

Ubuntu镜像与K8S冲突,容器持续Terminating

问题 记录一次软件冲突BUG&#xff1a; eclipse-temurin:11-jdk&#xff08;底层Ubuntu 20.04.3 LTS&#xff09;镜像创建的容器在K8S-1.25.5上无法正常terminating&#xff0c;造成资源浪费&#xff0c;甚至引发K8S资源CPU insufficient报错。具体表现 某些容器镜像在K8S上无…

九章量子计算机:探索量子世界的革命性工具

九章量子计算机:探索量子世界的革命性工具 一、引言 九章量子计算机的推出,是近年来科技界最为引人瞩目的成就之一。这款基于量子力学的计算机,以其独特的计算方式和潜在的应用前景,引发了全球范围内的关注和讨论。本文将深入探讨九章量子计算机的原理、技术特点、应用前景…

【工具分享】| 阅读论文神器 使用技巧 AI润色 AI翻译

文章目录 1 使用技巧1.1 功能一 即时翻译1.2 功能二 文献跳转1.3 功能三 多设备阅读1.4 功能四 小组讨论笔记共享1.5 功能五 个人文献管理 2 其他功能 超级喜欢Readpaper这一款论文阅读软件&#xff0c;吹爆他哈哈 为什么&#xff1f; 当然是他可以解决我们传统阅读论文的种种…

python之pyqt专栏5-信号与槽1

在上一篇文章&#xff0c;我们了解到如果想要用代码改变QLabel的文本内容&#xff0c;可以调用QLabel类的text()函数。 但是现在有个这样的需求&#xff0c;界面中有一个Button与一个Label&#xff0c;当点击Button时&#xff0c;将Label的内容改变为“Hello world&#xff01;…

前端:实现div的隐藏与显示

效果 完整代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-widt…

云计算如何创芯:“逆向工作法”的性感之处

在整个云计算领域&#xff0c;能让芯片规模化的用起来&#xff0c;是决定造芯是否成功的天花板。在拉斯维加斯的亚马逊云科技2023 re:Invent则是完美诠释了这一论调。 亚马逊云科技2023 re:Invent开幕前两个小时&#xff0c;有一场小型的欢迎晚宴&#xff0c;《星期日泰晤士报》…

开源与闭源

我的观点&#xff1a; 开源与闭源软件都有各自的优势和劣势&#xff0c;没有绝对的对错之分。.. 一、开源和闭源的优劣势比较 开源的好处与劣处 优势&#xff1a; 创新与合作&#xff1a;开源软件能够吸引更多的开发者参与到项目中来&#xff0c;促进创新和合作。开放的源代码…

【小布_ORACLE笔记】Part11-1--RMAN Backups

Oracle的数据备份于恢复RMAN Backups 学习第11章需要掌握&#xff1a; 一.RMAN的备份类型 二.使用backup命令创建备份集 三.创建备份文件 四.备份归档日志文件 五.使用RMAN的copy命令创建镜像拷贝 文章目录 Oracle的数据备份于恢复RMAN Backups1.RMAN Backup Concepts&#x…

[PyTorch][chapter 64][强化学习-DQN]

前言&#xff1a; DQN 就是结合了深度学习和强化学习的一种算法&#xff0c;最初是 DeepMind 在 NIPS 2013年提出&#xff0c;它的核心利润包括马尔科夫决策链以及贝尔曼公式。 Q-learning的核心在于Q表格&#xff0c;通过建立Q表格来为行动提供指引&#xff0c;但这适用于状态…

社区便利店销售微信APP的设计与实现

摘 要 社区便利店销售小程序采用的技术&#xff1a;第一是Mysql数据库&#xff1b;第二是java程序开发语言&#xff1b;第三是ssm框架&#xff1b;第四是B/S结构。系统主要分为管理员、商家、用户三部分&#xff0c;这个销售小程序的功能有首页和个人中心&#xff0c;同时还有…

计算机毕业设计|基于SpringBoot+MyBatis框架健身房管理系统的设计与实现

计算机毕业设计|基于SpringBootMyBatis框架的健身房管理系统的设计与实现 摘 要:本文基于Spring Boot和MyBatis框架&#xff0c;设计并实现了一款综合功能强大的健身房管理系统。该系统涵盖了会员卡查询、会员管理、员工管理、器材管理以及课程管理等核心功能&#xff0c;并且…

MySQL 教程 1.4

MySQL 连接 使用mysql二进制方式连接 您可以使用MySQL二进制方式进入到mysql命令提示符下来连接MySQL数据库。 实例 以下是从命令行中连接mysql服务器的简单实例&#xff1a; [roothost]# mysql -u root -p Enter password:****** 在登录成功后会出现 mysql> 命令提示窗…