实用算法实现-第 14 篇 启发式搜索

禁忌搜索(Tabu Search)算法及python实现 禁忌搜索(Tabu Search)算法解决及python实现 禁忌搜索(Tabu Search,TS,又称禁忌搜寻法)是一种现代启发式算法,由美国科罗拉多大学教授Fred Glover在1986年左右提出的,是一个用来跳脱局部最优解的搜索方法。其先创立一个初始化的方案;基于此,算法“移动”到一相邻的方案。经过许多连续的移动过程,提高解的质量。本Markdown编辑器使用StackEdit修改而来... 阅读详情

14.1    A*搜索

A*(A star)算法是一种很好的树搜索策略,在许多人工智能的书籍中有所介绍。比如《人工智能,一种现代方法》和《人工智能,复杂问题求解的结构和策略》。

[i]文介绍到,A*算法使用估价函数F(N)来估算从初始状态S到当前状态N,再到目标状态T需要的最小步数。有公式:

F(N) = G(N) + H(N)

其中,G(N)是起始状态S到当前状态的实际代价G(N),它比最佳路径的代价G*(N)大。

H(N)是从当前状态到目标状态T的实际代价的估算值H*(N),它比实际代价H(N)大。

对于一个起始状态到当前状态的实际路径,G(N)是已经决定的。H(N)的选择则至关重要。有两个限制:

1. H(N)一定要小于等于当前结点N至目标结点T的实际代价。

2. 任意结点的F值必须大于其父辈状态的F值,即F单调递增。

当估价函数F满足以上两个限制条件,则启发式搜索算法一定能得出问题的最优解。

14.1.1   实例

PKU JudgeOnline, 1077, Eight.

14.1.2   问题描述

15数码游戏就是完成类似下面的转换的一种游戏:

1  2 3  4    1 2  3  4   1  2  3 4    1  2 3  4

5  6 7  8    5 6  7  8   5  6  7 8    5  6 7  8

9  x 10 12   9 10  x 12    9 10 11 12    9 10 11 12

1314 11 15   13 14 11 15   13 14 x 15   13 14 15  x

           r->           d->           r->

    8数码游戏类似,只不过只有8个数码而已。

    给出8数码游戏的一个初始状态,求达到目标状态的一个解,不要求是最优解。如果没有解,输出“unsolvable”。

14.1.3   输入

2 3  4  1 5  x  7 6  8

1.1.4   输出

ullddrurdllurdruldr

14.1.5   分析

《人工智能,一种现代方法》对使用A*算法解决八数码问题进行了深入的分析。提出了两种启发函数的策略:

1. h1 = 不在位的棋子的总数。

2. h2 = 所有棋子到其目标位置的曼哈顿距离的总和。

并且通过实验,得到h2的性能总是优于h1。

具体实现中,用到最小堆实现的优先队列。

这里还需要用到一个排列到整数的映射方法,以判断一种状态是不是已经遍历过。一个具体的映射方法如下:

把9看成插到8的排列中,那么有9种插法,可以把362880等分成9段,分别代表一个位置,每段递归处理。

令pos(a)为数字a在排列中排在a前面并且小于a的数字的个数,那么有伪代码:

int n=1;

for (int i=1; i<10; i++)

{

     n+=pos(i)*(i-1)!;

}

     下面程序中int calPos1(node *temp)和int calPos(node *temp)就是两种映射方法。

也许[ii]中介绍的排列的“反序”概念,能很好地用来解释上面这个算法。

