人工智能基础实践课代码(一) 产生式推理(动物识别系统)+极大极小值(一字棋)+ 遗传算法

1、实验目的

理解和掌握产生式系统的推理方法,能够用选定的编程语言实现推理机。

2、实验内容和要求

(1)以实验1的动物识别系统的规则库和综合数据库为基础;
(2)用选定的编程语言开发一个推理机,该推理机能利用实验1的规则库和综合数据库进行推理。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

话不多说,直接上代码

C++版本
运行截图
在这里插入图片描述

#include<iostream>
#include<string>
#include<cstdlib>
#include<iomanip>
#include<list>
 
using namespace std;
 
const int fact_num = 31;      //知识库中的知识:31种知识
const int rule_num = 15;      //知识库中的规则:15条规则
const int rule_volume = 4;    //规则中每个结果最多有4个前提条件
const int object_range_begin = 25;  //从第25个知识开始
const int object_range_end = 31;    //到第31个知识为目标结论
const int object_middle_begin = 21;     //中间结果起始位置 
 
string fact[fact_num] =               
{
    
    
	"有毛发","产奶","有羽毛","会飞","会下蛋",
	"吃肉","有犬齿","有爪","眼盯前方","有蹄",
	"反刍","黄褐色","有斑点","有黑色条纹","长脖",
	"长腿","不会飞","会游泳","黑白二色","善飞",
	"哺乳类","鸟类","食肉类","蹄类","金钱豹",
	"虎","长颈鹿","斑马","鸵鸟","企鹅","信天翁"
};
 
int rule_prerequisite[rule_num][rule_volume] =      
{
    
    
	{
    
    1,0,0,0},
	{
    
    2,0,0,0},
	{
    
    3,0,0,0},
	{
    
    4,5,0,0},
	{
    
    21,6,0,0},
	{
    
    7,8,9,0},
	{
    
    21,10,0,0},
	{
    
    21,11,0,0},
	{
    
    23,12,13,0},
	{
    
    23,12,14,0},
	{
    
    24,15,16,13},
	{
    
    24,14,0,0},
	{
    
    22,15,16,4},
	{
    
    22,18,19,4},
	{
    
    22,20,0,0}
};
 
int rule_result[rule_num] =
{
    
    
	21,
	21,
	22,
	22,
	23,
	23,
	24,
	24,
	25,
	26,
	27,
	28,
	29,
	30,
	31
};
 
bool backward_reasoning(int num,int message[]) ;
bool inference(int num,int message[])         //迭代推理机
{
    
    
	int ii, ij, ik,im,in;
	int hit_num = 0;          //输入前提也规则前提重合数
	int prerequisite_num;     //规则前提数
	int *message_c;           //迭代前提
	int num_c;                //迭代前提数量
	for (ik = 0; ik < num; ik++)     //剪枝函数
	{
    
    
		if (message[ik] >= object_range_begin&&message[ik] <= object_range_end)
		{
    
    
			cout << "归并信息:" << fact[message[ik] - 1] << endl;
			cout << "推理成功!" << endl<<endl;
			system("pause");
			exit(0);
		}
	}
	for (ii = 0; ii < rule_num; ii++)   //遍历规则匹配
	{
    
    
		prerequisite_num = 0;
		hit_num = 0;
		for (ij = 0; ij < rule_volume; ij++)   //计算规则集前提数
		{
    
    
			if (rule_prerequisite[ii][ij] == 0)
			{
    
    
				break;
			}
			prerequisite_num++;
		}
		for (ij = 0; ij < prerequisite_num; ij++)
		{
    
    
			for (ik = 0; ik < num; ik++)
			{
    
    
				if (rule_prerequisite[ii][ij] == message[ik])
				{
    
    
					hit_num++;
				}
			}
		}
		if (hit_num == prerequisite_num)  //满足某个规则集全部前提
		{
    
    
			bool flag;
			for (ik = 0; ik < num; ik++)
			{
    
    
				if (message[ik] == rule_result[ii])
				{
    
    
					break;
				}
			}
			if (ik == num)
			{
    
    
				num_c=num - hit_num+1;
				flag = true;
			}
			else
			{
    
    
				num_c = num - hit_num;
				flag = false;
			}
			message_c = new int[num_c];
			in = 0;
			for (ik = 0; ik < num; ik++)
			{
    
    
				for (im = 0; im < hit_num; im++)
				{
    
    
					if (rule_prerequisite[ii][im] == message[ik])
					{
    
    
						break;
					}
				}
				if (im < hit_num)
				{
    
    
					continue;
				}
				message_c[in++] = message[ik];
			}
			if (flag == true)
			{
    
    
				message_c[in] = rule_result[ii];
			}
			cout << "推导信息:";
			for (int iz = 0; iz < num; iz++)
			{
    
    
				cout << fact[message[iz]-1] << " ";
			}
			cout << endl;
			return inference(num_c,message_c);
		}
	}
	cout << "归并信息:";
	for (int iz = 0; iz < num; iz++)
	{
    
    
		cout << fact[message[iz]-1] << " ";
	}
	cout << endl;
	backward_reasoning(num,message);
	return false;
}
 
