Expert Systems artificial intelligence

Similar documents
File I/O Christian Schumacher, Info1 D-MAVT 2013

Welcome Back. CSCI 262 Data Structures. Hello, Let s Review. Hello, Let s Review. How to Review 1/9/ Review. Here s a simple C++ program:

Welcome Back. CSCI 262 Data Structures. Hello, Let s Review. Hello, Let s Review. How to Review 8/19/ Review. Here s a simple C++ program:

Assignment 2 Solution

Classes and Objects. Instructor: 小黑

Week 3: File I/O and Formatting 3.7 Formatting Output

C++ STREAMS; INHERITANCE AS

CSc Introduc/on to Compu/ng. Lecture 19 Edgardo Molina Fall 2011 City College of New York

Review: C++ Basic Concepts. Dr. Yingwu Zhu

File Operations. Lecture 16 COP 3014 Spring April 18, 2018

Animals Due Part 1: 19 April Part 2: 26 April

CSE 143: Computer Programming II Spring 2015 HW7: 20 Questions (due Thursday, May 28, :30pm)

CPSC 427: Object-Oriented Programming

Interview Questions of C++

File I/O. File Names and Types. I/O Streams. Stream Extraction and Insertion. A file name should reflect its contents

CPSC 427: Object-Oriented Programming

Why Is Repetition Needed?

Data Structures Lab II. Binary Search Tree implementation

Note 11/13/2014. They are like those i s, j s, and temp s that appear and disappear when the function starts and finishes...

G52CPP C++ Programming Lecture 17

Lab 2: ADT Design & Implementation

III. Classes (Chap. 3)

C++ does not, as a part of the language, define how data are sent out and read into the program

Chapter 2. Procedural Programming

More File Operations. Lecture 17 COP 3014 Spring april 18, 2018

Copying Data. Contents. Steven J. Zeil. November 13, Destructors 2

CSCE 110 PROGRAMMING FUNDAMENTALS

Fundamentals of Programming Session 25

CSI33 Data Structures

Lecture 14: more class, C++ streams

Due Date: See Blackboard

[CSE10200] Programming Basis ( 프로그래밍기초 ) Chapter 7. Seungkyu Lee. Assistant Professor, Dept. of Computer Engineering Kyung Hee University

Object Oriented Programming COP3330 / CGS5409

What we will learn about this week:

การทดลองท 8_2 Editor Buffer Array Implementation

Compuer Science 62 Assignment 10

CSE au Midterm Exam Nov. 2, 2018 Sample Solution

Today in CS162. External Files. What is an external file? How do we save data in a file? CS162 External Data Files 1

Short Notes of CS201

2. It is possible for a structure variable to be a member of another structure variable.

CS201 - Introduction to Programming Glossary By

File I/O CS 16: Solving Problems with Computers I Lecture #9

CSCS 261 Programming Concepts Exam 1 Fall EXAM 1 VERSION 1 Fall Points. Absolutely no electronic devices may be used during this exam.

CMSC 341 Lecture 10 Binary Search Trees

Writing a Good Program. 7. Stream I/O

Class Example. student.h file: Declaration of the student template. #ifndef STUDENT_H_INCLUDED #define STUDENT_H_INCLUDED

Simple File I/O.

Fall 2017 CISC/CMPE320 9/27/2017

CSE 143: Computer Programming II Summer 2015 HW6: 20 Questions (due Thursday, August 13, :30pm)

Due Date: See Blackboard

CSCE 110 PROGRAMMING FUNDAMENTALS

Programming in C++ Prof. Partha Pratim Das Department of Computer Science and Engineering Indian Institute of Technology, Kharagpur

CSE 303: Concepts and Tools for Software Development

Linked List using a Sentinel

A <Basic> C++ Course

pointers & references

C++ basics Getting started with, and Data Types.

Introduction to Programming

G52CPP C++ Programming Lecture 14. Dr Jason Atkin

A <Basic> C++ Course

Physics 6720 I/O Methods October 30, C++ and Unix I/O Streams

Chapter 14 Sequential Access Files

Fundamental of Programming (C)

Chapter 12: Searching: Binary Trees and Hash Tables. Exercises 12.1

CS2141 Software Development using C/C++ Stream I/O

Operator Overloading in C++ Systems Programming

Abstract Data Types (ADTs) 1. Legal Values. Client Code for Rational ADT. ADT Design. CS 247: Software Engineering Principles

