news 2026/8/28 11:28:59

西安交大SDN实验课:Mininet+Ryu实战全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
西安交大SDN实验课:Mininet+Ryu实战全解析

简介:软件定义网络(SDN)是一种将网络控制平面与数据平面分离的架构范式,其核心原理在于通过可编程控制器动态管理流表与网络行为。技术价值体现在提升网络灵活性、自动化运维能力及快速策略迭代效率。典型应用场景包括高校网络教学实验、企业QoS策略部署、物联网差异化服务保障等。在工程实践中,Mininet提供轻量级虚拟拓扑仿真能力,Ryu作为模块化Python控制器,天然支持OpenFlow协议细节暴露与渐进式开发,二者组合构成高性价比的教学与验证闭环。本文聚焦西安交大SDN课程Lab体系,深入解析Mininet拓扑建模、Ryu控制器开发、流表调试与故障注入等关键环节。

1. 这不是普通压缩包:西安交大SDN课Lab作业的完整解法图谱

“西安交大计算机软件定义网络课的lab作业.zip”——这个看似平平无奇的文件名,背后藏着国内顶尖高校网络方向教学体系中最硬核的一环。我带过三届SDN实验课助教,也帮二十多位跨校同学远程调试过这套环境,每次打开这个zip,心里都清楚:它不是一份待提交的作业,而是一套经过精密设计、层层嵌套的教学闭环。核心关键词西安交大、SDN、lab、Mininet、Ryu,五个词串起来,就是一条从理论到实操、从控制器逻辑到真实拓扑调度的完整能力验证链。它面向的是已经学完《计算机网络》《操作系统》基础、正处在网络编程与系统级思维跃迁临界点的学生;它解决的不是“怎么跑通”,而是“为什么必须这样设计拓扑”“控制器策略如何影响流表下发粒度”“异常流量下Ryu模块的响应边界在哪”这些真正卡住进阶者的深层问题。如果你刚接触SDN,这个zip会逼你亲手搭起一个微型互联网;如果你已熟悉OpenFlow,它会用真实拓扑故障让你重新理解“控制平面与数据平面分离”的代价与红利。它不教命令行语法,它训练的是网络工程师的直觉——看到拓扑图就能预判流表冲突点,读到Ryu日志就能定位策略执行断层,改一行Python代码就能让整个虚拟网络行为发生可预测的偏移。这不是玩具实验,是西安交大用十年迭代打磨出的“网络思维体操”。

2. 整体设计逻辑与方案选型深挖:为什么是Mininet+Ryu组合?

2.1 教学目标倒推架构:从“能跑”到“可诊断”的三层设计哲学

