当前位置: 首页 > news >正文

学会玩游戏,智能究竟从何而来?

最近在读梅拉妮·米歇尔《AI 3.0》第三部分第九章,谈到学会玩游戏,智能究竟从何而来?

作者: [美] 梅拉妮·米歇尔
出版社: 四川科学技术出版社·湛庐
原作名: Artificial Intelligence: A Guide for Thinking Humans
译者: 王飞跃 / 李玉珂 / 王晓 / 张慧
出版年: 2021-2
装帧: 平装
ISBN: 9787572700378

Google DeepMind团队在强化学习研究工作中将Q学习与DNN相结合,深度Q学习Deep Q-learning和深度Q网络Deep Q-network,监督学习和强化学习之间的核心差异:如何更新权重。强化学习不是将其输出与人类给定的标签进行匹配,而是假设后续迭代给出的值比前面迭代给出的值更好,网络学习的是使其输出在一次迭代到下一次迭代的过程中保持一致。这是深度Q学习如何应用于《打砖块》的工作原理。

系统将其当前状态作为深度Q网络的输入,深度Q网络为每个可能的动作输出一个值,系统选择并执行一个动作,产生一个新的状态。然后,学习开始了:系统将其新状态输入网络,网络为每个动作输出一组新值。新值集与原值集之间的差异被认为是网络的“误差”,这个误差再经过反向传播来改变网络的权重。这些步骤在许多片段中执行,即游戏回合中重复执行。此处的深度Q网络、虚拟操纵杆和游戏本身都是运行在计算机上的软件。

需要一些技巧来对这种算法进行改进和加速。系统从一款游戏中学到的知识,即网络权重,无法迁移到另一款游戏上。每一款游戏,系统都需要经过上千个片段的训练,但是该过程可以通过先进的计算机硬件比较快速地完成。

书中提到二十世纪七八十年代雅达利(英语:Atari,NASDAQ:ATAR),它是美国诺兰·布什内尔在1972年成立的电脑公司。在此回看雅达利的经典游戏主机及其故事。

1974年,19岁的乔布斯从里德学院退学,那是充满自由精神的学校,同时也是美国收费最为高昂的私立大学之一。退学后,乔布斯计划找一份工作来养活自己。雅达利在San Jose Mercury刊登的招聘广告吸引了他。雅达利的广告词是这样写的:Have fun, Make money,又爽又赚钱。

乔布斯到雅达利公司应聘,说自己要得到这份工作,不然不会离开。

下图是乔布斯在雅达利公司填写的个人简历。

时任雅达利首席工程师的阿尔康接到了电话,人事跟阿尔康说道:“公司大厅有个嬉皮士。他说在我们雇佣他之前他不会离开,我们应该报警还是让他进来?”

阿尔康说道:“让他进来吧。”不修边幅的乔布斯让人惊讶,而在与乔布斯的交谈中,阿尔康感受到了这位年轻人对技术的热情,他决定聘用乔布斯。另外一个重要原因是,19岁肄业乔布斯要求的工资并不高。乔布斯成为了雅达利的第40号员工。

才华横溢又喜欢嘲讽同事的乔布斯在雅达利并不讨人喜欢,他不爱洗澡带来的浓烈体味引发了很多投诉。阿尔康对此不以为意,只是让乔布斯晚上来工作,这样就跟大家避开了。

雅达利的工作让乔布斯攒够了去印度修行的钱,他远赴印度修行7个月后,1975年又回到雅达利。

这就是乔布斯如何来到了雅达利。

毫无悬疑地,布什内尔计划用一个新的骗局来压榨阿尔康的生产力。他不知道的是,身为摩羯座的阿尔康是一个自我驱动能力极强的顶尖工程师。

布什内尔告诉阿尔康,他负责的新项目是雅达利跟通用电气公司的合作合同,而不是Bally的产品。通用电气的要求是:游戏街机硬件成本不能高于15美元。阿尔康对此毫不知情,他完全按照布什内尔的意见推动这款产品开发。

某次采访中,记者问到阿尔康当时的场景,阿尔康是这样回答的。