Summary of basic C++-commands

CPE Summer 2015 Exam I (150 pts) June 18, 2015

CSE 374 Programming Concepts & Tools. Hal Perkins Fall 2015 Lecture 19 Introduction to C++

Defensive Programming

CS 247: Software Engineering Principles. ADT Design

Object Oriented Programming Using C++ UNIT-3 I/O Streams

CISC 2200 Data Structure Fall, C++ Review:3/3. 1 From last lecture:

cs3157: c++ lecture #2 (mon-11-apr-2005) chronology of some programming languages... C++ vs Java identifiers.

Iterative Constructs

CSE 374 Programming Concepts & Tools. Hal Perkins Spring 2010

EECE.3220: Data Structures Spring 2017

Encapsulation. Contents. Steven Zeil. July 17, Encapsulation Encapsulation in C Classes 4. 3 Hiding Attributes 8

File Input / Output Streams in C++ CS 16: Solving Problems with Computers I Lecture #9

CS3157: Advanced Programming. Outline

IS 0020 Program Design and Software Tools

Intermediate Programming Methodologies in C++ CIS22B. Joe Bentley

C++_ MARKS 40 MIN

PIC 10A Objects/Classes

Fundamentals of Programming Session 27

UEE1302 (1102) F10: Introduction to Computers and Programming

Due Date: See Blackboard

Traversing Trees with Iterators

Traversing Trees with Iterators

Chapter 12. Streams and File I/O. Copyright 2010 Pearson Addison-Wesley. All rights reserved

CpSc212 Goddard Notes Chapter 10. Linked Lists

Major Differences between Java and C++ Programming in C++ Multiple Inheritance

Convenient way to deal large quantities of data. Store data permanently (until file is deleted).

Lecture 9. Introduction

OBJECT ORIENTED PROGRAMMING

Agenda. The main body and cout. Fundamental data types. Declarations and definitions. Control structures

Programming Language. Functions. Eng. Anis Nazer First Semester

Modern C++ for Computer Vision and Image Processing. Igor Bogoslavskyi

Chapter 2 - Control Structures

Transcription:

Expert Systems The game of animal is an old children s game. There are two participants in the game the player and the guesser. The player is asked to think of an animal, which the guesser will try to guess. The guesser asks the player a series of yes-no questions, such as Guesser: Does it live on land? If the player answers yes, then the guesser can eliminate from consideration those animals that do not live on land, and use this information in formulating the next question, such as Guesser: Does it have four feet? Again, the answer to the question allows the user to eliminate from consideration either the animals with four feet, or those that do not have four feet. Carefully formulating each question allows the guesser to eliminate a large group of animals from consideration, based on the player s response. Eventually, the guesser knows of only a single animal with the given characteristics: Guesser: Is it an elephant? If the guesser is correct, then he or she wins the game. Otherwise, the player wins the game, and the guesser asks the player: Guesser: What is your animal? Player: An aardvark. Guesser: How does an elephant differ from an aardvark? Player: An elephant has a trunk, but an aardvark does not. By remembering the new animal and the difference between his or her animal and the new animal, the guesser learns to distinguish between the two animals. A computer program that plays the animal game provides a classic example of a situation in which a program can seemingly learn and thus display artificial intelligence. The user of the program assumes the role of the player and the program assumes the role of the guesser. The program maintains a knowledge base of questions, each of which allows it to eliminate animals from consideration. When the program has narrowed its search to a single animal, it guesses that animal. If the guess is correct, the program wins. Otherwise the program asks the player to name the animal of which he or she was thinking, and then asks how to distinguish between this new animal and the animal it guessed. It then stores this question and the new animal in its knowledge base for the next time the game is played. The program thus exhibits some of the characteristics of learning each time it adds a new animal to its knowledge base.