bool backward_reasoning(int num,int message[])   //反向推理
{
    
    
	int ii,ij,ik;
	int prerequisite_num = 0;
	int hit_num = 0;
	int need_rule_number[rule_num];
	int hit_rule_number[rule_num];
	float hit_rule_rate[rule_num];
	float best_hit_rule_rate=0;
	int best_hit_rule_number;
	int *new_message;
	for (ii = 0; ii < rule_num; ii++)   //遍历规则匹配
	{
    
    
		prerequisite_num=0;
		hit_num=0;
		for (ij = 0; ij < rule_volume; ij++)   //计算规则集前提数
		{
    
    
			if (rule_prerequisite[ii][ij] == 0)
			{
    
    
				break;
			}
			prerequisite_num++;
		}
		need_rule_number[ii]=prerequisite_num;
		for (ij = 0; ij < prerequisite_num; ij++)   //计算输入信息命中规则集中的前提数
		{
    
    
			for (ik = 0; ik < num; ik++)
			{
    
    
				if (rule_prerequisite[ii][ij] == message[ik])
				{
    
    
					hit_num++;
				}
			}
		}
		hit_rule_number[ii]=hit_num;
		hit_rule_rate[ii]=(float)hit_num/prerequisite_num;  //命中率
		for(ij=0;ij<num;ij++)
		{
    
    
			if(message[ij]==rule_result[hit_rule_number[ii]])
			{
    
    
				break;
			}
		}
		if(hit_rule_rate[ii]==1&&ij==num)
		{
    
    
			new_message=new int[num+1];
			for(ik=0;ik<num;ik++)
			{
    
    
				new_message[ik]=message[ik];
			}
			new_message[num]=rule_result[hit_rule_number[ii]];
			num++;
			return inference(num,new_message);
		}
		cout<<"rule "<<setw(2)<<ii<<" -> "<<setw(8)<<fact[rule_result[ii]-1]
		<<"命中率:"<<hit_rule_rate[ii]<<endl;
	}
	best_hit_rule_number=-1;
	for(ii=0;ii<rule_num;ii++)
	{
    
    
		if(best_hit_rule_rate<hit_rule_rate[ii]&&
			rule_result[ii]>=object_middle_begin)
		{
    
    
			best_hit_rule_rate=hit_rule_rate[ii];
			best_hit_rule_number=ii;
		}
	}
	if(best_hit_rule_number==-1)
	{
    
    
		cout<<"您输入的信息对本系统无效!按任意键退出..."<<endl<<endl;
		system("pause");
		exit(0);
	}
	cout<<endl;
	cout<<"best_hit_rule_number="<<best_hit_rule_number<<endl;
	cout<<"best_hit_rule_rate="<<best_hit_rule_rate<<endl;
	cout<<"最佳匹配最终结果="<<fact[rule_result[best_hit_rule_number]-1]<<endl;
	for(ii=0;ii<need_rule_number[best_hit_rule_number];ii++)
	{
    
    
		for(ij=0;ij<num;ij++)
		{
    
    
			if(rule_prerequisite[best_hit_rule_number][ii]==message[ij])
			{
    
    
				break;
			}
		}
		if(ij!=num)
		{
    
    
			continue;
		}
		else
		{
    
    
			if(rule_prerequisite[best_hit_rule_number][ii]<object_middle_begin)
			{
    
    
				cout<<endl<<"请问您持有的信息是否包含\"";
				cout<<fact[rule_prerequisite[best_hit_rule_number][ii]-1];
				cout<<"\"?(y or n)"<<endl;
				char input;
				while(true)
				{
    
    
					cin>>input;
					if(input=='n')
					{
    
    
						new_message=new int[num];
						for(ik=0;ik<num;ik++)
						{
    
    
							new_message[ik]=message[ik];
						}
						break;
					}
					else if(input=='y')
					{
    
    
						new_message=new int[num+1];
						for(ik=0;ik<num;ik++)
						{
    
    
							new_message[ik]=message[ik];
						}
						new_message[num]=rule_prerequisite[best_hit_rule_number][ii];
						num++;
						return inference(num,new_message);
					}
					else
					{
    
    
						cout<<"请重新输入(y or n)!";
					}
				}
			}
			else      //询问是否有中间结果rule_prerequisite[best_hit_rule_number][ii]
			{
    
    	
				int middle_result=rule_prerequisite[best_hit_rule_number][ii];
				for(ii=0;ii<rule_num;ii++)
				{
    
    
					if(rule_result[ii]==middle_result)
					{
    
    
						for(ik=0;ik<need_rule_number[ii];ik++)
						{
    
    
							if(rule_prerequisite[ii][ik]>=object_middle_begin-1)
							{
    
    
								continue;
							}
							for(ij=0;ij<num;ij++)
							{
    
    
								if(rule_prerequisite[ii][ik]==message[ij])
								{
    
    
									break;
								}
							}
							if(ij!=num)
							{
    
    
								continue;
							}
							else
							{
    
    
								cout<<endl<<"请问您持有的信息是否包含\"";
								cout<<fact[rule_prerequisite[ii][ik]-1];
								cout<<"\"?(y or n)"<<endl;
								char input;
								while(true)
								{
    
    
									cin>>input;
									if(input=='n')
									{
    
    
										break;
									}
									else if(input=='y')
									{
    
    
										new_message=new int[num+1];
										for(int iq=0;iq<num;iq++)
										{
    
    
											new_message[iq]=message[iq];
										}
										new_message[num]=rule_prerequisite[best_hit_rule_number][ii];
										num++;
										return inference(num,new_message);
									}
									else
									{
    
    
										cout<<"请重新输入(y or n)!";
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
 
int main(int argc, char **argv)
{
    
    
	bool flag;
	int num;
	int *message;
	int ii,ij;
	cout<<"《知识库》"<<endl;
	for(ii=0;ii<fact_num;ii++)
	{
    
    
		cout<<setiosflags(ios::left);
		cout<<setw(2)<<ii+1<<":"<<setw(10)<<fact[ii]<<"  ";
		if(ii%4==0)
		{
    
    
			cout<<endl;
		}
	}
	cout <<endl<<endl<< "请输入初始信息个数:(数字)" << endl;
	cin >> num;
	message = new int[num];
	cout << "请输入已有信息:(不重复的数字,以空格隔开)" << endl;
	for (ii = 0; ii < num; ii++)
	{
    
    
		cin >> message[ii];
	}
	cout << endl << "初始信息:";
	for (ij = 0; ij < num; ij++)
	{
    
    
		cout << fact[message[ij]-1] << " ";
	}
	cout << endl<<endl;
	if(!inference(num,message))
	{
    
    
		cout<<"通过您的输入无法得出结果!"<<endl;
	}
	system("pause");
	return 0;
}

Python 图形交互与语音播报

运行截图
在这里插入图片描述

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

# __author__:cv调包侠
from tkinter.filedialog import *
from tkinter import ttk
import tkinter
import tkinter.messagebox
import pyttsx3
import pyttsx3.drivers
import pyttsx3.drivers.sapi5
teacher = pyttsx3.init('sapi5')
voices = teacher.getProperty('voices')
# for i in voices:
#     teacher.setProperty('voice', i.id)
#     teacher.say('asdjfadf')
#     teacher.say('aaaaa')
# __author__:cv调包侠

import tkinter as tk
import csv

mammal1 = ["有奶"]
mammal2 = ["有毛发"]
Ungulates1 = ["有蹄", "mammal"]
Ungulates2 = ["mammal", "嚼反刍动物"]
birds1 = ["有羽毛"]
birds2 = ["会飞", "下蛋"]
Carnivores1 = ["吃肉"]
Carnivores2 = ["有犬齿", "有爪", "眼盯前方"]

leopard = ["Carnivores", "mammal", "黄褐色", "暗斑点"]
tiger = ["Carnivores", "mammal", "黄褐色", "黑色条纹"]
ostrich = ["bird", "长脖子", "长腿", "不会飞", "黑白二色"]
penguin = ["bird", "会游泳", "不会飞", "黑白二色"]
Albatross = ["bird", "会飞"]
zebra = ["Ungulates", "黑色条纹"]
giraffe = ["长脖子", "长腿", "暗斑点", "Ungulates"]
mammal = [mammal1, mammal2]
Ungulates = [Ungulates1, Ungulates2]
birds = [birds1, birds2]
Carnivores = [Carnivores1, Carnivores2]

class Surface(ttk.Frame):
    pic_path = ""
    viewhigh = 600
    viewwide = 600
    update_time = 0
    thread = None
    thread_run = False
    camera = None

    def __init__(self, win):
        ttk.Frame.__init__(self, win)
        frame_left = ttk.Frame(self)
        frame_right1 = ttk.Frame(self)
        frame_right2 = ttk.Frame(self)
        win.title("动物识别系统")

        # win.state("zoomed")   # 全屏
        # win.configure(background='pink')   # 去掉注释换颜色

        self.pack(fill=tk.BOTH, expand=tk.YES, padx="5", pady="5")
        frame_left.pack(side=LEFT, expand=1, fill=BOTH)
        frame_right1.pack(side=TOP, expand=1, fill=tk.Y)
        frame_right2.pack(side=RIGHT, expand=0, fill='both')
        ttk.Label(frame_left, text='').pack(anchor="nw")
        ttk.Label(frame_right1, text='').grid(column=0, row=0, sticky=tk.W)
        from_world_ctl = ttk.Button(frame_right2, text="输入特征", width=40, command=self.input)
        from_pic_ctl = ttk.Button(frame_right2, text="输出特征", width=40, command=self.output)
        # from_pic_ctl2 = ttk.Button(frame_right2, text="继续输入", width=40, command=self.output1)

        self.text = Entry(win, show=None, width=41, bg='cyan')  # 括号内增加  ,bg ='cyan' 文本框换颜色

        self.image_ctl = ttk.Label(frame_left)
        self.image_ctl.pack(anchor="nw")

        self.roi_ctl = ttk.Label(frame_right1)
        self.roi_ctl.grid(column=0, row=1, sticky=tk.W)
        ttk.Label(frame_right1, text='识别结果:').grid(column=0, row=2, sticky=tk.W)
        self.r_ctl = ttk.Label(frame_right1, text="")
        self.r_ctl.grid(column=0, row=3, sticky=tk.W)
        self.color_ctl = ttk.Label(frame_right1, text="", width="40")
        self.color_ctl.grid(column=0, row=4, sticky=tk.W)
        # from_vedio_ctl.pack(anchor="se", pady="5")
        # from_pic_ctl3.pack(anchor="se", pady="5")
        self.text.pack(anchor="se", pady="5")
        # from_vedio_ctl1.pack(anchor="se", pady="5")
        # from_vedio_ctl2.pack(anchor="se", pady="5")
        from_world_ctl.pack(anchor="se", pady="5")
        from_pic_ctl.pack(anchor="se", pady="5")

    def from_words(self):
        pass

    def parse(self):
        worlds = self.text.get()
        k = 0
        if not worlds:
            k = 1
            tkinter.messagebox.showwarning('警告', '输入为空,请重新输入!')
        # worlds = "暗斑点 长脖子 长腿 有奶 有蹄"
        features = [i for i in worlds.split(' ')]
        print(features)
        flag = 0
        for mammals in mammal:
            i = 0
            for feature in features:
                if feature in mammals:
                    features.append('mammal')
                    i = 1
                    flag = 1
                    tkinter.messagebox.showinfo('识别过程', '这个动物属于:mamals')
                    for i in voices:
                        teacher.setProperty('voice', i.id)
                        teacher.say('识别成功,这个动物属于:mamals(哺乳动物)')
                        teacher.runAndWait()
                    break
            # if i == 1:
            #     return
        for Ungulate in Ungulates:
            i = 0
            for feature in features:
                if feature in Ungulate:
                    features.append('Ungulates')
                    if flag == 1:
                        break
                    tkinter.messagebox.showinfo('识别过程', '这个动物属于:Ungulates(有蹄类动物)')
                    for i in voices:
                        teacher.setProperty('voice', i.id)
                        teacher.say('识别成功,这个动物属于:Ungulates(有蹄类动物)')
                        teacher.runAndWait()
                    i = 1
                    break
            if i == 1:
                break
        for bird in birds:
            i = 0
            for feature in features:
                if feature in bird:
                    features.append('bird')
                    if flag == 1:
                        break
                    teacher.say('识别成功,这个动物属于:bird(鸟类动物)')
                    teacher.runAndWait()
                    tkinter.messagebox.showinfo('识别过程', '这个动物属于:bird(鸟类动物)')

                    i = 1
                    break
            if i == 1:
                break

        for Carnivores1 in Carnivores:
            i = 0
            for feature in features:
                if feature in Carnivores1:
                    features.append('Carnivores')
                    if flag == 1:
                        break
                    tkinter.messagebox.showinfo('识别过程', '这个动物属于:Carnivores')
                    teacher.say('识别成功,这个动物属于:Carnivores(食肉动物)')
                    teacher.runAndWait()
                    i = 1
                    break
            if i == 1:
                break
        if k == 1:
            return
        return self.parse_animal(features)
# __author__:cv调包侠
    def parse_animal(self, parse):
        print(parse)
        i = 0
        name = ''
        for animl in leopard:
            if animl not in parse:
                i += 1
        best = 1 - i / len(leopard)
        best_name = 'leopard'
        string1 = 'leopard命中率:' + '{}'.format(str(1 - i / len(leopard)))
        if i == 0:
            name = 'leopard'
            print('leopard')
            # return name

        i = 0
        for animl in tiger:
            if animl not in parse:
                i += 1
        string2 = 'tiger命中率:' + '{}'.format(str(1 - i / len(tiger)))
        if 1 - i / len(tiger) >best:
            best = 1 - i / len(tiger)
            best_name = 'tiger'
        if i == 0:
            name = 'tiger'
            print('tiger')
            # return name

        i = 0
        for animl in ostrich:
            if animl not in parse:
                i += 1
        string3 = 'ostrich命中率:' + '{}'.format(str(1 - i / len(ostrich)))
        if 1 - i / len(ostrich) >best:
            best = 1 - i / len(ostrich)
            best_name = 'ostrich'
        if i == 0:
            name = 'ostrich'
            print('ostrich')
            # return name

        i = 0
        for animl in penguin:
            if animl not in parse:
                i += 1
        string4 = 'penguin命中率:' + '{}'.format(str(1 - i / len(penguin)))
        if 1 - i / len(penguin) > best:
            best = 1 - i / len(penguin)
            best_name = 'penguin'
        if i == 0:
            name = 'penguin'
            print('penguin')
            # return name

        i = 0
        for animl in Albatross:
            if animl not in parse:
                i += 1
        string5 = 'Albatross命中率:' + '{}'.format(str(1 - i / len(Albatross)))
        if 1 - i / len(Albatross) > best:
            best = 1 - i / len(Albatross)
            best_name = 'Albatross'
        if i == 0:
            name = 'Albatross'
            print('Albatross')
            # return name

        i = 0
        for animl in zebra:
            if animl not in parse:
                i += 1
        string6 = 'zebra命中率:' + '{}'.format(str(1 - i / len(zebra)))
        if 1 - i / len(zebra) > best:
            best = 1 - i / len(zebra)
            best_name = 'zebra'
        if i == 0:
            name = 'zebra'
            print('zebra')
            # return name


        i = 0
        for animl in giraffe:
            if animl not in parse:
                i += 1
        string7 = 'giraffe命中率:' + '{}'.format(str(1 - i / len(giraffe)))
        if 1 - i / len(giraffe) > best:
            best = 1 - i / len(giraffe)
            best_name = 'giraffe'
        if i == 0:
            name = 'giraffe'
            print('giraffe')
            # return name
        string = string1 + '\n' + string2 + '\n' + string3 + '\n' + string4 + '\n' + string5 + '\n' + string6 + '\n' + string7
        print(string)
        if best != 0:
            tkinter.messagebox.showinfo('识别结果', '这是动物:{}--->置信度:{}'.format(best_name,best), )
            teacher.say('前馈推理识别动物为:{}置信度为:{}'.format(best_name,best))
            teacher.runAndWait()
        return string
    def output(self):
        result = self.parse()
        if result:
            tkinter.messagebox.showinfo('命中率', result,)
        # else:
        #     tkinter.messagebox.showwarning('识别结果', '识别失败,请重新输入!')

    def input(self):
        tkinter.messagebox.showinfo('成功', '数据导入成功')
        with open('./knowledge.csv', 'r', encoding='utf-8') as f:
            reader = csv.reader(f)
            for row in reader:
                for i in row[0].split(' '):
                    if 'mammal' in i:
                        mammal1 = row[0].split(' ')[1]
                        print('features: ', mammal1)
                        return mammal1
                    if 'birds' in i:
                        birds1 = row[0].split(' ')[1]
                        return birds1



if __name__ == '__main__':
    win = tk.Tk()
    surface = Surface(win)
    # parse = surface.parse('a')
    # print(parse)
    # surface.parse_animal(parse)

# __author__:cv调包侠
    # win.protocol('WM_DELETE_WINDOW', close_window)
    win.mainloop()

关注一下~公众号,获取其他源码!!

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_46098574/article/details/108599987