So how did Nolan actually describe the game that became Pong to you? Did he give you a detailed design document?
Oh no, it was just a very general goal: let’s create a ping pong game on a TV screen where you’re looking down on it. One spot that moves, two paddles… just to get that on the screen with the limited technology we had was pretty exciting for me.

翻译起来很简单:阿尔康,你去电视上搞一个乒乓球游戏,一个球动,两个拍子。 搞吧。

单纯的阿尔康,以为这是通用电气的项目,立刻全身心地投入到这个15美元街机方案的开发。为了实现预期的功能,他掏出了自己在Ampex工作时攒下来的硬件。因为开发资金的限制,阿尔康选择了最为物美价廉的TTL逻辑电路,7400系列芯片。对于阿尔康来说,他不仅要完成硬件设计,还要对游戏的体验进行改善。

他做到了。

在设计这款街机游戏时,阿尔康做了一些创新。因为基础游戏太无聊,缺乏变化,阿尔康将球拍分成了八段来改变球的反弹角度。比如正中央以90度返回,而其他的部位则用更小的角度。为了增加乐趣,他还将球进行分段计速,在球被击打十二个回合后,球在比赛中开始加速。

阿尔康让布什内尔试玩,布什内尔提了一些新的意见:比如游戏里有逼真的音效和喧闹的人群声。阿尔康仔细研究了这个产品需求,发现用同步发生器就可以实现击球和得分的音效。这可比米罗华奥德赛强多了,米罗华奥德赛跟早期的默片一样,属于无声游戏。

为了构造原型机,阿尔康在商店里买了一台75美元的日立黑白电视用来做显示设备。这种极限的成本压缩,给布什内尔和达布尼留下了深刻印象,他们认为低价是一种可能的竞争优势。

3个月的努力,阿尔康终于完成了Pong 。布什内尔、达布尼和阿尔康三人反复试玩了这个游戏。布什内尔觉得这款产品挺有吸引力,但有点像换皮的米罗华奥德赛的《网球》。如果拿出去发售,有可能遭遇到专利问题。

阿尔康认为这款产品最大的问题是硬件预算严重超标,远高于之前确定的15美元。而达布尼则认为Pong,可以交给Bally作为合同里那款新的街机方案。二人都同意把这款产品推出去,可布什内尔并不看好Pong。经过一次激烈的争论,布什内尔妥协了:他同意将Pong投放到雅达利的渠道里面试试水,当然,那是拉尔斯丁转让给他们的销售渠道。

在米罗华奥德赛和 Computer Space的普通表现后,电子游戏艺术史上第一个爆款游街机,就要上场了。

取得一致后,达布尼迅速完成了外壳、控制面板和投币装置的制作。他将其中的一台《Pong》送到了位于加利福尼亚州桑尼维尔的安迪·卡普 (Andy· Capp) 酒馆。这台看起来粗制滥造的街机就放在酒吧的酒桶上,没有任何说明。而阿尔康和达布尼则一人拿了一瓶啤酒,等待接下来发生的事情。

喝啤酒的时候,开始有人投币来尝试玩《Pong》。这台街机游戏的优势在于,不需要说明书,就可以让玩家知道自己要做什么。当晚,没有发生任何奇迹。

奇迹发生在一周后。

一周后,酒吧老板比尔打来电话,说机器坏了。

阿尔康一点都不惊讶,因为他知道这台原型机只是为了展示,而不是商用。只要轻轻一撞,它可能就要罢工。让阿尔康惊讶的是,它竟然可以撑到这么久才坏。

下班后,阿尔康带着工具去到了安迪·卡普酒馆,这时已经有几个人等在机器前面,埋怨他为什么姗姗来迟。作为Pong的发明者,阿尔康还挺惊讶这台机器竟然拥有了不少粉丝。等到他打开机器一看,发现投币箱竟然满了,里面有400多个25美分的硬币。

一周100美元,这个成绩相当不错了。

当阿尔康把这个消息告诉布什内尔时,布什内尔的回答是:这很有趣。

照片摄于1973年。

从左到右:左一:泰德·达布尼、左二:诺兰·布什内尔、左三:弗雷德·马林希克、左四:艾尔·阿尔康。

