A*

转自http://www.mamicode.com/info-detail-1534200.html

康托展开

X = a[1]*(n-1)!+a[2]*(n-2)!+...+a[i]*(n-i)!+...+a[n-1]*1!+a[n]*0!
其中a[i]表示在num[i+1..n]中比num[i]小的数的数量

逆康托展开

由于:

a[i]≤n-i, a[i]*(n-i)!≤(n-i)*(n-i)!<(n-i+1)!

于是我们得到:

对于X=a[1]*(n-1)!+a[2]*(n-2)!+...+a[i]*(n-i)!+...+a[n-1]*1!+a[n]*0!

中的a[i]来说,无论a[i+1..n]的值为多少,其后面的和都不会超过(n-i)!

eg:当i=1  所以X约等于a[1]*(n-1)! +后面

X除以(n-1)!,得到商c和余数r。其中c就等于a[1],r则等于后面的部分


这样依次求解,就可以得到a[]数组了!

比如求解3的全排列中,编号为3的排列:

3 / 2! = 1 ... 1 => a[1] = 1
1 / 1! = 1 ... 0 => a[2] = 1
0 / 0! = 0 ... 0 => a[3] = 0

之后我们回想一下a[i]和含义  

a[i]表示在num[i+1..n]中比num[i]小的数的数量

对于已经排好序的序列比如

 {1, 2, 3},

a[] = {1, 1, 0}
unused = {1, 2, 3}, a[1] = 1, num[1] = 2
unused = {1, 3}, a[2] = 1, num[2] = 3
unused = {1}, a[3] = 0, num[3] = 1
=> 2, 3, 1

解释看http://www.mamicode.com/info-detail-1534200.html 

讲得很好

代码也很易懂


#include <algorithm>
#include <cstring>
#include <string.h>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <queue>
#include <vector>
#include <cstdio>
#include <cmath>#define LL long long
#define N 100005
#define INF 0x3ffffffusing namespace std;int factor[]={1,1,2,6,24,120,720,5040,40320};
vector<int>stnum; //八数码某个状态序列
int destination; //目标状态康托展开值struct state
{int f; //评估值和状态值的总和。int g; //从起始状态到当前状态的最少步数int h; //评估函数int k; //该状态康托展开值state(int f,int g,int h,int k):f(f),g(g),h(h),k(k){};friend bool operator<(state a,state b){if(a.f!=b.f)return a.f>b.f;else return a.g>b.g;}
};int cantor(vector<int>num) //康托展开
{int k = 0;int n = 9;for(int i=0;i<n;i++) {int tp = 0;for(int j = i+1; j < n; j++) {if(num[j] < num[i]) {tp++;}}k += tp * factor[n-1-i];}return k;
}vector<int> recantor(int k) //逆康托展开
{vector<int>num;int a[10];int n = 9;bool used[10];memset(used,false,sizeof(used));for(int i=0;i<n;i++){a[i] = k / factor[n-1-i];k %= factor[n-1-i];int cnt = 0;for(int j=0;j<n;j++){if(!used[j]) {cnt++;if(a[i] + 1==cnt) {num.push_back(j);used[j] = true;break;}}}}return num;
}int pos[]={8,0,1,2,3,4,5,6,7};int getdis(int a,int b) //曼哈顿距离
{return (abs(a/3-b/3)+abs(a%3-b%3));//a/3-b/3行差,a%3-b%3列差
}int get_evaluation(vector<int>num) //评估函数
{//评估函数设定为1-8八数字当前位置到目标位置的曼哈顿距离之和。 比如其中就有当前位置的1和目标位置的1 的曼哈顿距离之和//目标式1 2 3 4 5 6 7 8 0//此时 pos[1]=0 ,表示在目标式中1原本应该在第0位 从而推出0应该在第8位 对应pos[0] 所以pos的作用是 映射这个数字在目标式子中的位置,所以要偏移//当前   2 4 7 6 8 0 1 3 5//因此 i 表示 在当前式子中这个数字的位置  比如2 是第0位 4 是第1位int h=0;for(int i=;i<9;i++){h+=getdis(i,pos[num[i]]);}return h;
}void solve()
{priority_queue<state>openlist;set<int>closelist; //在closelist中,抛弃该状态。while(!openlist.empty()) openlist.pop();closelist.clear();int h=get_evaluation(stnum);openlist.push(state(h,0,h,cantor(stnum)));int step=0; //统计步数bool flag=false; //标记是否能找到目标状态while(!openlist.empty()){state cur=openlist.top(); //从openlist中取出F值最小的状态openlist.pop();int k=cur.k;//cur的康托展开 closelist.insert(k); //将该状态加入closelist if(destination==k) {//若该状态为目标状态,结束搜索flag=true; //找到目标状态step=cur.g; //步数break;}vector<int> st = recantor(k); //当前状态的八数码序列for(int i=0;i<9;i++) if(st[i]==0) //找到0的位置{if(i%3!=2) { //不在行末,0位可以和右边相邻位置交换swap(st[i],st[i+1]);int x = cantor(st);int g = cur.g+1;int h = get_evaluation(st);int f = g + h;if(closelist.find(x)==closelist.end()) {openlist.push(state(f,g,h,x));}swap(st[i],st[i+1]);//又要换回来来进行下面的步骤}if(i%3!=0) { //不在某行开头,可以和左边相邻位置交换swap(st[i],st[i-1]);int x = cantor(st);int g = cur.g+1;int h = get_evaluation(st);int f = g + h;if(closelist.find(x)==closelist.end()) {openlist.push(state(f,g,h,x));}swap(st[i],st[i-1]);}if(i<6) {swap(st[i],st[i+3]);int x = cantor(st);int g = cur.g+1;int h = get_evaluation(st);int f = g + h;if(closelist.find(x)==closelist.end()) {openlist.push(state(f,g,h,x));}swap(st[i],st[i+3]);}if(i>2) {swap(st[i],st[i-3]);int x = cantor(st);int g = cur.g+1;int h = get_evaluation(st);int f = g + h;if(closelist.find(x)==closelist.end()) {openlist.push(state(f,g,h,x));}swap(st[i],st[i-3]);}}}if(!flag) cout << "No Solution!" << endl;else cout<<step<<endl;}int main() {vector <int> des;for(int i=0;i<8;i++) des.push_back(i+1);des.push_back(0);destination=cantor(des);int T;cin >> T;while(T--){int a;stnum.clear();for(int i=0;i<9;i++) {cin>>a; stnum.push_back(a);}solve();}return 0;
}