As time passes and the program s knowledge base grows, it becomes more and more difficult for the player to think of animals that are not in the knowledge base the program becomes an expert at guessing animals. Programs that exhibit expertise in some area through use of a knowledge base are known as expert systems, and the study of such systems is one of the branches of artificial intelligence. Examples of such systems range from welding experts that control welding robots on an automotive assembly line to legal experts that can help draw up standard legal documents. Although most expert systems use fixed knowledge bases that the program is unable to modify, a program that plays the animal game is an example of a special adaptive expert system, because it adds new animals to its knowledge base as they are encountered. It is this ability to adapt its knowledge base that enables the animal program to simulate the process of learning. The following program plays the animal game. For its knowledge base, it uses a special DecisionTree class built specially for this purpose. /* animal.cpp plays the game of 'animal', in which the player thinks of an animal, and the program tries to guess it. -------------------------------------------------------------------*/ #include <iostream> using namespace std; #include "DecisionTree.h" bool playmore(); int main() cout << "\nwelcome to the game of Animal!\n"; DecisionTree dtree("animal.data"); // load knowledge base do cout << "\nthink of an animal, and I will try to guess it...\n\n"; int winner = dtree.descend(); // 0 == the person, // 1 == program if (winner) cout << "\nha! Even a computer program can beat you...\n"; else cout << "\nyou were just lucky...\n"; while ( playmore() );

// knowledge base is auto-saved to file by DecisionTree destructor bool playmore() char answer; cout << "\ndo you want to play again (y or n)? "; cin >> answer; return ((answer == 'y') (answer == 'Y')); Sample Run: Welcome to the game of Animal! Think of an animal, and I will try to guess it... Does it live on land (y or n)? y Does it have wings (y or n)? n Is it a(n) elephant (y or n)? y Ha! Even a computer program can beat you... Do you want to play again (y or n)? y Think of an animal, and I will try to guess it... Does it live on land (y or n)? n Is it a(n) whale (y or n)? n What animal are you thinking of? shark Please enter a question, such that the answer is yes - for a(n) shark, and no - for a(n) whale --> Is it cold-blooded You were just lucky... Think of an animal, and I will try to guess it... Does it live on land (y or n)? n Is it cold-blooded (y or n)? y Is it a(n) shark (y or n)? n What animal are you thinking of? electric eel Please enter a question, such that the answer is

yes - for a(n) shark, and no - for a(n) whale --> Is meeting it a shocking experience You were just lucky... Do you want to play again (y or n)? n The program plays the game by building a special tree to serve as its knowledge base, containing the questions and the animals it knows. For example, when the program was first written, it knew only three animals: a duck, an elephant, and a whale. Its knowledge base was initially structured as follows: yes yes Does it have wings? no Does it live on land? no Is it a whale? 0 0 Is it a duck? Is it an elephant? 0 0 0 0 Such a structure is called a decision tree each node in the tree contains the information needed to make a yes-no decision between its two subtrees. The guesser begins by asking the topmost question and, based on the player s response, follows the yes branch or the no branch to the next question. The guesser continues this process, descending through the tree until it reaches a leaf node (i.,e., the end of a line of questioning), in which case it asks its final question and guesses the animal stored in that node. By implementing such a tree as a linked structure, new nodes can be easily inserted(or deleted). Thus, in the first game, the program got lucky because it happened that the animal the player was thinking of (an elephant) was one of the three it knew about. However in the second game, the user was thinking of a shark an animal the program did not know about. Using the information supplied by the player, the program learned to distinguish between a whale and a shark by creating and inserting the nodes that will allow it to distinguish between the two animals:

yes Does it live on land? no Does it have wings? Is it cold-blooded? yes no yes no Is it a duck? Is it an elephant? Is it a shark? Is it a whale? 0 0 0 0 0 0 0 0 Similarly, in the next game, the program learned to distinguish between a shark and an electric eel: yes Does it live on land? no Does it have wings? Is it cold-blooded? yes no yes no Is it a duck? Is it an elephant?... shocking...? Is it a whale? 0 0 0 0 0 0 yes no Is it an electric eel? Is it a shark? 0 0 0 0 The program thus learns by expanding its decision tree each time it encounters an animal that is not already there. To avoid forgetting what it has learned, the DecisionTree destructor writes the tree s data to a file when the program terminates, and the DecisionTree constructor reads from this same file to initialize the DecisionTree when the program is run again. This simple mechanism allows the program to remember what it has learned in previous games. Over the course of time, such a program can become quite adept at identifying animals, based on the characteristics it is taught. Attached is the source code for the DecisionTree class and the interested reader is invited to study it further. DecisionTree.h /* This file contains the declaration for class DecisionTree. ---------------------------------------------------------------*/ #ifndef DECISION_TREE #define DECISION_TREE #include <iostream> // istream, ostream, <<, >>,... #include <string> // string using namespace std;

