人工智能--野人過河

人工智能(Artificial Intelligence),英文縮寫爲AI。它是研究、開發用於模擬、延伸和擴展人的智能的理論、方法、技術及應用系統的一門新的技術科學。人工智能的定義能夠分爲兩部分,即「人工」和「智能」。「人工」比較好理解,爭議性也不大。有時咱們會要考慮什麼是人力所能及製造的,或者人自身的智能程度有沒有高到能夠創造人工智能的地步,等等。但總的來講,「人工系統」就是一般意義下的人工系統。html

人工智能是計算機科學的一個分支,它企圖瞭解智能的實質,並生產出一種新的能以人類智能類似的方式作出反應的智能機器,該領域的研究包括機器人、語言識別、圖像識別、天然語言處理和專家系統等。人工智能從誕生以來,理論和技術日益成熟,應用領域也不斷擴大,能夠設想,將來人工智能帶來的科技產品,將會是人類智慧的「容器」。人工智能能夠對人的意識、思惟的信息過程的模擬。人工智能不是人的智能,但能像人那樣思考、也可能超過人的智能。java

人工智能是一門極富挑戰性的科學,從事這項工做的人必須懂得計算機知識,心理學和哲學。人工智能是包括十分普遍的科學,它由不一樣的領域組成,如機器學習,計算機視覺等等,總的說來,人工智能研究的一個主要目標是使機器可以勝任一些須要人類智能才能完成的複雜工做。但不一樣的時代、不一樣的人對這種「複雜工做」的理解是不一樣的。算法

 

 

  • 上機題簡介

用JAVA語言編寫和調試一個基於寬度優先搜索法的解決「野人與傳教士過河」問題的程序。目的是學會運用知識表示方法和搜索策略求解一些考驗智力的簡單問題,熟悉簡單智能算法的開發過程並理解其實現原理。數據庫

野人與傳教士渡河問題:3個野人與3個傳教士打算乘一條船到對岸去,該船一次最多能運2我的,在任什麼時候候野人人數超過傳教士人數,野人就會把傳教士吃掉,如何用這條船把全部人安全的送到對岸?數組

 

野人與傳教士渡河問題實驗原理:安全

先實現寬度優先搜索數據結構

定義一個結構體或類來保存狀態信息,狀態信息包括當前某一岸邊野人和傳教士的人數,船所在位置,以及指向前次狀態節點的指針或其在鏈表中的編號等機器學習

每次船運載的人數只有5種可能函數

1野人;1傳教士;2野人;2傳教士;1野人1傳教士學習

1.爲了不重複,咱們將搜索過的狀態記錄下來,以後避開搜索這個狀態。

2.咱們把知足條件的狀態稱爲安全狀態,首先要定義出安全狀態,經過對問題的分析, 不可貴出只有知足如下條件之一的狀態纔是安全的(以左岸爲例): 
1)傳教士與野人的數目相等; 
2)傳教士都在左岸; 
3)傳教士都不在左岸。 
咱們只對安全的狀態進行深度優先搜索,直至找到一個合法的解。

 

野人傳教士渡河問題程序功能結構圖:

流程圖:

數據結構定義:

class state   //定義狀態類

public int left_c;    //定義左岸傳教士

public int left_y;    //定義左岸野人

public int boat;      //定義船的位置

public int right_c;   //定義右岸傳教士

public int right_y;   //定義右岸野人

主要變量:

nullboat.setleft_c   //空數組中左岸傳教士人數

nullboat.setleft_y   //空數組中左岸野人人數

nullboat.setright_c  //空數組中右岸傳教士人數

nullboat.setright_y  //空數組中右岸野人人數

nullboat.setboat   //空數組中船的位置

import java.util.ArrayList;  //Java數組類
import java.util.List;

class state{   //定義狀態類
	public int left_c;    //定義左岸傳教士
	public int left_y;    //定義左岸野人
	public int boat;      //定義船的位置
	public int right_c;   //定義右岸傳教士
	public int right_y;   //定義右岸野人
	public state(int left_c,int left_y,int boat,int right_c,int right_y)	//state方法重寫
	{	super();
		this.left_c=left_c;
		this.left_y=left_y;
		this.boat=boat;
		this.right_c=right_c;
		this.right_y=right_y;
	}
	public void setleft_c(int i) {  
		// TODO Auto-generated method stub
		this.left_c=i;
	}
	public void setleft_y(int left_y2) {
		// TODO Auto-generated method stub
		this.left_y=left_y2;
	}
	public void setright_c(int i) {
		// TODO Auto-generated method stub
		this.right_c=i;
	}
	public void setright_y(int right_y2) {
		// TODO Auto-generated method stub
		this.right_y=right_y2;
	}
	public void setboat(int i) {
		// TODO Auto-generated method stub
		this.boat=i;
	}
}

public class Cross {   //過河方法
	//static List<state> list=new ArrayList<state>();  //數組集合
//	static state state; 
//	static List<state> list;
	