布什内尔带着另外一台Pong 去了芝加哥,想用这个替代之前Bally方案里所说的冰球游戏。

Bally觉得这个游戏有那么点意思,但是比起布什内尔之前提出要做的冰球街机,差得不是一点半点。Bally不想接受Pong,但是仍然推荐布什内尔将游戏卖给自己的子公司:Midway,可Midway同样看不上。

虽说好马不吃回头草,可脸皮极厚的布什内尔找到了曾经的东家,Nutting公司。没想到老板纳廷不仅表达了对Pong的蔑视,而且落井下石地说,自己找到新人来设计双人Computer Space街机游戏,原来的合同作废了。

没有人愿意给雅达利生产Pong,布什内尔抱着生产样机的目的,继续生产这台新型街机。1972年10月到11月之间,雅达利造出了12台Pong。这12台机器,10台送到了酒吧,1台留在公司,1台送给了Bally。

几周内,这10台机器就带来了非常可观的收入。布什内尔拿着Pong的市场反馈数据,想再一次说服Bally。怕Bally认为他们在数据中灌水,布什内尔还把数据压低了2/3 。即便如此,Bally还是不愿意接受雅达利Pong的设计方案。按照合约,如果Bally不明确拒绝Pong街机方案,雅达利不能生产,也不能授权其他厂商生产。

万般无奈,布什内尔提议:雅达利应该尝试自己生产Pong街机。

达布尼和阿尔康不同意他的提议,因为这个操作太过于冒险。Bally家大业大,雅达利如果故意违约,赔偿的金额可不是小数目。可二人明显架不住布什内尔的说服力,同意了由雅达利自己生产街机的方案。

三人与达布尼的兄弟一起组装出50台Pong街机,因为自己的仓库不够用,还在墙壁上打了一个洞,用上了隔壁闲置的库房。

此时Bally回复说,他们对Pong不感兴趣,按照合同条款,雅达利仍然要给Bally设计一款弹珠机。这就是明确拒绝了Pong方案了,布什内尔他们如释重负,开启了疯狂接单模式。

为了满足市场需求,布什内尔需要更多的资金来生产Pong街机。钱从哪里来呢?布什内尔跑了许多银行,银行家都认为Pong街机是弹珠机的变种。而在1970年的美国,弹珠机总会被跟黑手党联系到一起,所以布什内尔没能从银行贷到款。

直到富国银行给布什内尔贷了5万美元,才解决雅达利的资金问题。

Tips:

富国银行是巴菲特投资超32年的银行,也是巴菲特最成功的投资案例之一。

布什内尔买下了公司附近的一栋楼,开始招聘新员工生产Pong街机和送货,1972年12月,雅达利开始正式配送新的街机。

1973年2月后,雅达利已经可以向国外发货,Pong街机正式走向了全球。

对于一家年轻的公司,火爆的生意带来了大量新的考验。

Pong街机影响深远,是雅达利的开山之作,下一步的雅达利将走向何方呢?

1977年发行的雅达利Atari 2600 主机,商标Atari。

雅达利经典的游戏如银河小行星Aster-oids,太空入侵者Space-Invaders,乒乓Pong,吃豆人Pac-Man,打砖块Breakout等等。

Atari 2600 可分离式手柄、可更换卡带的设计思路延续至今,现在来看依然非常经典。凭借出色游戏软件和游戏设备,雅达利带领游戏行业从「蛮荒时代」逐渐走向了成熟。

由操纵杆控制的游戏对小孩子而言特别容易学,但是要让成年人保持兴趣却很难。

通过下面这个简短的故事,一起来感受下历史的脉搏:在 1972 年的美国,那时候的街机游戏机没有电脑主机,只能在芯片上集成晶体管电路,让晶体管控制电路开关,但是由于晶体管价格昂贵,每增加一个都是真金白银!所以雅达利一直希望能够在游戏设计中,减少芯片中晶体管的数量,那时候雅达利的员工制作一款游戏大约需要用到 150 个晶体管左右。这也让制作一台游戏机的成本一直很高。