通常A* 还有一个更新

对于第n个F

即 if(F>g(n)+1+H(n-1))  F=g(n)+1+H(n-1)






转载于:https://www.cnblogs.com/LandingGuy/p/9280239.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unity第三人称射击游戏_在游戏上第3部分完美的信息游戏

unity第三人称射击游戏Previous article上一篇文章 The economics literature distinguishes the quality of a game’s information (perfect vs. imperfect) from the completeness of a game’s information (complete vs. incomplete). Perfect information means that ev…

JVM(2)--一文读懂垃圾回收

与其他语言相比&#xff0c;例如c/c&#xff0c;我们都知道&#xff0c;java虚拟机对于程序中产生的垃圾&#xff0c;虚拟机是会自动帮我们进行清除管理的&#xff0c;而像c/c这些语言平台则需要程序员自己手动对内存进行释放。 虽然这种自动帮我们回收垃圾的策略少了一定的灵活…

2058. 找出临界点之间的最小和最大距离

2058. 找出临界点之间的最小和最大距离 链表中的 临界点 定义为一个 局部极大值点 或 局部极小值点 。 如果当前节点的值 严格大于 前一个节点和后一个节点&#xff0c;那么这个节点就是一个 局部极大值点 。 如果当前节点的值 严格小于 前一个节点和后一个节点&#xff0c;…

tb计算机存储单位_如何节省数TB的云存储

tb计算机存储单位Whatever cloud provider a company may use, costs are always a factor that influences decision-making, and the way software is written. As a consequence, almost any approach that helps save costs is likely worth investigating.无论公司使用哪种…

nginx简单代理配置

原文&#xff1a;https://my.oschina.net/wangnian/blog/791294 前言 Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器&#xff0c;也是一个IMAP/POP3/SMTP服务器。Nginx是由Igor Sysoev为俄罗斯访问量第二的Rambler.ru站点开发的&#xff0c;第一个公开版本…

2059. 转化数字的最小运算数

2059. 转化数字的最小运算数 给你一个下标从 0 开始的整数数组 nums &#xff0c;该数组由 互不相同 的数字组成。另给你两个整数 start 和 goal 。 整数 x 的值最开始设为 start &#xff0c;你打算执行一些运算使 x 转化为 goal 。你可以对数字 x 重复执行下述运算&#xf…

Django Rest Framework(一)

一、什么是RESTful REST与技术无关&#xff0c;代表一种软件架构风格&#xff0c;REST是Representational State Transfer的简称&#xff0c;中文翻译为“表征状态转移”。 REST从资源的角度审视整个网络&#xff0c;它将分布在网络中某个节点的资源通过URL进行标识&#xff0c…

光落在你脸上,可爱一如往常