14.1.6   程序

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
bool visited[362880];
#define maxNum     10000000
#define MAX        0x7F7F7F7F
struct tile{
     int x;
     int y;
};
#define maxLength 100//貌似最数码游戏的解长度为...
struct node{
     tile pos[3][3];
     int key;
     charop[maxLength];
     int blankX;
     int blankY;
};
nodeminHeap[maxNum];
int heapSize;
void minHeapify(int i)
{
     int l;
     int r;
     int min;
     node temp;
     l = i * 2;
     r = i * 2 + 1;
     min = i;
     if((l <=heapSize)&&
     (minHeap[l].key < minHeap[min].key)){
         min = l;
     }
     if((r <=heapSize)&&
     (minHeap[r].key < minHeap[min].key)){
         min = r;
     }
     if(min !=i)
     {
         temp = minHeap[min];
         minHeap[min] = minHeap[i];
         minHeap[i] = temp;
         minHeapify(min);
     }
}
void buildMinHeap()
{
     int i;
     for(i =heapSize / 2; i > 0; i--){
         minHeapify(i);
     }
}
nodeheapExtractMin()
{
     node min;
     if(heapSize< 1)
     {
         cout << "ERROR:no more" << endl;
     }
     min = minHeap[1];
     minHeap[1] = minHeap[heapSize];
     heapSize--;
     minHeapify(1);
     return min;
}
void heapIncreaseKey(int i, int key)
{
     node temp;
     if(key >minHeap[i].key)
     {
         cout << "ERROR:new key is smaller than current key" << endl;
     }
     minHeap[i].key = key;
     while(i> 1 && minHeap[i/2].key > minHeap[i].key)
     {
         temp = minHeap[i];
         minHeap[i] = minHeap[i/2];
         minHeap[i/2] = temp;
         i = i / 2;
     }
}
void minHeapInsert(node temp)
{
     heapSize++;
     minHeap[heapSize] = temp;
     minHeap[heapSize].key = MAX;
     heapIncreaseKey(heapSize, temp.key);
}
inline int solved(node *temp)
{
     int i, j;
     for(i = 0;i < 3; i++){
         for(j =0; j < 3; j++){
              if((*temp).pos[i][j].y!= i || (*temp).pos[i][j].x != j)
              {
                   return0;
              }
         }
     }
     return 1;
}
int adj[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
char operation[4] = {'l', 'r', 'u', 'd'};
int calKey(node *temp, int blankX2, int blankY2)
{
     int key;
     int x1;
     int y1;
     int x2;
     int y2;
     int blankX1= (*temp).blankX;
     int blankY1= (*temp).blankY;
     key = 1;
     x1 = abs((*temp).pos[blankY1][blankX1].x -blankX1);
     y1 = abs((*temp).pos[blankY1][blankX1].y -blankY1);
     x2 = abs((*temp).pos[blankY2][blankX2].x -blankX2);
     y2 = abs((*temp).pos[blankY2][blankX2].y -blankY2);
     key += - (x1 + y1 + x2 + y2);
     x1 = abs((*temp).pos[blankY2][blankX2].x -blankX1);
     y1 = abs((*temp).pos[blankY2][blankX2].y -blankY1);
     x2 = abs((*temp).pos[blankY1][blankX1].x -blankX2);
     y2 = abs((*temp).pos[blankY1][blankX1].y -blankY2);
     key += x1 + y1 + x2 + y2;
     return key;
}
int factorial[9] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};
int calPos1(node *temp)
{
     int i;
     int j;
     int x, y;
     int x1, y1;
     int temp1,temp2;
     int num;
     int sum;
     sum = 0;
     for(i = 0;i < 9; i++)
     {
         y = i / 3;
         x = i % 3;
         temp1 = (*temp).pos[y][x].x +(*temp).pos[y][x].y * 3;
         num = 0;
         for(j =0; j < i; j++)
         {
              y1 = j / 3;
              x1 = j % 3;
              temp2 = (*temp).pos[y1][x1].x +(*temp).pos[y1][x1].y * 3;
              if(temp2< temp1)
              {
                   num++;
              }
         }
         sum += (temp1 - num) * factorial[9 - i- 1];
        
     }
     return sum;
}
int calPos(node *temp)
{
    inti,j,k=0,b[9],ret=0,num=0;
    for(i=0;i<3;i++)
        for(j=0;j<3;j++)
            b[k++]=(*temp).pos[i][j].x +(*temp).pos[i][j].y * 3;
    for(i=0;i<9;i++)
    {
        num=0;
        for(j=0;j<i;j++)
            if(b[j]>b[i])  num++;
        ret+=factorial[i]*num;
    }
    return ret;
}
int main()
{
     int i;
     int j;
     int x;
     int y;
     int blankX;
     int blankY;
     char c;
     int length;
     node insertNode;
     node temp;
     int pos;
     bool find;
     insertNode.key = 0;   
     for(i = 0;i < 3; i++){
         for(j =0; j < 3; j++){
              cin >> c;
              if(c== 'x'){
                   insertNode.blankY = i;
                   insertNode.blankX = j;
                   insertNode.pos[i][j].x = 2;
                   insertNode.pos[i][j].y = 2;
              }else{
                   x = c - '1';
                   y = x / 3;
                   x = x % 3;
                   insertNode.pos[i][j].x = x;
                   insertNode.pos[i][j].y = y;
              }
              insertNode.key +=abs(insertNode.pos[i][j].x - j);
              insertNode.key +=abs(insertNode.pos[i][j].y - i);
         }
     }
     heapSize = 0;
     for(i = 0;i < maxLength; i++)
     {
         insertNode.op[i] = '\0';
     }
     memset(visited, 0, sizeof(visited));
     pos = calPos(&insertNode);
     visited[pos] = 1;
     minHeapInsert(insertNode);
     find = 0;
     int count =0;
     while(heapSize> 0){
         if(heapSize> maxNum)
         {
              cout <<endl<< "Too large" << endl;
              return-1;
         }
         temp = heapExtractMin();
         if(solved(&temp)== 1)
         {
              find = 1;
              cout << temp.op <<endl;
              break;
         }
         for(i =0; i < 4; i++){
              blankX = temp.blankX;
              blankY = temp.blankY;
              y = blankY + adj[i][0];
              x = blankX + adj[i][1];
              count++;
              if(x< -1 || x > 3 || y < -1 || y > 3)
              {
                   while(1)
                   {}
              }
              if(x< 0 || y < 0 || x > 2 || y > 2)
              {
                   continue;
              }
              insertNode = temp;
              insertNode.pos[y][x].x =temp.pos[blankY][blankX].x;
              insertNode.pos[y][x].y =temp.pos[blankY][blankX].y;
              insertNode.pos[blankY][blankX].x =temp.pos[y][x].x;
              insertNode.pos[blankY][blankX].y =temp.pos[y][x].y;
              pos = calPos(&insertNode);
              if(visited[pos]!= 0){
                   continue;
              }
              visited[pos] = 1;
              insertNode.key +=calKey(&temp, x, y);
              insertNode.blankX = x;
              insertNode.blankY = y;
              length = strlen(temp.op);
              insertNode.op[length] =operation[i];
              minHeapInsert(insertNode);
         }
     }
     if(find ==0)
     {
         printf("unsolvable\n");
     }
     return 1;
}