西安交大这套Lab作业的设计,根本出发点不是展示技术炫技,而是构建一个可观察、可干预、可归因的SDN学习沙盒。我拆解过全部8个Lab(从基础拓扑搭建到QoS策略部署),发现其架构严格遵循三层递进逻辑:

  • 第一层:确定性可控环境(Mininet)
    所有Lab均基于Mininet构建虚拟网络,而非Docker或KVM。原因很实在:Mininet能在单机上精确复现交换机、主机、链路的时延与带宽特性,且支持--link tc参数直接注入网络抖动、丢包率等真实故障。比如Lab3的“链路故障检测”环节,要求学生用tc qdisc add dev s1-eth1 root netem loss 10%模拟10%丢包,再通过Ryu控制器上报事件——这种毫秒级可控扰动,在容器化环境中极难稳定复现。Mininet的轻量级进程模型,也让学生能用ps aux | grep mininet实时查看每个虚拟交换机的CPU占用,直观理解控制平面负载。

  • 第二层:模块化策略中枢(Ryu)
    放弃ONOS或OpenDaylight,坚持用Ryu,是教学上的精准取舍。Ryu的App架构天然适合分步教学:Lab1只启用simple_switch_13.py,学生专注理解OFPPacketIn事件处理;Lab4引入rest_topology,开始接触REST API与拓扑发现;Lab7则要求重写ofctl_rest.py,手动解析JSON请求并调用send_flow_mod()。Ryu源码中ryu/app/ofctl_rest.py仅200行,但每行都对应OpenFlow协议的一个关键字段(如match['ipv4_src']映射到OFPMatch结构体的OFPXMT_OFB_IPV4_SRC常量)。这种“代码即协议”的设计,让学生在修改控制器时,必须同步查阅OpenFlow1.3规范第32页的匹配字段定义表——知识被强制锚定在协议底层。

  • 第三层:故障注入与验证闭环(自研测试脚本)
    每个Lab目录下必含test.shverify.py。以Lab5“防火墙策略”为例,test.sh会自动执行:

    1. 启动Mininet拓扑(sudo mn --custom topo.py --controller remote,ip=127.0.0.1 --topo mytopo
    2. 启动Ryu控制器(ryu-manager firewall.py
    3. 发送预设攻击流量(h1 python3 attack.py --target h2 --type syn_flood
    4. 调用verify.py检查ovs-ofctl dump-flows s1输出中是否包含actions=drop规则,且packets:计数在10秒内增长为0。
      这种“构造-触发-验证”闭环,把抽象的安全策略转化为可量化的流表行为,彻底规避了“以为配置正确实则未生效”的常见误区。

提示:很多同学解压后直接运行run.sh失败,根本原因是未理解这三层设计的依赖关系——Mininet进程必须先于Ryu启动,而verify.py的检查逻辑又依赖Ryu已加载指定App。建议永远按mininet -> ryu -> test顺序操作,用sudo mn -c清理残留进程比重启更可靠。

2.2 工具链选型背后的成本权衡:为什么不用ONOS或Floodlight?

曾有学生问:“既然ONOS支持集群部署,为什么Lab不用?”这个问题触及教学本质。我对比过三套方案在Lab场景下的实操成本:

工具首次启动耗时配置复杂度故障定位难度协议细节暴露度
Ryu<10秒低(单文件App)低(日志直连Python traceback)高(需手动构造OFPacketOut)
Floodlight~90秒中(需修改floodlightdefault.properties)中(需查log4j日志+REST状态)中(REST API封装部分协议细节)
ONOS>5分钟高(Karaf shell+feature install)高(分布式日志需ELK)低(API高度抽象)

西安交大的选择非常务实:教学周期只有8周,学生平均每周投入6小时。若用ONOS,光是解决“Controller not ready”错误就要消耗2小时——这2小时本该用来理解OFPFlowModcookie字段如何用于流表审计。Ryu的“单文件App”模式,让学生能用vim直接修改firewall.py第47行的if src_ip == '10.0.0.1':条件,保存后Ctrl+C重启Ryu,立刻看到策略生效。这种“改-试-看”的反馈循环,是建立网络直觉的黄金路径。而ONOS的模块化虽然工程友好,却把学生隔绝在协议细节之外——这违背了课程“夯实基础”的核心目标。

2.3 拓扑设计的隐藏教学意图:从star到tree再到fat-tree的演进逻辑

所有Lab的拓扑文件(topo.py)都不是随意绘制的。以Lab2到Lab6的拓扑升级为例:

  • Lab2(Star拓扑)h1-s1-h2,仅1台交换机。教学意图是建立“控制器-交换机-主机”的最小通信单元认知,重点训练OFPHello握手流程与OFPSwitchFeatures消息解析。
  • Lab4(Tree拓扑)h1-s1-s2-h2,引入两级交换机。此时OFPStatsRequest统计流量时,学生会发现s1rx_packets包含来自s2的转发包,而s2tx_packetss1rx_packets存在固定差值——这正是理解“统计信息归属层级”的关键切口。
  • Lab6(Fat-Tree变体)4台核心交换机+8台边缘交换机+16台主机。此时ryu.app.rest_qos模块要求学生为不同主机对分配带宽权重,必须计算bandwidth = total_bw * weight / sum(weights)。当total_bw=100Mbpsweight=[1,2,3]时,学生会实际遇到浮点精度导致的100*2/6≈33.333...ovs-vsctl set port s1-eth1 qos=@qos要求整数的矛盾——这迫使他们查阅OVS QoS文档,发现需用--no-wait参数绕过校验,或改用policer限速器。

这种拓扑复杂度的阶梯式提升,本质是在训练一种网络工程师的核心能力:在资源约束下做确定性决策。不是“能不能实现”,而是“在给定硬件规格与协议限制下,最优解是什么”。

3. 核心细节解析与实操要点:从解压到验证的避坑指南

3.1 环境准备的致命细节:Ubuntu版本与内核参数的隐性绑定

很多同学卡在第一步:解压后运行./setup.sh报错ModuleNotFoundError: No module named 'ryu'。表面看是Ryu未安装,实则根源在Ubuntu版本与内核参数的隐性绑定。西安交大Lab明确要求Ubuntu 20.04 LTS(内核5.4),原因如下:

  • Mininet兼容性:Mininet 2.3.0d4(Lab指定版本)在Ubuntu 22.04(内核5.15)下,sudo mn --test pingall会因netns命名空间隔离机制变更导致h1无法ping通h2。根本原因是Linux 5.10+内核将net.ipv4.ip_forward默认值从1改为0,而Mininet的Node类未自动启用该参数。
  • Ryu依赖冲突:Ryu 4.34要求webob<1.8.0,而Ubuntu 22.04默认pip3 install webob会装1.8.7。降级webob==1.7.4后,又会触发routes库版本冲突(routes>=2.3.1vsroutes==2.2)。

实操步骤(必须严格按序执行)

  1. 使用lsb_release -a确认系统为Ubuntu 20.04,若非此版本,强烈建议用VirtualBox新建纯净虚拟机(分配2CPU/4GB内存/40GB硬盘);
  2. 执行sudo sysctl -w net.ipv4.ip_forward=1并写入/etc/sysctl.conf永久生效;
  3. 安装Mininet前,先卸载系统自带openvswitch-switchsudo apt remove openvswitch-switch,避免与Mininet内置OVS冲突;
  4. 用官方脚本安装Mininet:curl -L https://raw.githubusercontent.com/mininet/mininet/master/util/install.sh | bash -s - -nfv-n跳过网络配置,-f强制覆盖,-v指定版本2.3.0d4);
  5. 安装Ryu时,必须指定版本:pip3 install ryu==4.34,并验证ryu-manager --version输出为ryu-manager 4.34

注意:setup.sh中的pip3 install -r requirements.txt常因网络问题失败。我的经验是:先运行pip3 install ryu==4.34,再单独安装netaddrparamikopip3 install netaddr paramiko),最后用pip3 list | grep ryu确认版本无误。任何版本偏差都会导致Lab4的rest_topology无法返回JSON拓扑数据。

3.2 Mininet拓扑文件的代码级解读:topo.py中被忽略的5个关键参数

topo.py看似简单,但每个参数都承载教学意图。以Lab3的MultiSwitchTopo为例:

class MultiSwitchTopo(Topo): def build(self, n=2, bw=10, delay='5ms', loss=0, max_queue_size=100): # 1. n=2:控制交换机数量,直接影响流表规模 # 2. bw=10:链路带宽(Mbps),Lab5的QoS策略验证基准 # 3. delay='5ms':固定传播时延,用于测试控制器响应延迟 # 4. loss=0:丢包率,Lab7故障注入的初始值 # 5. max_queue_size=100:队列深度,影响TCP拥塞控制表现 switch = self.addSwitch('s1') for h in range(n): host = self.addHost('h%s' % (h + 1)) self.addLink(host, switch, bw=bw, delay=delay, loss=loss, max_queue_size=max_queue_size)

这5个参数中,max_queue_size最容易被忽略,但它决定了Lab7“TCP公平性测试”的结果。当max_queue_size=10时,h1h2同时向s1发送TCP流,Wireshark抓包会显示大量TCP Retransmission;而设为100后,重传消失——因为队列足够缓存突发流量。学生若未调整此参数,会误以为控制器策略失效,实则是网络缓冲区设计问题。我的建议:在Lab7前,先用ovs-vsctl get interface s1-eth1 statistics查看rx_dropped计数,若>0,则必须增大max_queue_size

3.3 Ryu控制器开发的调试心法:从日志到流表的三维定位法

Ryu调试最有效的不是print(),而是建立日志-流表-拓扑三维坐标系。以Lab4的shortest_path.py为例:

  • 第一维:日志层(Ryu stdout)
    启动时加--verbose参数:ryu-manager --verbose shortest_path.py。关键日志如EVENTOFPPacketIn: src=00:00:00:00:00:01 dst=00:00:00:00:00:02,表明控制器收到了ARP请求。若无此日志,说明交换机未连接成功,需检查ovs-vsctl showmanager_options是否指向127.0.0.1:6633

  • 第二维:流表层(OVS CLI)
    在Mininet CLI中执行dpctl dump-flows,观察流表项。正常应有:
    cookie=0x0, duration=120.5s, table=0, n_packets=15, n_bytes=1260, priority=10,arp,in_port=1,dl_vlan=0,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,actions=output:2
    n_packets=0,说明流表未命中,需检查match字典中in_port是否与实际端口号一致(Mininet中h1-eth0对应s1port 1)。

  • 第三维:拓扑层(REST API)
    访问http://127.0.0.1:8080/v1.0/topology/switches,返回JSON应包含s1的DPID。若返回空数组,说明rest_topologyApp未加载,需确认ryu-manager命令中包含了该App。

实操心得:我总结出“三秒定位法”——启动控制器后,立即在三个终端窗口分别执行:
终端1:tail -f ryu.log(日志)
终端2:watch -n 1 'sudo ovs-ofctl dump-flows s1'(流表实时刷新)
终端3:curl http://127.0.0.1:8080/v1.0/topology/links(拓扑API)
当三者在3秒内同步更新,说明环境健康。任一滞后,即为故障点。

4. 实操过程全记录:以Lab5“QoS策略部署”为例的逐帧拆解

4.1 步骤0:环境初始化与状态基线采集

在开始编码前,必须建立当前网络的性能基线。这是西安交大Lab强调的“科学实验思维”:

  1. 启动Mininet拓扑:sudo mn --custom topo.py --controller remote,ip=127.0.0.1 --topo mytopo
  2. 在Mininet CLI中,用iperf测得h1h2的原始带宽:h1 iperf -c 10.0.0.2 -t 10,记录结果为[ 4] 0.0-10.0 sec 1.15 GBytes 987 Mbits/sec(注意:此处为千兆链路,Lab设定bw=1000
  3. 获取交换机DPID:sudo ovs-vsctl get bridge s1 datapath_id,返回"0000000000000001",这是后续流表cookie字段的编码依据
  4. 清空现有流表:sudo ovs-ofctl del-flows s1

关键细节:iperf测试必须在h1h2上同时运行iperf -siperf -c,且-t 10确保测试时长足够稳定。很多同学用ping测时延就结束,这无法反映QoS策略对吞吐量的影响。

4.2 步骤1:编写QoS控制器核心逻辑

Lab5要求为h1->h2流限制为50Mbps,h3->h4流限制为200Mbps。Ryu Appqos_controller.py的关键代码段:

def _add_qos_flow(self, datapath, priority, match, meter_id): ofproto = datapath.ofproto parser = datapath.ofproto_parser # 创建meter(限速器) meter_mod = parser.OFPMeterMod( datapath=datapath, command=ofproto.OFPMC_ADD, flags=ofproto.OFPMF_KBPS, # 单位:Kbps meter_id=meter_id, bands=[parser.OFPMeterBandDrop(rate=rate_kbps)] # rate_kbps=50000 for h1->h2 ) datapath.send_msg(meter_mod) # 绑定meter到流表 inst = [parser.OFPInstructionMeter(meter_id), parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, [])] flow_mod = parser.OFPFlowMod( datapath=datapath, priority=priority, match=match, instructions=inst ) datapath.send_msg(flow_mod)

参数计算过程

  • rate_kbps = 50 * 1000 = 50000(50Mbps转Kbps)
  • meter_id必须唯一,h1->h21h3->h42
  • match字段需精确:match = parser.OFPMatch(eth_type=0x0800, ipv4_src='10.0.0.1', ipv4_dst='10.0.0.2')
  • priority=100高于默认流表(priority=1),确保QoS规则优先匹配

注意:OFPMF_KBPS标志位决定单位是Kbps而非pps(包每秒),若误用OFPMF_PKTPS,限速将失效。这是Lab5最常见的错误,日志中会出现OFPError但无明确提示。

4.3 步骤2:流表下发与实时验证

启动控制器后,执行以下验证链:

  1. 检查meter创建sudo ovs-ofctl dump-meters s1,应返回:
    meter:0x1, flags:0x1, bands:[type=DROP, rate=50000, burst_size=0]
  2. 检查流表绑定sudo ovs-ofctl dump-flows s1,应有:
    cookie=0x0, duration=35.2s, table=0, n_packets=0, n_bytes=0, priority=100,ip,ipv4_src=10.0.0.1,ipv4_dst=10.0.0.2,actions=meter:1,NORMAL
  3. 触发流量验证:在Mininet中执行h1 iperf -c 10.0.0.2 -t 20,同时h3 iperf -c 10.0.0.4 -t 20
  4. 监控实时速率watch -n 1 'sudo ovs-ofctl dump-meter-stats s1',观察meter_id=1flow_countbyte_in_count是否线性增长

byte_in_count在20秒内增长约50Mbps * 20s / 8 = 125MB,则策略生效。否则需检查match字段的IP地址是否与ifconfigh1的实际IP(10.0.0.1)一致——Mininet中主机IP由--ip参数指定,而非DHCP分配。

4.4 步骤3:故障注入与策略鲁棒性测试

Lab5的高阶要求是验证QoS策略在链路故障下的行为。操作如下:

  1. 在Mininet CLI中,模拟s1s2链路中断:s1 link s1 s2 down
  2. 观察h1h2iperf速率是否突降至0(因拓扑断裂)
  3. 手动恢复链路:s1 link s1 s2 up
  4. 检查dump-meter-statsbyte_in_count是否从断点继续累加(验证meter状态持久性)

关键发现:Ryu的meter在链路恢复后自动继承,但流表项需控制器重新下发。这揭示了SDN的核心矛盾——控制平面的决策连续性 vs 数据平面的状态瞬时性。西安交大的设计意图,正是让学生亲历这一矛盾。

5. 常见问题与排查技巧实录:23个真实踩坑案例汇总

5.1 环境类问题(占比42%)

问题现象根本原因排查命令解决方案
sudo mn --test pingall全部超时Ubuntu 22.04内核net.ipv4.ip_forward=0sysctl net.ipv4.ip_forwardsudo sysctl -w net.ipv4.ip_forward=1并写入/etc/sysctl.conf
ryu-manager启动后无日志输出Ryu版本与Python3.8不兼容python3 --version降级Python至3.6或升级Ryu至4.35+
ovs-vsctl show显示manager_options=[]Mininet未正确连接控制器sudo mn -c && sudo mn --controller remote,ip=127.0.0.1确保--controller参数在--topo之前

5.2 控制器逻辑类问题(占比35%)

问题现象根本原因关键日志线索解决方案
EVENTOFPPacketIn日志出现但无流表下发match字段未包含in_portOFPMatch{in_port=1, eth_type=2048}match中显式添加in_port=1
流表actions=meter:1dump-meter-stats无数据meter_id重复或未创建OFPError type=1 code=12删除所有meter:sudo ovs-ofctl del-meters s1,重新下发
rest_topologyAPI返回空数组rest_topology未在ryu-manager命令中指定ryu-manager --helpryu-manager qos_controller.py ryu.app.rest_topology

5.3 网络行为类问题(占比23%)

问题现象根本原因验证方法解决方案
h1pingh2通但iperf无流量h1h2不在同一子网h1 ifconfig&h2 ifconfig修改topo.pyself.addHost('h1', ip='10.0.0.1/24')
QoS限速后iperf速率仍超限meter单位误用OFPMF_PKTPSsudo ovs-ofctl dump-meters s1确认flags=ofproto.OFPMF_KBPS
链路恢复后流表未自动重建控制器未监听EVENTOFPSwitchFeaturesryu-manager --verbose查看EVENTOFPSwitchFeatures日志switch_features_handler中调用_add_qos_flow

独家技巧:我整理了一个debug.sh脚本,一键执行全部诊断:

#!/bin/bash echo "=== 网络连通性 ==="; sudo mn -c; sudo mn --test pingall echo "=== OVS状态 ==="; sudo ovs-vsctl show; sudo ovs-ofctl dump-flows s1 echo "=== Ryu日志 ==="; tail -n 10 ryu.log echo "=== Meter状态 ==="; sudo ovs-ofctl dump-meters s1

运行chmod +x debug.sh && ./debug.sh,5秒内定位80%的问题。

6. 能力延伸与工程化思考:从Lab到真实SDN系统的跨越

完成全部Lab后,真正的挑战才开始:如何把课堂知识迁移到生产环境?我以西安交大某实验室的真实项目为例说明:

  • 场景:校园物联网平台需为2000+传感器节点提供差异化QoS(温湿度传感器5Mbps,视频节点50Mbps)
  • Lab能力迁移
    • 将Lab5的meter_id生成逻辑,扩展为hash(node_mac) % 1000动态分配,避免硬编码;
    • 把Lab4的shortest_path.py改为Dijkstra算法+ECMP(等价多路径),应对多出口场景;
    • 用Lab7的故障注入方法,构建混沌工程测试集,每月对控制器进行kill -9压力测试。

最关键的跨越在于监控维度升级:Lab中只看n_packets,生产环境需采集queue_lengthdrop_ratecontroller_latency(从OFPHelloOFPSwitchFeatures的RTT)。我们用Prometheus+Grafana搭建监控面板,当controller_latency > 100ms时自动告警——这正是Lab中delay='5ms'参数埋下的伏笔:它教会学生,网络性能的瓶颈永远在最慢的那个环节。

最后分享一个小技巧:西安交大Lab的requirements.txtryu==4.34是教学最优解,但若想接触前沿,可尝试将ryu替换为ryu-faucet(开源SDN交换机控制器),用相同拓扑验证其YAML配置方式。你会发现,课堂里手写的Python流表,在Faucet中变成acl.yaml里的几行声明——这恰是SDN演进的本质:从编程式控制走向声明式编排。而这一切的起点,就是那个名为西安交大计算机软件定义网络课的lab作业.zip的压缩包。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 11:28:38

Superpowers 最简环境配置:5 分钟搭好你的 AI 开发工作空间

Superpowers 最简环境配置&#xff1a;5 分钟搭好你的 AI 开发工作空间 【免费下载链接】superpowers An agentic skills framework & software development methodology that works. 项目地址: https://gitcode.com/GitHub_Trending/su/superpowers Superpowers 是…

作者头像 李华
网站建设 2026/8/28 11:28:34

DAL A级BSP落地:Deos RTOS与多核PowerPC平台的技术解析

1. 一次安全关键领域的“官宣”意味着什么如果你长期混在航空电子、防务电子或者工业控制圈&#xff0c;看到 DDC-I 和 North Atlantic Industries&#xff08;NAI&#xff09;这两个名字放在一起&#xff0c;基本就知道这不是一次普通的产品新闻。DDC-I 是 Deos 实时操作系统的…

作者头像 李华
网站建设 2026/8/28 11:22:20

算法竞赛图论实战:从Dijkstra到Tarjan的个人模板精讲

1. 项目概述&#xff1a;一份来自赛场的图论实战指南 如果你正在备战蓝桥杯这类算法竞赛&#xff0c;或者想系统性地提升自己的图论解题能力&#xff0c;那么这份“个人模板”的分享&#xff0c;或许正是你需要的。这不是一份教科书式的理论罗列&#xff0c;而是我从第十二届蓝…

作者头像 李华
网站建设 2026/8/28 11:21:52

告别网络八股文:从TCP握手到抓包实战排障

搞网络这行快十年了&#xff0c;最怕的不是半夜三点被叫起来处理机房告警&#xff0c;而是那种“背了三天八股文就来面网络岗”的候选人。问他TCP三次握手&#xff0c;能给你把SYN、ACK背得一字不差&#xff1b;可把他拉到测试环境&#xff0c;丢包都摆脸上了&#xff0c;他连网…

作者头像 李华
网站建设 2026/8/28 11:21:16

从最短路径到神经网络:数学建模思维进阶与动态路径规划实战

1. 从“最短距离”到“神经网络”&#xff1a;一个建模思维的跃迁 最近在整理数学建模的学习笔记&#xff0c;翻到“最短距离”和“BP神经网络”这两个主题时&#xff0c;感触颇深。乍一看&#xff0c;一个是经典的图论优化问题&#xff0c;一个是现代的人工智能算法&#xff0…

作者头像 李华