实验三 产生式系统推理

一、实验目的

本实验课程是计算机、智能、物联网等专业学生的一门专业课程,通过实验,帮助学生更好地掌握人工智能相关概念、技术、原理、应用等;通过实验提高学生编写实验报告、总结实验结果的能力;使学生对智能程序、智能算法等有比较深入的认识。
1.掌握人工智能中涉及的相关概念、算法;
2.熟悉人工智能中的知识表示方法;
3.掌握问题表示、求解及编程实现;
4.理解产生式系统的结构原理与实际应用;
5.掌握产生式规则表示及规则库组建的实现方法;
6.熟悉和掌握产生式系统的运行机制,掌握基于规则推理的基本方法。

二、基本要求

1.实验前,复习《人工智能》课程中的有关内容。
2.准备好实验数据。
3.编程要独立完成,程序应加适当的注释。
4.完成实验报告。

三、实验软件

使用C或C++(Visual studio或其它开发环境)(不限制语言使用)。

四、实验内容:

以动物识别系统为例,用选定的编程语言建造规则库和综合数据库,开发能进行正确的正向推理或反向推理的推理机。
正向推理过程
从已知事实出发,通过规则库求得结论,或称数据驱动方式。推理过程是:
规则集中的规则前件与事实库中的事实进行匹配,得匹配的规则集合。
从匹配规则集合中选择一条规则作为使用规则。
执行使用规则的后件,将该使用规则的后件送入事实库中。
重复这个过程直至达到目标。

1 动物分类规则集
(1)若某动物有奶,则它是哺乳动物。
(2)若某动物有毛发,则它是哺乳动物。
(3)若某动物有羽毛,则它是鸟。
(4)若某动物会飞且生蛋,则它是鸟。
(5)若某动物是哺乳动物且有爪且有犬齿且目盯前方,则它是食肉动物。
(6)若某动物是哺乳动物且吃肉,则它是食肉动物。
(7)若某动物是哺乳动物且有蹄,则它是有蹄动物。
(8)若某动物是有蹄动物且反刍食物,则它是偶蹄动物。
(9)若某动物是食肉动物且黄褐色且有黑色条纹,则它是老虎。
(10)若某动物是食肉动物且黄褐色且有黑色斑点,则它是金钱豹。
(11)若某动物是有蹄动物且长腿且长脖子且黄褐色且有暗斑点,则它是长颈鹿。
(12)若某动物是有蹄动物且白色且有黑色条纹,则它是斑马。
(13)若某动物是鸟且不会飞且长腿且长脖子且黑白色,则它是驼鸟。
(14)若某动物是鸟且不会飞且会游泳且黑白色,则它是企鹅。
(15)若某动物是鸟且善飞且不怕风浪,则它是海燕。
下面是该规则集所形成的(部分)推理网络:
图1 动物识别系统部分推理网络

1.2 问题描述