14.2    IDA*搜索

A*算法减少存储需求的最简单的方法就是将迭代深入的思想用在启发式搜索上,形成迭代深入A*算法,即IDA*。

使用BFS搜索需要实用一个队列,这个队列如果过大就可能超出内存限制。用DFS代替BFS,可以减少存储需求。

IDA*算法实际上是在迭代加深的深度优先搜索的基础上进行的一种改进。迭代加深的深度优先搜索使用当前搜索深度来判断是否停止搜索,而IDA*算法则使用A*算法的估价函数F(N) = G(N) + H(N)来判断是否停止搜索。可以知道,此时的G(N)就是当前搜索深度,H(N)则是对于从当前结点N至目标结点T的实际代价一种乐观估计。说H(N)乐观,是因为在设计估价函数的时候,H(N)被约束为小于等于实际代价。由此可知,相对于朴素的迭代加深的深度优先搜索,IDA*算法省去了一些不必要的搜索。

14.2.1   实例

PKU JudgeOnline, 2286, The Rotation Game.

14.2.2   问题描述


如上图一种游戏,给定初始状态,通过拉动A到H的,对该行或列进行旋转。目标是使得中间的八个数字相等。

输出字典序最小的最优解的旋转过程,及其最终状态时中间的数字。

14.2.3   输入