class DecisionTree public: DecisionTree(const string& filename); ~DecisionTree(); int descend(); private: DecisionTree(const DecisionTree&); // disable copying DecisionTree& operator=(const DecisionTree&); // disable assignment void read(const string& filename); void write(const string& filename); struct Node Node(const string& question); Node(const string& question, Node* leftchild, Node* rightchild); ~Node(); string myquestion; Node* myyeschild; Node* mynochild; // the question I store // where to go if the answer is 'y' // where to go if the answer is 'n' ; typedef Node* NodePtr; void buildtree(istream& InF, NodePtr& NPtr); int descendtree(nodeptr& NPtr); void learnsomething(nodeptr& NPtr); void writetree(ostream& OutF, NodePtr NPtr); NodePtr myroot; string mydatafile; ;

/* Explicit-value constructor Receive: filename, a string. PRE: filename is the name of a text file containing DecisionTree data. POST: I am a DecisionTree containing the data found in filename. -------------------------------------------------------------------*/ inline DecisionTree::DecisionTree(const string& filename) myroot = 0; // just in case filename is empty... read(filename); // build myself using data from filename mydatafile = filename; // save for use by destructor /* Destructor PRE: my lifetime is over POST: my data (including anything I have learned) has been saved to mydatafile. -------------------------------------------------------------------*/ inline DecisionTree::~DecisionTree() write(mydatafile); // write myself back to data file delete myroot; // delete root node (recursively deleting everything) myroot = 0; // unnecessary, but... /* Node constructor Receive: A question for the DecisionTree POST: I am a DecisionTree::Node containing question && myyeschild == 0 && mynochild == 0. -------------------------------------------------------------------*/ inline DecisionTree::Node::Node(const string& question) myquestion = question; myyeschild = 0; mynochild = 0; inline DecisionTree::Node::Node(const string& question, DecisionTree::NodePtr left, DecisionTree::NodePtr right) myquestion = question; myyeschild = left; mynochild = right; /* Node destructor PRE: my lifetime is over (someone has used 'delete' on my handle) POST: both of my subtrees have been deleted -------------------------------------------------------------------*/ inline DecisionTree::Node::~Node() delete myyeschild; // delete yes subtree (recursively) delete mynochild; // delete no subtree (recursively)

/* method to 'walk' the tree from its root to a leaf (really just a wrapper for the recursive method). return: 1 if the answer to the leaf-node's question was 'yes' 0 if the answer at the leaf-node's question was 'no' Relies on the recursive method descendtree() ------------------------------------------------------------------*/ inline int DecisionTree::descend() return descendtree(myroot); #endif DecisionTree.cpp /* This file contains the definition for class DecisionTree. ---------------------------------------------------------------*/ #include "DecisionTree.h" #include <fstream> // ifstream, ofstream,... #include <cstdlib> // exit() using namespace std; /* read tree-data from filename receive: filename, a string. input(filename): a sequence of Node values. POST: I am a DecisionTree containing the data from filename. Relies on: buildtree() Called by: DecisionTree constructor ---------------------------------------------------------------*/ void DecisionTree::read(const string& filename) ifstream fin( filename.data() ); if (!fin.is_open()) cerr << "\ndecisiontree::load(filename) unable to open filename: '" << filename << "'; exiting...\n"; exit (-1); buildtree(fin, myroot); fin.close();

/* utility to recursively build the tree by reading from an istream Receive: fin, an istream' nptr, the 'root' of a DecisionTree. POST: the tree has been built from nptr 'down' using values from fin. Called by: read() ---------------------------------------------------------------*/ void DecisionTree::buildTree(istream& fin, DecisionTree::NodePtr& nptr) // trivial case: fin is empty, do nothing if (!fin.eof() && fin.good()) // nontrivial case: string question; // a. read 1 node's data getline(fin, question); int leftsubtreeexists, rightsubtreeexists; fin >> leftsubtreeexists >> rightsubtreeexists; char separator; fin.get(separator); // b. build a new node for that data nptr = new DecisionTree::Node(question); if (leftsubtreeexists) // c. if necessary buildtree(fin, nptr->myyeschild); // build 'yes' node recursively if (rightsubtreeexists) // d. if necessary buildtree(fin, nptr->mynochild); // build 'no' node recursively /* recursively 'walk' a tree from its root to a leaf return: 1 if the answer to the leaf-node's question was 'yes' 0 if the answer at the leaf-node's question was 'no' Called by: descend() -----------------------------------------------------------------*/ int DecisionTree::descendTree(NodePtr& nptr) char response; int result; if (nptr!= 0) // validate parameter do // get a y or n response // to this node's question cout << "\n" + nptr->myquestion; cin >> response; while ((response!= 'y') && (response!= 'n')); // if this is a leaf node if ((nptr->myyeschild == 0) && (nptr->mynochild == 0)) if (response == 'y') // and we guessed correctly

