廣度優先搜尋解決八數碼問題
#include <iostream> #include <string> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <set> using namespace std; #define N 9 int jc[N+1]={1,1,2,6,24,120,720,5040,40320,362880};//0-9的階乘 typedef struct data { int arr[N];//格局 int hash;//儲存某一格局的雜湊 int pos;//0當前位置 int step;//記錄步數 }Node; int dir[4][2]={ {0,1}, {1,0}, {0,-1}, {-1,0} }; /** * 康託展開 */ int cantor(int arr[N]) { int i,j; int sum=0; for( i=0;i<N;i++) { int nmin=0; for(j=i+1;j<N;j++) { if(arr[i]>arr[j]) nmin++; } sum+=(nmin*jc[N-i-1]); } return sum; } /** *資料交換 */ void swap(int *arr,int i,int j) { int t=arr[i]; arr[i]=arr[j]; arr[j]=t; } /** * 列印陣列,測試用 */ void printArray(int * arr) { int i,j; for (i=0;i<N;i++) { if(i%3==0) cout<<"\n"; cout<<arr[i]<<" "; } cout<<endl; } /** * 複製陣列 */ void copyArray(int src[N],int target[N]) { int i; for(i=0;i<N;i++) { target[i]=src[i]; } } /** * 廣搜 */ int bfs(int arr[N],int sHash,int tHash) { if(sHash==tHash) return 0; int i,j; queue<Node> q; set<int> setHash; Node now,next; copyArray(arr,now.arr); int pos=0; for (i=0;i<N;i++) { if(arr[i]==0) break; pos++; } now.hash=sHash; now.step=0; next.step=0; now.pos=pos; q.push(now); setHash.insert(now.hash); while(!q.empty()) { now=q.front(); q.pop(); for (i=0;i<4;i++) { int offsetX=0,offsetY=0; offsetX=(now.pos%3+dir[i][0]); offsetY=(now.pos/3+dir[i][1]); if(offsetX>=0&&offsetX<3&&offsetY<3&&offsetY>=0) { copyArray(now.arr,next.arr);//每次換方向,就複製 next.step=now.step; next.step++; swap(next.arr,now.pos,offsetY*3+offsetX); next.hash=cantor(next.arr); next.pos=(offsetY*3+offsetX); int begin=setHash.size(); setHash.insert(next.hash); int end=setHash.size(); if(next.hash==tHash){ return next.step; } if(end>begin) { q.push(next); } } } } return -1; } /** *求逆序數 */ int inversion(int arr[N]) { int sum=0; for(int i=0;i<N;++i) { for(int j=i+1;j<N;++j) { if(arr[j]<arr[i]&&arr[j]!=0)//不與0比較 { sum++; } } } return sum; } int main(int argc, char **argv) { int i,j; string s="123456780"; string t="123456078"; int is[N],it[N];//源int陣列和目標int陣列 for (i=0;i<9;i++) { if (s.at(i)>='0'&&s.at(i)<='8') { is[i]=s.at(i)-'0'; }else { is[i]=0; } if (t.at(i)>='0'&&t.at(i)<='8') { it[i]=t.at(i)-'0'; }else { it[i]=0; } } int sHash,tHash;//源雜湊和目標雜湊 sHash=cantor(is); tHash=cantor(it); int inver1=inversion(is);//求初始格局的逆序數 int inver2=inversion(it);//求目標格局的逆序數 if((inver1+inver2)%2==0) { int step=bfs(is,sHash,tHash); cout<<step<<endl; } else { cout<<"無法從初始狀態到達目標狀態"<<endl; } return 0; }
相關推薦
廣度優先搜尋解決八數碼問題
#include <iostream> #include <string> #include <cstring> #include <cmath> #include <vector> #include <queue> #include &
廣度優先搜尋(8數碼問題)
#include <iostream>#include <vector>#include <limits>#include <string>#include<set> #include<queue&
廣度優先搜尋-八數碼問題
演算法簡介:廣度優先搜尋 問題 給定一個一幅圖和一個起點s,回答“從s到給定的頂點v是否存在一條路徑?如果有,找出其中最短的那條(所含邊數最少)。“ 思路 邊數最少,很自然想到從從經過1條邊能到達的節點有哪些?然後經過這些邊再到達的節點有哪些?這
圖演算法_普通廣度優先搜尋(BFS)解八數碼問題_C語言
Copyright (C)2009 Chris Xue. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Docume
廣度優先搜尋--演算法圖解--書中部分"錯誤"解決記錄
在<圖解演算法>的第六章 廣度優先搜尋中,6.5進行演算法實現時,報如下錯誤: UnboundLocalError: local variable 'search_queue' referenced before assignment 原始碼(書本是python2.
資訊學奧賽一本通(C++版) 第二部分 基礎演算法 第八章 廣度優先搜尋算
//1329 【例8.2】細胞//編寫過程中,發現輸入資料用整數無法讀取,要採用字串形式//核心思路,將非零數字字元改成0字元 //將程式碼修改,提交AC #include <stdio.h>int n,m,next[][2]={{1,0},{-1,0},{0,1},{0,-1}};char a[
廣度優先搜尋——經典的8數碼問題
話不多說,直接貼程式碼吧~ //廣度搜索-8數碼問題 #include <iostream> #include <cstring> using namespace std; const int Max = 8; const int All =
【轉】A*算法解決八數碼問題
nim fir 空格 sin get () explore sed deepcopy from utils import ( PriorityQueue) import copy infinity = float(‘inf‘) def best_first_gr
廣度優先搜尋雙佇列通用程式設計模板
廣度優先搜尋主要用於解決求最短問題,如最短路徑,最少變化步數問題等等,思想是從起點出發,按層遍歷,直到搜尋到目標或者已經搜尋完全部區域。通常利用佇列實現廣度優先搜尋,我這裡使用的雙佇列法,用一個佇列cur表示當前層,next表示由當前層擴充套件的下一層,用雙佇列有個好處是我們只需要定義一個全域性
演算法7-6:圖的遍歷——廣度優先搜尋
http://www.dotcpp.com/oj/problem1703.html 題目描述 廣度優先搜尋遍歷類似於樹的按層次遍歷的過程。其過程為:假設從圖中的某頂點v出發,在訪問了v之後依次訪問v的各個未曾被訪問過的鄰接點,然後分別從這些鄰接點出發依次訪問它們的鄰接點,並使“先被訪問的
佇列的JS實現及廣度優先搜尋(BFS)的實現
佇列是先進先出(FIFO)的資料結構,插入操作叫做入隊,只能新增在佇列的末尾;刪除操作叫做出隊,只能移除第一個元素。在JS中,用陣列可以很簡單的實現佇列。 function Queue () { this.queue = []; } // 增加 Queue.prototype.enQueue = f
廣度優先搜尋(鄰接表)
#include <iostream> #include <cstdio> #include <vector> #include <queue> using namespace std; struct Node{ //to 代表每個節點
利用佇列廣度優先搜尋圖
//廣度優先搜尋樹,一定要使用佇列,佇列的特性很好用 import java.util.*; public class Guangduyouxiansousuosuanfa1 { public static void main(String args[]){ Scanner
【BFS】層層遞進—廣度優先搜尋
【BFS】層層遞進—廣度優先搜尋 Breadth First Search 啊哈演算法 迷宮中尋找小哈 #include <iostream> #include <stdio.h> #include <stdlib.h> using na
資料結構——圖(4)——廣度優先搜尋(BFS)演算法思想
廣度優先搜尋 儘管深度優先搜尋具有許多重要用途,但該策略也具有不適合某些應用程式的缺點。 深度優先方法的最大問題在於它從其中一個鄰居出發,在它返回該節點或者是訪問其他鄰居之前,它必須訪問完從出發節點開始的整個路徑。 如果我們嘗試在一個大的圖中發現兩個節點之間的最短路徑,則使用深度優先
python 遞迴深度優先搜尋與廣度優先搜尋演算法模擬實現
一、遞迴原理小案例分析 (1)# 概述 遞迴:即一個函式呼叫了自身,即實現了遞迴 凡是迴圈能做到的事,遞迴一般都能做到! (2)# 寫遞迴的過程 1、寫出臨界條件2、找出這一次和上一次關係3、假設當前函式已經能用,呼叫自身計算上一次的結果,再求出本次的結果 (3)案例分析:求1+2+3+…+n的數和
鄰接表建立無向圖,廣度優先搜尋遍歷輸出
1 #include<stdio.h> 2 #include<string.h> 3 #include <iostream> 4 #include<algorithm> 5 using namespace std; 6 #defin
深度優先搜尋遍歷與廣度優先搜尋遍歷
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
無向圖鄰接連結串列的廣度優先搜尋
個人認為圖的演算法看起來非常簡潔,但是實現起來需要基礎很紮實。因為經常會涉及多種簡單的資料結構,怎樣把他們恰當的串聯起來,不會報那種,空指標了,型別不匹配,實體型別不符合了等等。 在做無向圖鄰接連結串列廣度優先搜尋的時候,寫的很冒火,想去找別的博主的程式碼借鑑一下,發現大部分,真的是大部分,
搜尋_BFS(廣度優先搜尋)_演算法分析
為方便討論BFS演算法, 考慮對圖的每個結點設定屬性color表示結點的顏色, color可取WHITE, GRAY, BLACK, 設定屬性d表示對應結點到源結點的最短路徑長度, 設定屬性p, 其中v.p表示存在一條從源結點到結點v的最短路徑且v的前驅為v.p, 下