11 1 1 3 2 3 2 3 1 3 2 2 3 1 2 2 2 3 1 2 1 3 3

11 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3

0

14.2.4   输出

AC

2

DDHH

2

14.2.5   分析

对搜索的深度给一个步数限制。每次在状态空间里进行DFS搜索的时候,如果遇见当前状态决定了已经不可能在限制内找到解,就返回,而不再搜索其子状态。如果这次DFS没找到,就继续放宽限制,重新对状态空间进行DFS。如此反复直到找到一个解。

显然这个解是最优的解。

确保解字典序最小的办法是DFS中顺次地从A到H中选择子状态。

14.2.6   程序

#include <iostream>
using namespace std;
 
int a[25];
int res[1000];
int ans;
int limit;
 
int state[8][7][2] = {
     { {1,23}, {3,1}, {7,3}, {12,7}, {16,12},{21,16}, {23,21} },
     { {2,24}, {4,2}, {9,4}, {13,9}, {18,13},{22,18}, {24,22} },
     { {11,5}, {10,11}, {9,10}, {8,9}, {7,8},{6,7}, {5,6} },
     { {20,14}, {19,20}, {18,19}, {17,18},{16,17}, {15,16}, {14,15} },
     { {24,2}, {22,24}, {18,22}, {13,18},{9,13}, {4,9}, {2,4} },
     { {23,1}, {21,23}, {16,21}, {12,16},{7,12}, {3,7}, {1,3} },
     { {14,20}, {15,14}, {16,15}, {17,16},{18,17}, {19,18}, {20,19} },
     { {5,11}, {6,5}, {7,6}, {8,7}, {9,8},{10,9}, {11,10} }
 
};
 
 
int isSuccess()
{
     int ll =a[7];
     if(a[8]!=ll|| a[9]!=ll || a[12]!=ll || a[13]!=ll ||
         a[16]!=ll || a[17]!=ll || a[18]!=ll)
         return0;
     return ans= ll;
}
 
int getval()
{
     int i;
     int cnt[4];
     memset(cnt,0,sizeof(cnt));
     for(i = 7;i <=9 ;i++)cnt[a[i]]++;
     for(i = 12;i <=13 ;i++)cnt[a[i]]++;
     for(i = 16;i <=18 ;i++)cnt[a[i]]++;
     return8-max(cnt[1],max(cnt[2],cnt[3]));
}
 
int dfs(int t)
{
     inttemp[25];
     if(t==limit)
         returnisSuccess();
     if(t +getval() > limit)return 0;
     for(int i = 0 ; i < 8 ; i++)
     {
         res[t] = i;
         memcpy(temp,a,sizeof(a));
         for(int j = 0 ; j < 7 ; j++)
              a[state[i][j][1]] =temp[state[i][j][0]];
         int ret= dfs(t+1);
         memcpy(a,temp,sizeof(temp));
         if(ret!=0)return ret;
     }
     return 0;
}
 
 
int main()
{
     while(true)
     {
         scanf("%d",&a[1]);
         if(!a[1])
              break;
         for(int i = 2; i <=24; i++)
              scanf("%d",&a[i]);
         if(isSuccess())
         {
              cout<<"No moves needed"<<endl<<a[7]<<endl;
              continue;
         }
         limit = 1;
         while(dfs(0)== 0)limit++;
         for(int i = 0 ; i < limit ;i++)putchar((char)(res[i]+'A'));
         printf("\n%d\n",ans);
     }
     system("pause");
     return 0;
}
本文章欢迎转载,请保留原始博客链接http://blog.youkuaiyun.com/fsdev/article


[i] 实用算法的分析与程序设计。吴文虎,王建德。

[ii] The Art of Computer Programming, Volume 3, Sorting and Searching.Donald E. Knuth.

A*搜索算法(python) 先了解一下什么是A*算法。 A*搜寻算法,俗称A星算法。这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法。常用于游戏中的NPC(Non-Player-ControlledCharacter)的移动计算,或线上游戏的BOT(ROBOT)的移动计算上。该算法像Dijkstra算法一样,可以找到一条最短路径;也像BFS一样,进行启发式的搜索。 A*算法是一种启发式搜索算法,启... 阅读详情

