408考研必备:置换-选择排序在外部排序中的实战应用与优化策略

news2026/4/15 11:31:00
1. 从一道真题说起为什么置换-选择排序是408的“必考题”我记得第一次在408真题里碰到置换-选择排序的时候心里也犯嘀咕这算法名字听着就拗口什么“置换”又“选择”的感觉特别复杂。但后来我花了点时间把几道真题放在一起琢磨发现它其实是一个逻辑非常清晰、设计极其巧妙的“空间换时间”的典范。对于考研来说它之所以成为高频考点恰恰是因为它完美地串联起了数据结构堆、算法设计思想选择与淘汰和实际应用场景外部排序这三个核心板块。想象一下这个场景你有一个超级大的文件里面存了10亿个学生的成绩记录你的电脑内存很小一次只能装下1万个记录。你怎么把这个文件整体排好序这就是外部排序要解决的经典问题。它的核心思路是“分而治之”先把大文件切成一个个内部有序的小段这些就是初始归并段然后再把这些有序小段像合并扑克牌一样多轮合并成一个完整的有序大文件。那么问题来了怎么生成这些初始归并段才最划算最笨的办法是每次从大文件里读1万条记录到内存用快排排好序写回磁盘得到一个1万条记录的有序段。这样10亿条记录就需要10万个初始归并段。后续合并这10万个段工作量会非常巨大。而置换-选择排序的妙处就在这里它用同样大小的内存比如还是装1万条记录却能生成平均长度远大于1万条的有序段。我实测过在数据随机的情况下它生成的归并段平均长度大约是内存容量的两倍。这意味着初始归并段的数量几乎能减少一半从而大幅降低后续归并的趟数和磁盘I/O次数这是性能提升的关键。考研真题比如2023年的那道考察的就是这个核心给定一个具体序列和工作区大小你能一步步推导出生成几个段、每个段是什么吗以及从理论上分析第一个归并段最长能有多长最短又能有多短这都是在检验你是否真正理解了算法“延长归并段”的内在机理。所以别再把它当成一个孤立的知识点了。它是一把钥匙帮你理解如何用有限的内存高效处理海量数据。掌握了它你对“堆”的应用、对外部排序流程的理解会上一个全新的台阶。下面我就带你亲手拆解这道真题把每一步的逻辑都掰开揉碎讲清楚。2. 手把手拆解2023真题一步步“运行”算法咱们就拿2023年408真题的原始数据来实操一遍。题目给了19个记录关键字序列是51, 94, 37, 92, 14, 63, 15, 99, 48, 56, 23, 60, 31, 17, 43, 8, 90, 166, 100。工作区大小 m 4也就是我们的内存最小堆只能同时放下4条记录。我们的目标是模拟置换-选择排序的过程生成所有的初始归并段。这个过程就像是一个智能的“筛选流水线”。2.1 初始化与核心规则首先我们从输入文件也就是那个序列中读出前4个记录[51, 94, 37, 92]放入工作区并立即把它们调整成一个最小堆。最小堆的特性是堆顶元素永远是当前最小的。所以调整后堆的顺序是[37, 51, 92, 94]这里用数组表示堆的逻辑结构37是堆顶。现在我们定义两个关键变量当前归并段和max_output。我们刚开始生成第一个归并段max_output初始可以设为一个非常小的值比如 -∞它记录的是当前这个归并段里已经输出的最大的那个关键字。为什么需要它这是算法的灵魂规则为了保持当前归并段内部有序新加入的记录关键字必须不小于max_output。否则它就会破坏有序性只能被归到下一个归并段去。算法的主循环步骤如下输出堆顶取出并输出堆顶元素当前最小它成为当前归并段的一部分。更新最大值用刚输出的关键字更新max_output。置换新记录从输入文件中读入一个新记录用它替换掉刚才输出的堆顶位置。关键判断比较新记录的关键字key和当前的max_output。如果key max_output恭喜这个新记录“合格”它可以参与当前归并段的后续排序。我们把它放到堆顶然后重新调整堆minHeapify让它找到新的合适位置。如果key max_output抱歉这个新记录“不合格”它比当前段里已经输出的某些记录还小不能放在这个段里。我们给它打上一个“属于下一个归并段”的标记代码里常用一个isNextRun的布尔变量然后仍然把它放在堆顶。注意即使被标记它仍然留在工作区占着位置但后续调整堆时会被视为“无效”元素而沉到堆底。段结束判断什么时候当前归并段结束呢当工作区里所有的记录都被标记为“属于下一个归并段”时。这意味着再也找不出能接在当前段后面的记录了。此时我们清空所有标记把工作区里这些“下一段”的记录视为一个新的初始集合重新建堆开始生成下一个归并段。2.2 实战推演第一个归并段是如何诞生的让我们严格遵循上面的规则推演第一个归并段的生成步骤1堆顶是37输出37。max_output更新为37。读入下一个记录14。比较14 37不合格标记14为下一段。工作区变为[14*, 51, 92, 94]*表示标记。调整堆由于14被标记它会被下沉堆顶变成下一个最小的未标记记录51。步骤2输出51。max_output51。读入63。63 51合格用63替换堆顶工作区为[63, 14*, 92, 94]。调整堆63比14大但14被标记了所以63成为堆顶。步骤3输出63。max_output63。读入15。15 63不合格标记15*替换堆顶。工作区[15*, 14*, 92, 94]。步骤4输出92。max_output92。读入99。99 92合格替换堆顶。工作区[99, 15*, 14*, 94]。步骤5输出94。max_output94。读入48。48 94不合格标记48*。工作区[48*, 15*, 14*, 99]。步骤6输出99。max_output99。读入56。56 99不合格标记56*。工作区[56*, 48*, 15*, 14*]。此时工作区四个记录[56*, 48*, 15*, 14*]全部被标记为“下一段”第一个归并段生成结束。我们输出了序列37, 51, 63, 92, 94, 99长度是6。看我们的内存工作区只能容纳4个记录但却产出了一个长度为6的有序段这就是算法的威力。2.3 继续推进完成所有归并段第一个段结束后我们清空所有记录的标记。现在工作区里的[56, 48, 15, 14]就是第二段的起点。重新建最小堆得到[14, 15, 48, 56]。然后重复上述过程。按照同样的逻辑模拟下去你会得到第二个归并段14, 15, 23, 31, 48, 56, 60, 90, 166长度是9。第三个归并段8, 17, 43, 100长度是4。所以最终答案共生成3个初始归并段。通过这个一步步的推演你是不是感觉算法不再是一个黑盒了每一个判断、每一次标记都是为了在有限内存内尽可能多地收集能构成有序序列的记录。自己动手在纸上画一遍这个流程是理解它最有效的方法考试时也能做到心中不慌。3. 深度剖析归并段长度的边界与优化本质做完真题模拟我们自然会思考一个更理论的问题这算法的性能边界在哪题目第二问就是考察这个对于任意的工作区大小m第一个初始归并段的最大长度和最小长度分别是多少搞清楚这个你就抓住了算法优化的命脉。3.1 最大长度理想情况下的极限什么时候第一个归并段能最长我们需要最充分地利用工作区。设想一个完美场景初始时工作区里的m个记录本身肯定都能输出这是m个长度。关键在后续的置换。当我们输出第1个记录后读入第m1个新记录。为了让段继续这个新记录必须当前输出的最大值。在最理想情况下之后读入的每一个新记录都比当前已输出的最大值要大。这样每输出一个就能立刻补充进一个“合格”的新记录。这个“甜蜜期”能持续多久直到我们读入第2m个记录即初始m个输出后又读入了m个。此时工作区里是最新读入的m个记录。当我们试图输出第2m个记录也就是最新读入的这批里的最后一个时它需要跟当前max_output比较。在最理想情况下这个比较依然通过。但是当我们要为第2m个记录寻找“替补”读入第2m1个记录时问题来了。这个新记录必须比当前max_output也就是第2m个记录的值还要大才能继续。然而由于输入是任意的我们无法保证这一点。一旦这个新记录比max_output小它就会被标记从而导致归并段结束。因此第一个归并段的最大长度是初始m个 理想情况下后续能连续输出的(m-1)个 2m - 1。也就是说给你m大小的内存在最走运的情况下你第一次能搓出一个差不多两倍于内存大小的有序段。3.2 最小长度最坏情况的底线那最短能有多短呢考虑最倒霉的情况初始工作区里的m个记录恰好是全局最小的m个并且是升序排列这样每次堆顶都是当前最小。输出第一个记录最小的后max_output就是这个值。接下来读入的新记录每一个都比当前的max_output小于是每一个新记录都被立刻标记为“下一段”。由于堆顶元素输出后被标记的新记录会占据堆顶在后续的堆调整中这些被标记的记录会被视为“无效”而沉底堆顶会依次选出工作区里剩余的、未标记的原始记录。就这样工作区里最初的m个记录被一个一个输出完毕而每次置换进来的新记录全部被标记。当最初的m个记录都输出完时工作区里充满了m个被标记的“下一段”记录于是第一个归并段结束。所以第一个归并段的最小长度就是m。即你至少能把工作区里初始的那批记录排好序输出。3.3 优化策略的核心如何逼近最大长度理解边界是为了优化。在实际应用或做题时我们虽然无法控制输入数据但可以深入理解算法从而做出更优的设计或判断。策略一工作区大小m的选择。m越大平均归并段长度约2m就越长生成的段数就越少后续归并的趟数呈对数级下降。这能极大减少磁盘I/O这是置换-选择排序最大的优势。所以在内存允许的范围内应尽可能增大m。在真题中这常常是分析排序总代价时的关键参数。策略二利用数据的局部有序性。置换-选择排序有一个隐藏优点如果输入数据本身存在一定的“趋势”或局部有序它能非常有效地利用这一点生成更长的归并段。比如如果数据是基本递增的那么新记录很容易满足key max_output的条件。相反如果数据完全随机段长度就会接近平均值。在备考时你可以思考如果题目给出的序列是近乎有序的或者完全逆序的生成的段数和长度会有什么变化这能帮你更灵活地应对考题变种。策略三堆维护的代码实现优化。在手动模拟或代码实现时堆的维护是关键。尤其是当堆顶元素被标记为“下一段”后如何高效地找到当前实际可用的最小元素标准的做法是在minHeapify函数中比较元素大小时优先判断标记位。被标记的记录在调整时被视为“无穷大”从而自然下沉。确保你的代码逻辑清晰处理了这种“无效”节点这是写出正确模拟程序的基础。4. 从原理到代码写出无懈可击的模拟程序理解了原理和过程我们最终要落实到代码上。无论是为了应对408的算法题还是为了真正掌握它自己实现一遍置换-选择排序的模拟程序都是必不可少的。下面我结合真题给出一个清晰、健壮且易于理解的C语言实现并附上关键注释。#include stdio.h #include stdlib.h #include stdbool.h #define MAX_SIZE 100 // 记录结构体包含关键字和是否属于下一个归并段的标记 typedef struct { int key; bool isNextRun; // true表示该记录属于下一个归并段 } Record; // 针对置换-选择排序优化的最小堆调整函数 // 核心被标记为下一段的记录(isNextRuntrue)被视为“无限大”在调整中下沉 void minHeapify(Record heap[], int size, int i) { int smallest i; int left 2 * i 1; int right 2 * i 2; // 比较左孩子如果左孩子未被标记并且当前节点被标记 或 左孩子key更小 if (left size !heap[left].isNextRun (heap[smallest].isNextRun || heap[left].key heap[smallest].key)) { smallest left; } // 比较右孩子 if (right size !heap[right].isNextRun (heap[smallest].isNextRun || heap[right].key heap[smallest].key)) { smallest right; } // 如果最小值不是当前节点交换并递归调整 if (smallest ! i) { Record temp heap[i]; heap[i] heap[smallest]; heap[smallest] temp; minHeapify(heap, size, smallest); } } // 建立最小堆 void buildMinHeap(Record heap[], int size) { for (int i size / 2 - 1; i 0; i--) { minHeapify(heap, size, i); } } // 置换-选择排序主函数 void replacementSelection(int keys[], int n, int m) { if (n 0 || m 0) { printf(参数错误\n); return; } Record* workArea (Record*)malloc(m * sizeof(Record)); if (workArea NULL) { printf(内存分配失败\n); return; } int inputIdx 0; // 输入序列指针 int runCount 0; // 归并段计数器 int currentSize 0; // 当前工作区实际记录数可能小于m当输入快读完时 printf(原始关键字序列: ); for (int i 0; i n; i) printf(%d , keys[i]); printf(\n工作区容量 m %d\n\n, m); // 第一阶段初始化工作区 for (currentSize 0; currentSize m inputIdx n; currentSize) { workArea[currentSize].key keys[inputIdx]; workArea[currentSize].isNextRun false; } // 开始生成归并段 while (currentSize 0) { runCount; printf(第%d个归并段: , runCount); int maxOutput -1; // 当前段已输出的最大值初始化为极小值 int runLength 0; // 当前段长度 // 为新归并段重建堆清除之前的标记影响 buildMinHeap(workArea, currentSize); // 循环输出当前归并段 while (1) { // 检查工作区中是否还有属于当前段的记录未被标记 bool hasCurrentRunRecord false; for (int i 0; i currentSize; i) { if (!workArea[i].isNextRun) { hasCurrentRunRecord true; break; } } if (!hasCurrentRunRecord) break; // 全是下一段的记录当前段结束 // 确保堆顶是当前可用的最小记录可能因为标记变动需要重新建堆 buildMinHeap(workArea, currentSize); // 输出堆顶元素 Record minRecord workArea[0]; printf(%d , minRecord.key); runLength; // 更新当前段最大值 if (minRecord.key maxOutput) { maxOutput minRecord.key; } // 尝试从输入文件读取新记录进行置换 if (inputIdx n) { int newKey keys[inputIdx]; workArea[0].key newKey; // 核心判断新记录是否属于当前段 workArea[0].isNextRun (newKey maxOutput); } else { // 输入已耗尽将堆顶记录移出工作区用最后一个元素覆盖 workArea[0] workArea[currentSize - 1]; currentSize--; } // 如果工作区还有元素调整堆以维持性质 if (currentSize 0) { minHeapify(workArea, currentSize, 0); } } printf((长度: %d)\n, runLength); // 当前段结束清除所有记录的标记为下一段做准备 for (int i 0; i currentSize; i) { workArea[i].isNextRun false; } } printf(\n总计生成 %d 个初始归并段。\n, runCount); free(workArea); } int main() { // 2023年408真题数据 int keys[] {51, 94, 37, 92, 14, 63, 15, 99, 48, 56, 23, 60, 31, 17, 43, 8, 90, 166, 100}; int n sizeof(keys) / sizeof(keys[0]); int m 4; printf( 置换-选择排序算法模拟 \n); replacementSelection(keys, n, m); return 0; }这段代码严格遵循了我们之前讨论的算法步骤。有几个细节值得你特别注意isNextRun标记的处理这是算法正确性的核心。在minHeapify函数中被标记的记录在比较时被视为“无限大”这保证了它们不会成为堆顶被输出。归并段结束条件内层while循环开始前通过遍历检查是否还有未被标记的记录来判断当前段是否应继续。输入耗尽时的处理当输入序列读完我们不再读入新记录而是简单地将堆顶元素与工作区最后一个元素交换并减小currentSize相当于从堆中删除该元素。段与段之间的切换一个归并段结束后需要遍历工作区将所有记录的isNextRun标记重置为false。这些被标记的记录正是下一个归并段的“种子”。你可以把这段代码复制到编译器里运行看看输出是否和我们手动模拟的一致。动手调试、跟踪变量的变化是消化这个算法最扎实的方式。5. 408考点延伸与实战答题技巧掌握了核心原理和代码我们最后来聊聊在408考场上关于置换-选择排序可能怎么考以及如何高效准确地作答。常见考点一过程模拟题。就像2023年真题这样给一个序列和m值让你写出生成的归并段。这是最直接的考法。答题技巧在草稿纸上清晰地画出工作区堆的变化过程每步标出max_output和新记录的判断结果。步骤写清楚避免混乱。答案格式要规范例如“共生成x个初始归并段分别为(a1, a2,...), (b1, b2,...)”。常见考点二理论分析题。分析第一个归并段的最大/最小长度或者分析算法的时间/空间复杂度。答题技巧记住结论最大长度2m-1最小长度m。时间复杂度是O(n log m)因为每个记录进出堆一次堆调整代价为O(log m)。空间复杂度是O(m)。回答时最好配上简短的文字解释说明在何种极端情况下达到边界这样能拿满分。常见考点三综合应用题。将置换-选择排序嵌入到一个完整的外部排序问题中。例如给定文件总记录数n、内存容量m、磁盘块大小等信息要求计算采用置换-选择排序生成初始段后再进行k路平衡归并所需的总I/O次数。答题技巧先估算置换-选择排序生成的初始归并段平均长度L通常按2m估算和段数r ceil(n / L)。然后套用多路归并的公式归并趟数S ceil(log_k r)。总I/O次数 读初始文件 写初始归并段 归并过程中读写* 块数。每一步都要清晰列出计算过程。常见考点四算法比较与选择。可能会问为什么用置换-选择排序而不是直接用内部排序生成初始段或者在什么情况下置换-选择排序的优势不明显答题思路紧扣“减少初始归并段数量”这个核心优势。可以这样回答传统方法每个初始段长度固定为m段数多导致后续归并趟数多I/O开销大。置换-选择排序能生成平均长度约2m的段减少了段数从而显著降低了归并趟数和总I/O开销。当输入数据完全随机时优势明显如果数据本身已基本有序优势会更大但如果数据完全逆序则效果可能退化和传统方法类似。在复习时我建议你把历年考过外部排序的真题都找出来集中练习。重点不是背答案而是反复训练“手动模拟”的过程直到你能不假思索地、准确无误地推演出任意给定序列的结果。同时把堆排序、败者树这些相关的数据结构也复习扎实因为它们往往是外部排序算法实现的基石。当你把这些点都串联起来外部排序这一章就再也难不倒你了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…