result = 1; // we won! else // otherwise, we lost, so learnsomething(nptr); // learn about the new animal result = 0; else // otherwise: it's a non-leaf node if (response == 'y') // so follow the appropriate link result = descendtree(nptr->myyeschild); else result = descendtree(nptr->mynochild); return result; /* utility to expand my 'knowledge base'; invoked when I reach a leaf node and the answer is 'n'. Receive: nptr, the handle of the leaf Node. POST: nptr now points to a new interior node && nptr->mynochild points to the old leaf (animal) && nptr->myyeschild points to a new leaf (animal) ---------------------------------------------------------------*/ void DecisionTree::learnSomething(NodePtr& nptr) // get new animal name cout << "\nwhat animal are you thinking of? "; char separator; cin.get(separator); string newanimal; getline(cin, newanimal); // extract old animal name int end = nptr->myquestion.find(" (y or n)?", 0); if (end == string::npos) cerr << "DecisionTree::learnSomething(): ill-formatted question: '" << nptr->myquestion << "'; exiting...\n" << endl; exit(1); string oldanimal = nptr->myquestion.substr(11, end-10); // get question to distinguish them cout << "\nplease enter a question, such that the answer is\n" << "\tyes - for a(n) " << newanimal << ", and\n\tno - for a(n) " << oldanimal << "\n--> "; string newquestion; getline(cin, newquestion); NodePtr tempptr = nptr; // save node containing oldanimal nptr = new Node(newQuestion + " (y or n)? "); // make node for new question // make node for newanimal NodePtr newanimalptr = new Node("\nIs it a(n) " + newanimal + " (y or n)? "); nptr->myyeschild = newanimalptr; // arrange the 3 nodes correctly nptr->mynochild = tempptr;

/* utility to write a DecisionTree's data to a data file. (mostly just a wrapper for the recursive writetree() method). Receive: filename, a string. POST: All of my data has been written to filename. Called by: DecisionTree destructor. ---------------------------------------------------------------*/ void DecisionTree::write(const string& filename) ofstream fout( filename.data() ); if (!fout.is_open() ) cerr << "\ndecisontree::write(filename): unable to open filename: '" << filename << "'; exiting...\n"; exit (-1); writetree(fout, myroot); fout.close(); /* Utility to recursively write a node and its subtrees to a file via an ostream Receive: fout, the stream to which data should be written; nptr, the root of a DecisionTree. POST: fout contains the data of nptr and its subtrees. Called by: write() --------------------------------------------------------------------*/ void DecisionTree::writeTree(ostream& fout, DecisionTree::NodePtr nptr) if (nptr!= 0) fout << nptr->myquestion << endl << (nptr->myyeschild!= 0) << ' ' << (nptr->mynochild!= 0) << endl; writetree(fout, nptr->myyeschild); writetree(fout, nptr->mynochild); animal.cpp /* animal.cpp plays the game of 'animal', in which the player thinks of an animal, and the program tries to guess it. If the program is unable to guess the player's animal, it "learns" to distinguish the player's animal from its animal (with the player's assistance). --------------------------------------------------------------------*/ #include <iostream> #include "DecisionTree.h" using namespace std;

bool playmore(); int main() cout << "\nwelcome to the game of Animal!\n"; DecisionTree dtree("animal.data"); // load tree-data from file do cout << "\nthink of an animal, and I will try to guess it...\n\n"; int winner = dtree.descend(); // 0 == the person, 1 == the program if (winner) cout << "\nha! Even a computer program can beat you...\n"; else cout << "\nyou were just lucky...\n"; while (playmore()); // tree-data is auto-saved to file by DecisionTree destructor bool playmore() char answer; cout << "\ndo you want to play again (y or n)? "; cin >> answer; return ((answer == 'y') (answer == 'Y'));