相关推荐

实用算法实现-第13篇 搜索(盲目搜索)

在人工智能中,盲目搜索是相对于启发式搜索来说的。 13.1    广度优先搜索 《算法导论》中,广度优先(Breadth-First)搜索树的伪代码如下: BFS(G,s) 1  for each vertex u ∈ V[G] - {s} 2       docolor[u] ← WHITE 3          d[u] ← ∞ 4          ∏[u] ← NIL

李希的博客 1万+

【人工智能实验】A*算法求解8数码问题

1、画出A*算法求解N数码问题的流程图。根据A*算法的实验原理,;这样估价函数f(n)在g(n)一定的情况下,会或多或少的受距离估计值h(n)的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行,因此f是根据需要找到一条最小代价路径的观点来估算节点的。设计A*算法的流程图如图4.1.1所示,按照流程图编写伪代码,进而编写完整的程序。其中OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。

weixin_43442778的博客 12万+

【第31话:路径规划】自动驾驶启发式搜索算法(A星搜索算法( A* 搜索算法))详解及代码举例说明

本文详细介绍了自动驾驶系统中启发式搜索算法(以A算法为例)的原理与应用。文章首先阐述了启发式搜索的基础概念,包括代价函数、启发式函数及其在自动驾驶路径规划中的重要性。接着重点解析A算法的运作机制,强调其通过优先队列和启发式函数实现高效搜索的特点。文章还提供了A*算法的Python实现示例,展示了其在网格地图中的实际应用。最后,作者探讨了算法在自动驾驶中的优化方向,如动态环境处理和启发式设计改进,并指出未来可能的发展趋势,包括与机器学习结合和硬件加速等。全文兼顾理论与实操,为自动驾驶路径规划提供了清晰的技术指

一碗白开水一 1290

A*算法中的估价函数

这两天在编写人工智能大作业,主要是A*寻路算法这方面,加之考试中会涉及到估价函数这方面的考点,所以我就对A*算法中的估价函数做一下总结。 首先,先说下启发式搜索。在空间很大的情况下,如果只是采取广度优先的方法,效率会非常低。启发式搜索就是对状态空间中的每一步进行评估,获得最有可能在最终路线上的点,比方说走迷宫,终点在右下角,那就会优先向右下角移动,每次移动都具有目的方向性。 其

dala_da的博客 3万+

14、图搜索算法:从基础到启发式搜索的全面解析

本文全面解析了多种图搜索算法,包括深度受限搜索(DLS)、广度优先搜索(BFS)、一致代价搜索(UCS)、迭代加深深度优先搜索(IDDFS)、双向搜索及启发式搜索等。详细介绍了每种算法的原理、优缺点、时间与空间复杂度,并通过示例和伪代码帮助理解。文章还对比了各类算法的完整性与最优性,提供了算法选择策略、优化思路及在游戏开发、物流配送和社交网络中的实际应用案例,旨在帮助读者根据问题特征选用最合适搜索算法并进行性能优化。

wind6的博客 100

智能搜索中启发函数的选择及启发能力分析 (2007年)

以八数码难题实例的启发式搜索,分析了估价函数 f( n)中不同的启发函数 h( n)对搜索过程的影响,比较了3种不同 h(n)的搜索效率。指出了选择最佳启发函数 h*( n)的原则,讨论了八数码难题启发函数思路的通用性,并对A*算法及其可纳性和启发能力进行了深入研究。

启发式A*算法解决最短路径问题

A*算法: 在搜索的过程中,使用一个估价函数对当前点进行评估,找到最好的状态进行搜索,知道找到目标。 估价函数F(x)=G(x)+H(x),其中G(x)为实际代价,H(x)为启发函数,这就是启发式。并且启发函数要满足:H(x)<=H*(x),H*(x)为真实值,意思是启发函数的要求是必须小于等于真实值,启发函数的选取决定着A*算法的优劣,当启发值与真实值完全相等时,此时会达到最优的情况。 A*算法解决最短路问题 A*算法是一种启发式算法,在最短路径问题上是对Dijkstra算法的优化, 加入启发函数提