沙沙野 https://www.ssyer.com让作品遇见全世界图片来自&#xff1a;沙沙野沙沙野 https://www.ssyer.com让作品遇见全世界图片来自&#xff1a;沙沙野沙沙野 https://www.ssyer.com让作品遇见全世界图片来自&#xff1a;沙沙野沙沙野 https://www.ssyer.com让作品遇见全世界图…

数据可视化机器学习工具在线_为什么您不能跳过学习数据可视化

数据可视化机器学习工具在线重点 (Top highlight)There’s no scarcity of posts online about ‘fancy’ data topics like data modelling and data engineering. But I’ve noticed their cousin, data visualization, barely gets the same amount of attention. Among dat…

2047. 句子中的有效单词数

2047. 句子中的有效单词数 句子仅由小写字母&#xff08;‘a’ 到 ‘z’&#xff09;、数字&#xff08;‘0’ 到 ‘9’&#xff09;、连字符&#xff08;’-’&#xff09;、标点符号&#xff08;’!’、’.’ 和 ‘,’&#xff09;以及空格&#xff08;’ &#xff09;组成。…

fa

转载于:https://www.cnblogs.com/smallpigger/p/9546173.html

python中nlp的库_用于nlp的python中的网站数据清理

python中nlp的库The most important step of any data-driven project is obtaining quality data. Without these preprocessing steps, the results of a project can easily be biased or completely misunderstood. Here, we will focus on cleaning data that is composed…

51Nod 1043 幸运号码

1 #include <stdio.h>2 #include <algorithm>3 using namespace std;4 5 typedef long long ll;6 const int mod 1e9 7;7 int dp[1010][10000];8 // dp[i][j] : i 个数&#xff0c;组成总和为j 的数量9 10 int main() 11 { 12 int n; 13 scanf("%d…

一张图看懂云栖大会·上海峰会重磅产品发布

2018云栖大会上海峰会上&#xff0c;阿里云重磅发布一批产品并宣布了新一轮的价格调整&#xff0c;再次用科技普惠广大开发者和用户&#xff0c;详情见长图。 了解更多产品请戳&#xff1a;https://yunqi.aliyun.com/2018/shanghai/product?spm5176.8142029.759399.2.a7236d3e…

488. 祖玛游戏

488. 祖玛游戏 你正在参与祖玛游戏的一个变种。 在这个祖玛游戏变体中&#xff0c;桌面上有 一排 彩球&#xff0c;每个球的颜色可能是&#xff1a;红色 ‘R’、黄色 ‘Y’、蓝色 ‘B’、绿色 ‘G’ 或白色 ‘W’ 。你的手中也有一些彩球。 你的目标是 清空 桌面上所有的球。…

【黑客免杀攻防】读书笔记14 - 面向对象逆向-虚函数、MFC逆向

虚函数存在是为了克服类型域解决方案的缺陷&#xff0c;以使程序员可以在基类里声明一些能够在各个派生类里重新定义的函数。 1 识别简单的虚函数 代码示例&#xff1a; #include "stdafx.h" #include <Windows.h>class CObj { public:CObj():m_Obj_1(0xAAAAAA…

怎么看另一个电脑端口是否通_谁一个人睡觉另一个看看夫妻的睡眠习惯

怎么看另一个电脑端口是否通In 2014, FiveThirtyEight took a survey of about 1057 respondents to get a look at the (literal) sleeping habits of the American public beyond media portrayal. Some interesting notices: first, that about 45% of all couples sleep to…

495. 提莫攻击

495. 提莫攻击 在《英雄联盟》的世界中&#xff0c;有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希&#xff08;编者注&#xff1a;寒冰射手&#xff09;进入中毒状态。 当提莫攻击艾希&#xff0c;艾希的中毒状态正好持续 duration 秒。 正式地讲&#xff0c;提莫在…

Java基础之Collection和Map

List&#xff1a;实现了collection接口&#xff0c;list可以重复&#xff0c;有顺序 实现方式&#xff1a;3种&#xff0c;分别为&#xff1a;ArrayList&#xff0c;LinkedList&#xff0c;Vector。 三者的比较&#xff1a; ArrayList底层是一个动态数组&#xff0c;数组是使用…

20155320《网络对抗》Exp4 恶意代码分析

20155320《网络对抗》Exp4 恶意代码分析 【系统运行监控】 使用schtasks指令监控系统运行 首先在C盘目录下建立一个netstatlog.bat文件&#xff08;由于是系统盘&#xff0c;所以从别的盘建一个然后拷过去&#xff09;&#xff0c;用来将记录的联网结果格式化输出到netstatlog.…