	public static void robot(state state,List<state> list){  //將class state變成數組
		if (state.right_c == 3 && state.right_y== 3)   //判斷是否完成過河
		{			
			System.out.println("\n\n如下本次過河的方法以及實時狀態。\n");
			System.out.println("船位置"+"\t"+"左傳"+"\t"+"左野"+"\t"+"右傳"+"\t"+"右野");
			for (int i = 0; i < list.size(); i++)
			{
				//輸出船的位置,左岸傳教士人數,左岸野人數,右岸傳教士人數,右岸野人數
				System.out.println(list.get(i).boat+"\t "+list.get(i).left_c+"\t "+list.get(i).left_y+"\t "+list.get(i).right_c+"\t "+list.get(i).right_y);
			}

			return ;
		}
		
		// 判斷是否重複操做	
		for (int i= 0; i < list.size() - 1; i++) {
			if (list.get(i).left_c == state.left_c && list.get(i).left_y == state.left_y&&list.get(i).boat==state.boat) 
			{
				return ;
			}
		}
		
		// 人數合理嗎
		for (int i= 0; i < list.size() - 1; i++) {
			if (state.left_c< 0 || state.left_y< 0 || state.right_c< 0 || state.right_y< 0)  //判斷人數是否小於0
			{
				return ;
			}
		}
		
		// 傳教士被吃了沒
		if ((state.left_c < state.left_y && state.left_c != 0)|| (state.right_c< state.right_y && state.right_c != 0))
		{
			return ;
		}	
		//定義一個空的狀態		
		state nullboat = new state(0, 0, 0, 0, 0);
		
		//兩個傳教士過河
		nullboat.setleft_c(state.left_c - 2 * state.boat);   //此時左岸傳教士人數爲1
		nullboat.setleft_y(state.left_y);              //此時左岸野人人數爲3
		nullboat.setright_c(state.right_c + 2 * state.boat);  //此時右岸傳教士人數爲2
		nullboat.setright_y(state.right_y);   //此時右岸野人人數爲0
		nullboat.setboat(-state.boat);      //此時船在右岸
		list.add(nullboat);
		robot(nullboat, list);
		list.remove(list.size() - 1);
		
		// 兩個野人過河
		nullboat.setleft_c(state.left_c);         //此時左岸傳教士人數爲3
		nullboat.setleft_y(state.left_y - 2 * state.boat);  //此時左岸野人人數爲1
		nullboat.setright_c(state.right_c);      //此時右岸傳教士人數爲0
		nullboat.setright_y(state.right_y + 2 * state.boat); //此時右岸野人人數爲2
		nullboat.setboat(-state.boat);  //此時船在右岸
		list.add(nullboat);
		robot(nullboat,list);
		list.remove(list.size() - 1);
		
		// 一個野人,一個傳教士		
		nullboat.setleft_c(state.left_c - 1 * state.boat);    //此時左岸傳教士人數爲2
		nullboat.setleft_y(state.left_y - 1 * state.boat);    //此時左岸野人人數爲2
		nullboat.setright_c(state.right_c + 1 * state.boat); //此時右岸傳教士人數爲1
		nullboat.setright_y(state.right_y + 1 * state.boat); //此時右岸野人人數爲1
		nullboat.setboat(-state.boat);   //此時船在右岸
		list.add(nullboat);
		robot(nullboat, list);
		list.remove(list.size() - 1);
		
		// 一個傳教士過河
		nullboat.setleft_c(state.left_c - 1 * state.boat);     //此時左岸傳教士人數爲2
		nullboat.setleft_y(state.left_y);         //此時左岸野人人數爲3
		nullboat.setright_c(state.right_c + 1 * state.boat);  //此時右岸傳教士人數爲1
		nullboat.setright_y(state.right_y);  //此時右岸野人人數爲0
		nullboat.setboat(-state.boat);   //此時船在右岸
		list.add(nullboat);
		robot(nullboat, list);
		list.remove(list.size() - 1);
		
		// 一個野人過河
		nullboat.setleft_c(state.left_c);         //此時左岸傳教士人數爲3
		nullboat.setleft_y(state.left_y - 1 * state.boat);  //此時左岸野人人數爲2
		nullboat.setright_c(state.right_c);     //此時右岸傳教士人數爲0
		nullboat.setright_y(state.right_y + 1 * state.boat); //此時右岸野人人數爲1
		nullboat.setboat(-state.boat);   //此時船在右岸
		list.add(nullboat);
		robot(nullboat, list);
		list.remove(list.size() - 1);
		
		return ;
	}	
	public static void main(String[] args) {   //主函數		
		List<state> list = new ArrayList<state>();
		state begin =new state(3,3,1,0,0);    //定義初始狀態的船位置、左右傳教士人數和野人人數
		list.add(begin);
		robot(begin, list);
	}
}

體會

在傳教士和野人渡河問題中,在討論用產生式系統求解問題時,有時引入狀態空間圖的概念頗有幫助。狀態空間圖是一個有向圖,其節點可表示問題的各類狀態(綜合數據庫),節點之間的弧線表明一些操做(產生式規則),它們可把一種狀態導向另外一種狀態。這樣創建起來的狀態空間圖,描述了問題全部可能出現的狀態及狀態和操做之間的關係,於是能夠較直觀地看出問題的解路徑及其性質。

相關文章
相關標籤/搜索