weiambt的博客 5469

计组实验之四路表决器

请在之前四路表决器电路实现的基础上,继续用连接线 联接CD4511,将投票为1的票数总和显示到一个 LED上,思考如何做?由于我们需要通过显示字形来直接看出有几个1,在这里,我们最多有四个1,即显示字形最多到4就行,所以我们需要将有几个1用2进制数来表示,下面给出了相关电路图。显示输入插口,按真值表(自拟)要求,逐次改变输入变量, 测量相应的输出值,验证逻辑功能, 与表3-1 进行比较, 验证所设计的逻辑电路是否符合要求。用实验结果与真值表3-1和3-2进行比对,可以得出,我们实验结果是正确的。

szyugly的博客 1万+

【人工智能大作业】A*和IDA*搜索算法解决十五数码(15-puzzle)问题 (Python实现)(启发式搜索)

【人工智能】启发式搜索算法,A*和IDA*搜索算法解决十五数码(15-puzzle)问题 Python实现,理论算法分析与实验证明

MaxwellWong 1万+

反激电源RCD尖峰吸收电路的原理以及调试

反激电源RCD尖峰吸收电路的原理以及调试

mnmmnmn的博客 9250

RTT(RT-Thread)串口设备(RTT保姆级教程)

本章主要介绍串口设备在RT-Thread操作系统中应用层如何使用。关于串口设备的使用,我们只需要在应用层找到串口设备,然后去初始化,初始化完成以后就可以读写串口设备了。操作的方法在应用层,驱动是不需要我们去完成的,驱动已经在操作系统中提供了。

qq_25218501的博客 1万+

启发式路径搜索算法介绍