史蒂夫·乔布斯(Steve Jobs)在好友斯蒂夫·盖瑞·沃兹尼亚克(Stephen Gary Wozniak)(当时他还在惠普工作)的帮助下设计了游戏《Breakout》,也就是「打砖块」游戏的鼻祖。实际上,《Breakout》可以理解为《Pong》的单机版本,后者是雅达利的首款电子游戏,也被誉为史上第一款街机电子游戏,需要两名玩家进行对战。

乔布斯告诉沃兹:必须要在 4 天之内完成设计,并且用尽可能少的芯片。完成工作之后的奖金,他们对半分。在接下来的四天里,两人几乎不眠不休,乔布斯负责创作原型和测试,沃兹负责技术方面的工作。没想到的是,这两位大佬还真在 4 天内做出做出了这款可以永远载入游戏历史的《 打砖块 》,并且整款游戏仅仅用了 44 个晶体管!

雅达利2600 Breakout于1976年5月13日发布。

游戏包括在屏幕的前三分之一铺上一层砖,玩家的目标是通过反复将球从球拍上弹到砖中来摧毁它们。1978年发布的雅达利VCS端口使用彩色图形,而不是彩色覆盖的单色屏幕。

粉碎!POW!屏幕顶部会出现一堵砖墙,你的任务是从游戏场上砸碎两堵墙——一块砖一块砖。使用控制器在屏幕底部移动拨杆。用球拍把球打到墙上。每次球碰到砖块,砖块就会消失,你就得分了。一个球员或球队每场比赛能得到五个球。当你用球拍打丢一个球时,球就会从屏幕上消失。按下红色控制器按钮,再发球一个球,直到五个球都打完为止。

Original Release: 1978
Action / Skill
One / Two Player

Original Code: CX2622

此外,Breakout是后续电脑应用程序某些方面的基础和灵感来源。

C语言复刻打砖块游戏:

#include <graphics.h>
#include <time.h>
//画砖块
int  map[5][8];//描述整个地图
HWND hwnd = NULL;
//用1-3 给数组赋值
void initMap() 
{for (int i = 0; i < 5; i++) {for (int j = 0; j < 8; j++) {map[i][j] = rand() % 3 + 1;}}
}
void drawMap() 
{setlinestyle(PS_SOLID, 2);setlinecolor(WHITE);for (int i = 0; i < 5; i++) {for (int j = 0; j < 8; j++){int x = 100*j ;		//j=x/100int y = 25*i ;		//i=y/iswitch (map[i][j])   //map[i][j]!=0{case 0:			//做消除用的break;case 1:setfillcolor(YELLOW);fillrectangle(x, y, x + 100, y + 25);break;case 2:setfillcolor(LIGHTBLUE);fillrectangle(x, y, x + 100, y + 25);break;case 3:setfillcolor(LIGHTGREEN);fillrectangle(x, y, x + 100, y + 25);break;}}}
}
//木板的过程
struct Board 
{int x;int y;int speed;COLORREF color;int width;int height;
};
//struct Board board = { 300, 800 - 25,1, WHITE, 200, 25 };
struct Board* createBoard(int x, int y, int  speed, COLORREF color, int width, int height) 
{struct Board* pBoard = (struct Board*)malloc(sizeof(struct Board));//结构体指针->成员   ->指针指向运算符//(*指针).成员;pBoard->x = x;pBoard->y = y;pBoard->speed = speed;pBoard->color = color;//结构体变量.成员(*pBoard).width = width;(*pBoard).height = height;return pBoard;
}
void drawBoard(struct Board* pBoard) 
{setfillcolor(pBoard->color);fillrectangle(pBoard->x, pBoard->y,pBoard->x + pBoard->width, pBoard->y + pBoard->height);
}
//木板的按键操作
void keyDown(struct Board* pBoard)
{//C语言: scanf函数 getch() getchar() gets()//异步的按键操作if (GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT)&&pBoard->x>=0) {pBoard->x -= pBoard->speed;}if (GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT)&&pBoard->x<=800-200) {pBoard->x += pBoard->speed;}
}
//球:
struct Ball 
{int x;int y;int r;				//半径int dx;int dy;COLORREF color;
};
struct Ball* createBall(int x, int y, int r, int dx, int dy, COLORREF color)
{struct Ball* pBall = (struct Ball*)malloc(sizeof(struct Ball));pBall->x = x;pBall->y = y;pBall->r = r;pBall->dx = dx;pBall->dy = dy;pBall->color = color;return pBall;
}
void drawBall(struct Ball* pBall)
{setfillcolor(pBall->color);solidcircle(pBall->x, pBall->y, pBall->r);
}
//1.反射
//2.撞击木板
int hitBoard(struct Ball* pBall, struct Board* pBoard) 
{if (pBall->y + pBall->r == pBoard->y) //y满足{if (pBall->x >= pBoard->x && pBall->x <= pBoard->x + pBoard->width) {return 1;}}return 0;
}
int die(struct Ball* pBall) 
{if (pBall->y > 800 - 25){return 1;}return 0;
}
//3.撞击砖块
int hitBricks(struct Ball* pBall) 
{//1.算出球的行的列是属于地图int ballJ = pBall->x / 100;int ballI = (pBall->y - pBall->r) / 25;//2.当前下标下,数组中不等于表示有砖块需要反射if (ballJ < 8 && ballI < 5 && map[ballI][ballJ] != 0) {map[ballI][ballJ] = 0;return 1;}return 0;
}
void moveBall(struct Ball* pBall,struct Board* pBoard) 
{if (pBall->x - pBall->r <= 0 || pBall->x + pBall->r >= 800) {pBall->dx = -pBall->dx;}if (pBall->y - pBall->r <= 0 || hitBoard(pBall,pBoard)|| hitBricks(pBall)){pBall->dy = -pBall->dy;}pBall->x += pBall->dx;pBall->y += pBall->dy;
}
//4.收尾工作 :游戏结束
//5.定时器
int Timer(time_t num, int id) 
{static time_t start[10];time_t end = clock();if (end - start[id]>num) {start[id] = end;return 1;}return 0;
}
int gameOver() 
{for (int i = 0; i < 5; i++) {for (int j = 0; j < 8; j++) {if (map[i][j] != 0) {return 0;}}}return 1;
}
int main() 
{srand((unsigned int)time(0));			//设置随机数的范围跟随时间改变而改变hwnd=initgraph(800, 800);struct Board* pBoard = createBoard(300, 800 - 25,5, WHITE, 200, 25);struct Ball* pBall = createBall(400, 600, 15, 5, -5, RED);initMap();BeginBatchDraw();while (1) {cleardevice();drawMap();drawBoard(pBoard);drawBall(pBall);if(Timer(10,0))moveBall(pBall,pBoard);keyDown(pBoard);if (die(pBall)) {MessageBox(hwnd, "you die", "gameOver", MB_OK);exit(0);}if (gameOver()) {MessageBox(hwnd, "win game", "gameOver", MB_OK);exit(0);}FlushBatchDraw();}EndBatchDraw();closegraph();return 0;
}

离开雅达利之后,乔布斯便和沃兹尼亚克创办了苹果电脑公司(后来改名为苹果公司)。

雅达利游戏的简洁性和用户友好性影响着日后苹果的产品设计,而布什内尔本人的性格也深深地影响了乔布斯。

布什内尔强势的态度、享乐主义的精神潜移默化塑造了乔布斯的性格,而乔布斯的「现实扭曲力场」也被认为是受到了布什内尔的影响。「我告诉他,装得好像你掌控了一切,别人就会以为你真的掌控了一切。」

虽然后来的雅达利命运多舛,但那些离开雅达利公司的人将其「在享乐中赚钱」的企业文化继续发扬光大。

「雅达利就是硅谷文化的源头。」

2022年初雅达利50周年,还在这部打砖块的新作品中还加入了双人模式、无休止的街机模式、五十个挑战级别,轨道炮、导弹和炸药等等,全新的元素。游戏整个的赛博朋克画风也非常抓人眼球。

参见:

雅达利庆祝成立 50 周年,推出历史游戏 100+款合集_腾讯新闻

AI 3.0 (豆瓣)

25 Best Atari 2600 Games From The Golden Age Of Gaming

Google DeepMind

Motherboard Graphics by Ron Reuter

Breakout – Atari®

Breakout (Atari 2600) online game | AtariOnline.org

Atari 2600 Breakout Benchmark (Atari Games) | Papers With Code

STEVE JOBS' 'DIGITAL HUB STRATEGY

Atari Games | Papers With Code

https://arxiv.org/pdf/1312.5602v1.pdf

相关文章:

学会玩游戏,智能究竟从何而来?

最近在读梅拉妮米歇尔《AI 3.0》第三部分第九章&#xff0c;谈到学会玩游戏&#xff0c;智能究竟从何而来&#xff1f; 作者: [美] 梅拉妮米歇尔 出版社: 四川科学技术出版社湛庐 原作名: Artificial Intelligence: A Guide for Thinking Humans 译者: 王飞跃 / 李玉珂 / 王晓…...

Unity 常用操作

2D素材网站 https://craftpix.net/ https://itch.io/game-assets/tag-2d/tag-backgrounds 3D素材资源网址 https://www.mixamo.com/#/ 场景常用操作&#xff1a; 快捷键&#xff1a;QWER Q&#xff1a;Q键或鼠标中键&#xff0c;可以拉动场景。 W&#xff1a;选中物体后&…...

【计算机网络_应用层】协议定制序列化反序列化

文章目录 1. TCP协议的通信流程2. 应用层协议定制3. 通过“网络计算器”的实现来实现应用层协议定制和序列化3.1 protocol3.2 序列化和反序列化3.2.1 手写序列化和反序列化3.2.2 使用Json库 3.3 数据包读取3.4 服务端设计3.5 最后的源代码和运行结果 1. TCP协议的通信流程 在之…...

Doris实战——银联商务实时数仓构建

目录 前言 一、应用场景 二、OLAP选型 三、实时数仓构建 四、实时数仓体系的建设与实践 4.1 数仓分层的合理规划 4.2 分桶分区策略的合理设置 4.3 多源数据迁移方案 4.4 全量与增量数据的同步 4.5 离线数据加工任务迁移 五、金融级数仓稳定性最佳实践 5.1 多租户资…...

代码随想录算法训练营第七天

● 自己看到题目的第一想法 第454题.四数相加II 方法&#xff1a; 方法一&#xff1a; 暴力法 思路&#xff1a; 注意&#xff1a; 代码&#xff1a; class Solution { public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<i…...

文件操作和IO(2):Java中操作文件

目录 一、File的属性 二、File的构造方法 三、File的方法 四、代码示例 1、getName&#xff0c;getParent&#xff0c;getPath方法 2、getAbsolutePath&#xff0c;getCanonicalPath方法 3、exists&#xff0c;isDirectory&#xff0c;createNewFile方法 4、createNewF…...

人工智能-零基础

机缘 扩充下知识栈&#xff0c;准备零基础开始 人工智能零基础 日常 日常水一下博客… 憧憬 努力成为一个会人工智能的程序员...

网络爬虫部分应掌握的重要知识点

目录 一、预备知识1、Web基本工作原理2、网络爬虫的Robots协议 二、爬取网页1、请求服务器并获取网页2、查看服务器端响应的状态码3、输出网页内容 三、使用BeautifulSoup定位网页元素1、首先需要导入BeautifulSoup库2、使用find/find_all函数查找所需的标签元素 四、获取元素的…...

git命令笔记

文章目录 0、参考文档1、常用指令git checkout系列git pull系列git push系列git reset系列git branch系列git log系列git revert 撤销某次提交git diff其他 2、查看和修改用户名和邮箱&#xff0c;生成密钥other 0、参考文档 Git使用教程&#xff1a;最详细、最傻瓜、最浅显、…...

微服务day03-Nacos配置管理与Nacos集群搭建

一.Nacos配置管理 Nacos不仅可以作为注册中心&#xff0c;可以进行配置管理 1.1 统一配置管理 统一配置管理可以实现配置的热更新&#xff08;即不用重启当服务发生变更时也可以直接更新&#xff09; dataId格式&#xff1a;服务名-环境名.yaml&#xff0c;分组一般使用默认…...

DFS剪枝

剪枝 将搜索过程中一些不必要的部分剔除掉&#xff0c;因为搜索过程构成了一棵树&#xff0c;剔除不必要的部分&#xff0c;就像是在树上将树枝剪掉&#xff0c;故名剪枝。 剪枝是回溯法中的一种重要优化手段&#xff0c;方法往往先写一个暴力搜索&#xff0c;然后找到某些特…...

基于SpringBoot多模块项目引入其他模块时@Autowired无法注入

基于SpringBoot多模块项目引入其他模块时Autowired无法注入 一、问题描述1、解决方案 一、问题描述 启动Spring Boot项目时报 Could not autowire. No beans of ‘xxxxxxxx’ type found. 没有找到bean的实例&#xff0c;即spring没有实例化对象&#xff0c;也就无法根据配置文…...

每日一题——LeetCode1566.重复至少K次且长度为M的模式

方法一 暴力枚举 var containsPattern function(arr, m, k) {const n arr.length;for (let l 0; l < n - m * k; l) {let offset;for (offset 0; offset < m * k; offset) {if (arr[l offset] ! arr[l offset % m]) {break;}}if (offset m * k) {return true;}}r…...

代码随想录刷题笔记-Day27

1. 全排列 46. 全排列https://leetcode.cn/problems/permutations/ 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],…...

【小沐学GIS】QGIS安装和入门使用

文章目录 1、简介2、下载和安装3、使用3.1 XYZ Tiles3.2 WMS / WMTS3.3 GeoJson文件加载 4、在线资源结语 1、简介 QGIS是一款开源地理信息系统。该项目于2002年5月诞生&#xff0c;同年6月作为SourceForge上的一个项目建立。QGIS目前运行在大多数Unix平台、Windows和macOS上。…...

黑马程序员——接口测试——day03——Postman断言、关联、参数化

目录&#xff1a; Potman断言 Postman断言简介Postman常用断言 断言响应状态码断言包含某字符串断言JSON数据Postman断言工作原理Postman关联 简介实现步骤核心代码创建环境案例1案例2Postman参数化 简介数据文件简介编写数据文件 CSV文件JSON文件导入数据文件到postman读取数…...

Unreal触屏和鼠标控制旋转冲突问题

Unreal触屏和鼠标控制旋转冲突问题 鼠标控制摄像机旋转添加Input轴计算旋转角度通过轴事件控制旋转 问题和原因问题原因 解决办法增加触摸控制旋转代码触屏操作下屏蔽鼠标轴响应事件 鼠标控制摄像机旋转 通过Mouse X和Mouse Y控制摄像机旋转。 添加Input轴 计算旋转角度 通过…...

Vins-Moon配准运行

Vins-Moon运行 求助&#xff01;&#xff01;&#xff01;源码地址电脑配置环境配置编译Kitti数据集制作IMU时间戳问题 适配Kitti数据集运行结果Euroc数据集kitti数据集 evo评估&#xff08;KITTI数据&#xff09;输出轨迹(tum格式)结果 求助&#xff01;&#xff01;&#xff…...

MSCKF3讲:后端理论推导(上)

MSCKF3讲&#xff1a;后端理论推导&#xff08;上&#xff09; 文章目录 MSCKF3讲&#xff1a;后端理论推导&#xff08;上&#xff09;1 MSCKF中的状态变量① IMU状态:② cam0状态&#xff1a;③ IMU和cam0间状态关系 2 微分方程递推&#xff08;数值解&#xff09;3 IMU状态预…...

群控代理IP搭建教程:打造一流的网络爬虫

目录 前言 一、什么是群控代理IP&#xff1f; 二、搭建群控代理IP的步骤 1. 获取代理IP资源 2. 配置代理IP池 3. 选择代理IP策略 4. 编写代理IP设置代码 5. 异常处理 三、总结 前言 群控代理IP是一种常用于网络爬虫的技术&#xff0c;通过使用多个代理IP实现并发请求…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...