由上述动物识别规则组成规则库,推理机采用正向推理算法或反向推理算法,实现对动物的查询。
如给出初始事实:
F1:某动物有毛发
F2:吃肉
F3:黄褐色
F4:有黑色条纹
目标条件为:该动物是什么?
3 规则库扩充 (选做)
在上述规则集(Ⅰ)基础上增加以下规则集(Ⅱ):
(1)兔子:有毛发,有奶,善跳跃,唇裂;
(2)猫:有毛发,有奶,善捕鼠,脚有肉垫;
(3)犀牛:有毛发,有奶,鼻子上有角,褐色,皮糙肉后,皮糙肉厚,有蹄;
(4)熊猫:有毛发,有奶,黑眼圈,四肢短小;
(5)鹦鹉:鸟类,上嘴鹰钩,会模仿人说话;
(6)鸭子:鸟类,腿短,嘴扁平,善潜水游泳;
(7)鹰:鸟类,上嘴鹰钩,有爪,吃肉;
(8)鸭子:有羽毛,卵生,善游泳,嘴扁平,腿短;
(9)鹅:有羽毛,卵生,善潜水游泳,白色或黑色,颈长,嘴大,腿长,颈部有肉只凸起;
(10)鸦:有羽毛,卵生,黑色,嘴大;
(11)鹰:有羽毛,卵生,有爪,吃肉,上嘴鹰钩;
(12)鹦鹉:有羽毛,卵生,上嘴鹰钩,能模仿人说话;
(13)青蛙:卵生,生活在水中,生活在陆地,有皮肤呼吸,用肺呼吸,皮肤光滑,吃昆虫,会变色;
(14)蝾螈:卵生,生活在水中,生活在陆地,有皮肤呼吸,用肺呼吸,吃昆虫,皮肤粗糙,四肢扁,背部黑色;
(15)蟾蜍:卵生,生活在水中,生活在陆地,有皮肤呼吸,用肺呼吸,吃昆虫,皮肤粗糙;
(16)比目鱼:用鳃呼吸,身体有鳍,生活在海洋中,身体扁平,两眼在头部同侧;
(17)鲫鱼:用鳃呼吸,身体有鳍,生活在淡水中,身体扁平,头高尾部窄;
(18)蛇:生活在陆地,用肺呼吸,胎生,身体有鳞或甲,身体圆而细长,吃小动物;
(19)壁虎:生活在陆地,用肺呼吸,胎生,身体有鳞或甲,有四肢,尾巴细长易断,吃昆虫;
(20)乌龟:生活在陆地,用肺呼吸,胎生,身体有鳞或甲,身体圆而扁,有坚硬的壳;
(21)玳瑁:生活在陆地,用肺呼吸,胎生,身体有鳞或甲,壳为黄褐色,皮肤光滑,有黑斑;
(22)鳄鱼:生活在陆地,用肺呼吸,胎生,身体有鳞或甲,有四肢,善游泳,皮硬黑褐色。
要求在动物分类规则集(Ⅰ)的基础上添加上述22条知识,共构成29种动物的知识库系统,对原有动物分类系统进行扩充和修改。

五、实验程序组成

(1)使用的结构
Rule类,类中存放一个int类型的指针和重载了一个运算符 == ,用于后续与int类型的数组作比较。
(2)使用的各种函数
//用于中间状态操作的函数
Bool include(Rule rule, int *ch); //判断ch中含有rule全部元素
Void clean(Rule rule, int *ch); //删除ch中与rule相同的元素
bool zero(int *ch); //判断ch中是否全部元素都为0
Bool check(int *ch, int *p); //判断ch中是否还含有p中元素
//规则库函数
Int rule1(int *ch); //一级规则,可以直接由条件推理出
Int rule2(int *ch, int rule1); //二级规则,需要结合一级推理结果
Int rule3(int *ch, int rule2); //三级规则,需要结合二级推理结果
//推理结果处理函数
Int result(int *ch, int rule3); //根据rule3的结果进行分析
Void show(int a); //根据推理得出的序号输出相应文字
(3)部分实验代码:

//规则库
int rule1(int* ch) {if (!zero(ch)) {//有奶->哺乳动物Rule rule1;int t1=1;rule1.rule = &t1;if (include(rule1, ch)) {clean(rule1, ch);return 24;}//有毛发->哺乳动物Rule rule2;int t2=2;rule2.rule = &t2;if (include(rule2, ch)) {clean(rule2, ch);return 24;}//有羽毛->鸟Rule rule3;int t3 = 3;rule3.rule = &t3;if (include(rule3, ch)) {clean(rule3, ch);return 25;}//会飞,能生蛋->鸟Rule rule4;int t[2] = { 4,5 };rule4.rule = &t[0];if (include(rule4, ch)) {clean(rule4, ch);return 25;}}elsereturn 0;
}int rule2(int* ch, int rule1) {if (!zero(ch)) {switch (rule1) {//哺乳动物case 24: {//有爪,有犬齿,目盯前方->食肉动物Rule rule5;int t[3] = { 6,7,8 };rule5.rule = &t[0];if (include(rule5, ch)) {clean(rule5, ch);return 26;}//吃肉->食肉动物Rule rule6;int t1 = 9;rule6.rule = &t1;if (include(rule6, ch)) {clean(rule6, ch);return 26;}//有蹄->有蹄动物Rule rule7;int t2 = 10;rule7.rule = &t2;if (include(rule7, ch)) {clean(rule7, ch);return 27;}return 24;};//鸟case 25: {//不会飞,长腿,长脖子,黑白色->鸵鸟Rule rule8;int t[4] = { 14,15,19,20 };rule8.rule = &t[0];if (include(rule8, ch)) {clean(rule8, ch);return 33;}//不会飞,会游泳,黑白色->企鹅Rule rule9;int t1[3] = { 19,20,21 };rule9.rule = &t1[0];if (include(rule9, ch)) {clean(rule9, ch);return 34;}//善飞,不怕风浪->海燕Rule rule10;int t2[2] = { 22,23 };rule10.rule = &t2[2];if (include(rule10, ch)) {clean(rule10, ch);return 35;}return 25;};}}elsereturn rule1;
}int rule3(int* ch, int rule2) {if (!zero(ch)) {switch (rule2) {//食肉动物case 26: {//黄褐色,黑色条纹->老虎Rule rule11;int t1[2] = { 12,17 };rule11.rule = &t1[0];if (include(rule11, ch)) {clean(rule11, ch);return 29;}//黄褐色,黑色斑点->金钱豹Rule rule12;int t2[2] = { 12,13 };rule12.rule = &t2[0];if (include(rule12, ch)) {clean(rule12, ch);return 30;}return 26;};//有蹄动物case 27: {//反刍->偶蹄动物Rule rule13;int t1 = 11;rule13.rule = &t1;if (include(rule13, ch)) {clean(rule13, ch);return 28;}//长腿,长脖子,黄褐色,暗斑点->长颈鹿Rule rule15;int t3[4] = { 12,14,15,16 };rule15.rule = &t3[0];if (include(rule15, ch)) {clean(rule15, ch);return 31;}//白色,黑色条纹->斑马Rule rule14;int t4[2] = { 17,18 };rule14.rule = &t4[0];if (include(rule14, ch)) {clean(rule14, ch);return 32;}return 27;};}return rule2;}elsereturn rule2;
}

六、实验结果分析:

初始界面:

输入题设条件:

得出结果:

实验心得:

①实验中采用了对规则的分级保证了推理的中间过程的完善性,不过这也使得本程序中的可用规则全为最基本的规则,若是从中间过程开始的推理,如推理条件以哺乳动物为基本条件的推理,需要用于自行推理出哺乳动物的基本条件。②规则库与记录用户输入条件的数组以指针*ch的形式存放,原本在确定条件数量的时候想用ch[]!=NULL的,可是会出现越界的情况,后来观察错误发现越界后数值都十分大或小,故重新设置边界条件为-50~50用来计算条件数量,也算一种取巧。

完整代码:

#include<iostream>
using namespace std;//单条规则形式
class Rule {public:int *rule;bool operator ==(int *ch);
};
bool Rule::operator==(int *ch) {int i = 0;while (ch[i] > -50 && ch[i] < 50) {if (rule[i] != ch[i])return true;i++;}return false;
}//读取拥有函数
bool include(Rule rule,int *ch) {int rulelong=0, same=0;while (-50<rule.rule[rulelong] && rule.rule[rulelong]<50)rulelong++;;//检测ch有效长度内使用含有与rule数组相同数量的元素for (int i = 0; ch[i]>-50 && ch[i]<50; i++) {for (int m = 0; m < rulelong; m++) {if (rule.rule[m] == ch[i])same++;       }}if (same == rulelong)return true;else return false;
}
//删除已使用过的条件:在ch中删除相应规则rule1
void clean(Rule rule,int* ch) { int rulelong = 0, i = 0;while (rule.rule[rulelong] > -50 && rule.rule[rulelong] <50)                 rulelong++;while (ch[i] > -50 && ch[i] < 50) {int m = 0;while (m < rulelong) {if (rule.rule[m] == ch[i]) {ch[i] = 0;break;}m++;}i++;}
}
//全0判断
bool zero(int* ch) {int i = 0;while (ch[i] > -50 && ch[i] < 50) {if (ch[i] != 0)return false;i++;}return true;
}
//重复元素检查:ch中是否还含有p中的元素,true为可用重复,false为不可用重复
bool check(int* ch,int *p) {int same = 0,chlong=0;while (ch[chlong] >-50 && ch[chlong]<50)chlong++;//复制ch数组int* chcopy=new int[chlong];for (int i = 0; i < chlong; i++) {chcopy[i] = ch[i];}//先将0项加入same值中for (int i = 0; i < chlong; i++)if (chcopy[i] == 0)same++;//做相同分析for (int i = 0; i<chlong; i++)for (int m = 0; -50<p[m] && p[m]<50; m++)if (chcopy[i] == p[m] ) {same++;chcopy[i] = 0;}//比较same和ch长度if (same == chlong)return true;elsereturn false;
}//规则库
int rule1(int* ch) {if (!zero(ch)) {//有奶->哺乳动物Rule rule1;int t1=1;rule1.rule = &t1;if (include(rule1, ch)) {clean(rule1, ch);return 24;}//有毛发->哺乳动物Rule rule2;int t2=2;rule2.rule = &t2;if (include(rule2, ch)) {clean(rule2, ch);return 24;}//有羽毛->鸟Rule rule3;int t3 = 3;rule3.rule = &t3;if (include(rule3, ch)) {clean(rule3, ch);return 25;}//会飞,能生蛋->鸟Rule rule4;int t[2] = { 4,5 };rule4.rule = &t[0];if (include(rule4, ch)) {clean(rule4, ch);return 25;}}elsereturn 0;
}int rule2(int* ch, int rule1) {if (!zero(ch)) {switch (rule1) {//哺乳动物case 24: {//有爪,有犬齿,目盯前方->食肉动物Rule rule5;int t[3] = { 6,7,8 };rule5.rule = &t[0];if (include(rule5, ch)) {clean(rule5, ch);return 26;}//吃肉->食肉动物Rule rule6;int t1 = 9;rule6.rule = &t1;if (include(rule6, ch)) {clean(rule6, ch);return 26;}//有蹄->有蹄动物Rule rule7;int t2 = 10;rule7.rule = &t2;if (include(rule7, ch)) {clean(rule7, ch);return 27;}return 24;};//鸟case 25: {//不会飞,长腿,长脖子,黑白色->鸵鸟Rule rule8;int t[4] = { 14,15,19,20 };rule8.rule = &t[0];if (include(rule8, ch)) {clean(rule8, ch);return 33;}//不会飞,会游泳,黑白色->企鹅Rule rule9;int t1[3] = { 19,20,21 };rule9.rule = &t1[0];if (include(rule9, ch)) {clean(rule9, ch);return 34;}//善飞,不怕风浪->海燕Rule rule10;int t2[2] = { 22,23 };rule10.rule = &t2[2];if (include(rule10, ch)) {clean(rule10, ch);return 35;}return 25;};}}elsereturn rule1;
}int rule3(int* ch, int rule2) {if (!zero(ch)) {switch (rule2) {//食肉动物case 26: {//黄褐色,黑色条纹->老虎Rule rule11;int t1[2] = { 12,17 };rule11.rule = &t1[0];if (include(rule11, ch)) {clean(rule11, ch);return 29;}//黄褐色,黑色斑点->金钱豹Rule rule12;int t2[2] = { 12,13 };rule12.rule = &t2[0];if (include(rule12, ch)) {clean(rule12, ch);return 30;}return 26;};//有蹄动物case 27: {//反刍->偶蹄动物Rule rule13;int t1 = 11;rule13.rule = &t1;if (include(rule13, ch)) {clean(rule13, ch);return 28;}//长腿,长脖子,黄褐色,暗斑点->长颈鹿Rule rule15;int t3[4] = { 12,14,15,16 };rule15.rule = &t3[0];if (include(rule15, ch)) {clean(rule15, ch);return 31;}//白色,黑色条纹->斑马Rule rule14;int t4[2] = { 17,18 };rule14.rule = &t4[0];if (include(rule14, ch)) {clean(rule14, ch);return 32;}return 27;};}return rule2;}elsereturn rule2;
}//推理结果处理
int result(int *ch,int rule3) {//三重推理后还有剩余元素if (!zero(ch)) {//剩余有效重复元素正常返回,无效重复元素返回0switch (rule3) {case 24: {int t1[2] = { 1,2 };int* p1 = &t1[0];if (check(ch, p1))                                 //未通过check判定return 24;elsereturn 0;          //查无此动物}case 25: {int t2[3] = { 3,4,5 };int* p2 = &t2[0];if (check(ch, p2))return 25;elsereturn 0;}case 26: {int t3[6] = { 1,2,6,7,8,9 };int* p3 = &t3[0];if (check(ch, p3))return 26;elsereturn 0;     }case 27: {int t4[] = { 1,2,10 };int* p4 = &t4[0];if (check(ch, p4))return 27;elsereturn 0;       }case 28: {int t5[] = { 1,2,10,11 };int* p5 = &t5[0];if (check(ch, p5))return 28;elsereturn 0;    }case 29: {int t6[] = {1,2,6,7,8,9,12,17};int* p6 = &t6[0];if (check(ch, p6))return 29;elsereturn 0;      }case 30: {int t7[] = {1,2,6,7,8,9,12,13};int* p7 = &t7[0];if (check(ch, p7))return 30;elsereturn 0;      }case 31: {int t8[] = {1,2,10,12,14,15,16};int* p8 = &t8[0];if (check(ch, p8))return 31;elsereturn 0; }case 32: {int t9[] = {1,2,10,17,18};int* p9 = &t9[0];if (check(ch, p9))return 32;elsereturn 0;       }case 33: {int t10[] = {3,4,5,14,15,19,20};int* p10 = &t10[0];if (check(ch, p10))return 33;elsereturn 0;      }case 34: {int t11[] = {3,4,5,19,20,21};int* p11 = &t11[0];if (check(ch, p11))return 34;elsereturn 0;     }case 35: {int t12[] = { 3,4,5,22,23 };int* p12 = &t12[0];if (check(ch, p12))return 35;elsereturn 0;      }       }   }//三种推理后无剩余元素else return rule3;
}
//根据返回值进行输出
void show(int a){switch (a) {case 0: {cout << "根据给出条件,数据库中不存在此类动物,请重新输入" << endl;break;}case 24: {cout << "根据给出条件,所查询出结果为:哺乳动物" << endl;break;  }case 25: {cout << "根据给出条件,所查询出结果为:鸟" << endl;break;}case 26: {cout << "根据给出条件,所查询出结果为:食肉动物" << endl;break;}case 27: {cout << "根据给出条件,所查询出结果为:有蹄动物" << endl;break;}case 28: {cout << "根据给出条件,所查询出结果为:偶蹄动物" << endl;break;}case 29: {cout << "根据给出条件,所查询出结果为:老虎" << endl;break;}case 30: {cout << "根据给出条件,所查询出结果为:金钱豹" << endl;break;}case 31: {cout << "根据给出条件,所查询出结果为:长颈鹿" << endl;break;}case 32: {cout << "根据给出条件,所查询出结果为:斑马" << endl;break;}case 33: {cout << "根据给出条件,所查询出结果为:鸵鸟" << endl;break;}case 34: {cout << "根据给出条件,所查询出结果为:企鹅" << endl;break;}case 35: {cout << "根据给出条件,所查询出结果为:海燕" << endl;break;}}
}void main() {aceu:cout << "********产生式系统推理——动物识别系统*********" << endl;//输出序号以及所有条件图cout << "1.有奶          2.有毛发      3.有羽毛        4.会飞" << endl;cout << "5.能生蛋        6.有爪        7.有犬齿        8.目盯前方" << endl;cout << "9.吃肉          10.有蹄       11.反刍         12.黄褐色" << endl;cout << "13.黑色斑点     14.长腿       15.长脖子       16.暗斑点" << endl;cout << "17.黑色条纹     18.白色       19.不会飞       20.黑白色" << endl;cout << "21.会游泳       22.善飞       23.不怕风浪" << endl<<endl;cout << "请输入查询动物的特征序号,以‘0’结束" << endl;//测试创建指针数组int test[20] = { 0 };int q = 1;for (int i = 0; q != 0; i++) {cin >> test[i];q = test[i];}//读数,并写入ch数组int num = 0;while (test[num] != 0)num++;int* ch = new int[num];for (int i = 0; i < num; i++)ch[i] = test[i];show(result(ch, rule3(ch, rule2(ch, rule1(ch)))));int re;cout <<endl<<endl<<"******************************************************"<<endl<< "请输入一个数以便继续,输入0则退出" << endl;cin >> re;if (re != 0) {system("cls");goto aceu;}
}

动物识别——人工智能相关推荐

  1. java动物识别_java编写的专家系统(人工智能)动物识别

    import java.awt.*; //包含用于建立用户界面和绘制图形图像的全部类 import java.awt.event.*;   //提供处理由 AWT 组件所激发的各种事件的接口和类人工智 ...

  2. 动物识别系统代码python_动物识别 python 人工智能实验

    构建动物识别系统 系统分为两部分,第一部分是初始化综合数据库,分为两类,一类是间接数据库,即不指向最终动物的信息.另一类是直接数据库,即指向最终动物的信息.使用的是二维列表加上一个一维列表存储key与 ...

  3. 动物识别系统c语言编程,人工智能期末论文-简单动物识别系统的知识表示.doc

    简单动物识别系统的知识表示 摘要:动物识别系统是人工智能领域中基础也是非常具有代表性的一个智能系统智能系统最基本的组成部分即知识系统成为了研究热点.本文首先介绍知识系统的基本及作用,以动物识别系统的式 ...

  4. 人工智能导论-动物识别专家系统

    动物识别专家系统实验 这个人工智能导论实验可算是折磨了我许久,关键是我一直想不明白该如何推理. 在某天的晚上,我去对象那里上晚自习,突然灵感大开.由于电脑没有电了,我就手绘了一个系统结构图,并且想到了 ...

  5. 人工智能实验-动物识别系统

    ** 实验一:产生式系统实验 ** 一.实验目的: 熟悉一阶谓词逻辑和产生式表示法,掌握产生式系统的运行机制,以及基于规则推理的基本方法. 二.实验内容: 设计并编程实现一个小型产生式系统(如分类.诊 ...

  6. 动物识别系统代码python_人工智能-动物识别专家系统算法Python + Pyqt 实现

    #-*- coding: utf-8 -*- #Form implementation generated from reading ui file '动物识别专家系统.ui'# #Created b ...

  7. 人工智能-动物识别系统

    在本系统当中,知识库中的知识用产生式规则来表示,共有如下15条规则. R1 IF该动物有奶THEN该动物是哺乳动物 R2 IF该动物有毛发THEN该动物是哺乳动物 R3 IF该动物有羽毛THEN该动物 ...

  8. 人工智能实验:动物识别系统(C++代码实现)

    问题描述 建立一个动物识别系统的规则库,编写程序用以识别虎.豹.斑马.长颈鹿.企鹅.鸵鸟.信天翁等7种动物. 为了识别这些动物,可以根据动物识别的特征,建立包含下述规则库: R1:if 动物有毛发 t ...

  9. python动物专家系统_用Python实现一个动物识别专家系统--人工智能作业分享

    考察 产生式系统 我猜在搜索引擎的茫茫大海中,你能看见我的这篇文章不是缘分,而是你要交作业了(抖机灵) 求点赞,给作者一点分享的鼓励 代码没写GUI,因为不喜欢这玩意,直接在终端中进行人机交互.使用代 ...

最新文章

  1. xcode8控制台输出大量不用的log的问题解决NSLog失效的解决
  2. bottle+jquery 前后端分离
  3. C/C++ 语言的常用开发工具下载
  4. SpringBoot(一)_快速实战搭建项目
  5. CORS 跨域-哪些操作不受同源限制
  6. [转]如何完美应对面试
  7. CCNA笔记之第二十节:RIP协议(大实验4)
  8. 习题2.7 弹球距离 (15 分)
  9. 在WPF中嵌入WebBrowser可视化页面
  10. Spire.pdf-使用学习记录
  11. 高效记忆/形象记忆(07)110数字编码表 11-20
  12. c/c++:双人对战五子棋源代码
  13. 计算机组装图与名称,台式电脑组装硬件配置名称
  14. matlab的罗马数字怎么写好看图解,【我想知道1—100的罗马数字怎样写啊就是ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪ这些等】作业帮...
  15. Exchange 2013 启用反垃圾邮件功能
  16. phpword 实现word文件模板字符替换
  17. R语言保存png,pdf文件出现文件损坏或空白问题的解决方案
  18. 软件开发经验总结(容错性)
  19. [转]Ubuntu 小企鹅输入法fcitx 支持 五笔拼音
  20. 射频链路隔直电容选择

热门文章

  1. lisp如何批量选中特定图层_CAD里怎样一键选中某一个图层的所有内容?
  2. isalpha() / isupper() / islower()函数
  3. 09-Httprunner-生成测试报告
  4. eclipse性能调查工具tptp的使用方法
  5. python_pygame.外星人入侵
  6. 嘿,妈妈,我是设计师
  7. SAP 批量修改或添加BOM组件
  8. 罗技推出“语音鼠标”,隐藏着百度AI的产业化范式
  9. 慕容垂:百万战骨风云里——激荡的鲜卑史略之一(转载)
  10. 【使用TL431校准万用表】