作者丨Arwin(Haowen Yu)来源丨古月居前言启发式搜索(Heuristically Search)又称为有信息搜索(Informed Search),它是利用问题拥有的启发信息来引导搜索,达到减少搜索范围、降低问题复杂度的目的,这种利用启发信息的搜索过程称为启发式搜索。简单来说,就是已知起点和终点位置,寻找最佳路径。启发式搜索方法(Dijkstra sear...

3D视觉工坊 3058

STM32笔记:高精度脉冲宽度计 双输入捕获+DMA方式

本文介绍如何用STM32F107VC实现高精度的脉冲宽度计(测量周期脉冲的占空比)。 采用定时器的外部输入捕获功能,双输入+DMA方式,追求硬件的极限表现。

st01lsp的专栏 5289

启发式算法

启发式算法

JAZJD的博客 2384

癌症免疫治疗预测神器TIDE:从原理到实战(避坑指南)

本文详细解析了癌症免疫治疗预测工具TIDE的核心原理及实战应用。TIDE算法通过模拟肿瘤免疫逃逸的两种核心机制(T细胞功能障碍和排除),为临床决策提供精准预测。文章涵盖数据准备、标准化流程、网页工具操作指南及结果解读,帮助科研人员和临床医生避开常见误区,优化免疫治疗策略。

weixin_29309475的博客 199

麻雀搜索算法(SSA)详解:从鸟群智能到优化实践

麻雀搜索算法(SSA)是一种新型群智能优化算法,模拟麻雀群体的觅食行为和反捕食机制。该算法将优化问题转化为麻雀群体对食物源的搜索过程,通过发现者、加入者和警戒者的角色分工实现高效优化。SSA具有原理新颖、参数合理、收敛快速等特点,在函数优化、工程设计和机器学习等领域展现出良好应用前景。算法通过数学模型模拟麻雀的觅食策略,包括发现者全局探索、加入者局部开发和警戒者危险预警机制,有效平衡了全局搜索与局部开发能力。SSA相比传统优化算法具有更好的收敛性和优化效果。

qq_42212808的博客 1072

五种常见启发式算法求解TSP问题-总结篇

总结五种常见启发式算法(遗传算法、禁忌搜索算法、模拟退火算法、蚁群算法和粒子群算法)求解TSP问题的效果,并针对存在的问题进行简单讨论。

_2312 1万+

基于STM32的录音机设计(STM32F103+VS1053B)

本项目设计并实现了一款基于STM32微控制器的便携式录音机。该录音机采用STM32F103C8T6作为主控芯片,结合VS1053B音频编解码模块、SD卡存储、OLED显示屏以及按键模块,提供了手动录音、自动录音和录音回放等多种功能。

1万+

启发式搜索A*算法

A*寻路算法 (2011-02-15 10:53:11) 转载▼ 标签: 游戏 分类:算法 概述 虽然掌握了 A* 算法的人认为它容易,但是对于初学者来说, A* 算法还是很复杂的。 搜索区域(The Search Area) 我们假设某人要从 A 点移动到 B 点,但是这两点之间被一堵墙隔开。如图 1 ,绿...

dianxuanfan4560的博客 1240

【光子 AI】AI Agent 知识体系深度研究报告

从理论基础到前沿应用:全面解析人工智能代理的核心架构、关键技术与发展趋势📅 2026 年 3 月 | 📊 深度研究报告 | 🔬 人工智能领域 | 📈 前沿技术分析**AI Agent(人工智能代理)**是一种能够感知环境、基于所获得的信息做出决策,并执行行动以影响该环境的软件系统。AI Agent 的设计旨在模仿或实现智能行为,它们可以在各种环境中操作,包括物理世界和虚拟空间。随着大语言模型(LLM)技术的突破性进展,AI Agent 正从实验室研究快速走向产业应用。根据 Gartner 发布的《2

AI天才研究院 177

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

c语言启发式搜索,启发式搜索(heuristic search)

在宽度优先和深度优先搜索里面,我们都是根据搜索的顺序依次进行搜索,可以称为盲目搜索,搜索效率非常低。而启发式搜索则大大提高了搜索效率,由这两张图可以看出它们的差别:(左图类似与盲搜,右图为启发式搜索)(图片来源) 很明显启发式的搜索效率远远大于盲搜。什么是启发式搜索(heuristic search)利用当前与问题有关的信息作为启发式信息,这些信息是能够提升查找效率以及减少查找次数的。如何使用...

weixin_32369749的博客 1067

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

N数码问题的启发式搜索算法--A*算法python实现

一、启发式搜索:A算法 1)评价函数的一般形式 : f(n) = g(n) + h(n) g(n):从S0到Sn的实际代价(搜索的横向因子) h(n):从N到目标节点的估计代价,称为启发函数(搜索的纵向因子); 特点: 效率高, 无回溯, 搜索算法 OPEN表 : 存放待扩展的节点. CLOSED表 : 存放已被扩展过的节点. 2)评价函数 f(x) = g(x) +...

weixin_30693683的博客 994

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

DAY14打卡 启发式算法

表现好的个体(高验证分)更有机会“繁殖”(它们的参数组合会被借鉴和混合),并可能发生“变异”(参数随机小改动),产生下一代。它会记住自己飞过的最好位置,也会参考整个“鸟群”发现的最好位置,结合这两者来调整自己的飞行方向和速度,同时带点随机性。应用感觉: 像一个有点“冲动”的探险家,初期愿意尝试一些看起来不太好的路径(为了跳出局部最优的小山谷),后期则越来越“保守”,专注于在当前找到的好区域附近精细搜索。应用感觉: 像是一群探险家,既有自己的探索记忆,也会互相交流信息(全局最佳位置),集体协作寻找目标。

PJ1ul的博客 832

八数码问题-A*(AStar)算法实现

八数码问题可以说得上是搜索问题中比较经典的,可以有很多种搜索策略,比如说有最常见的BFS,DFS,此外,A*也是一个比较普遍的搜索算法。在八数码问题A*往往可以得到最优的求解路径。

Broken Geeker 5万+
上一篇: 实用算法实现-第13篇 搜索(盲目搜索)
下一篇: 实用算法实现-第 15 篇 对抗搜索
存储李希
博客等级 码龄15年 418粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值