使用PyTorch实现简单的AlphaZero的算法(1):背景和介绍

在本文中,我们将在PyTorch中为Chain Reaction[2]游戏从头开始实现DeepMind的AlphaZero[1]。为了使AlphaZero的学习过程更有效,我们还将使用一个相对较新的改进,称为“Playout Cap Randomization”[3],以及来自[4]的一些其他技术。在训练过程中,将使用并行处理来并行模拟多个游戏,还将通过一些相关的研究论文讨论AlphaZero的未来发展方向。

本文目的不是用AlphaZero构建最好的游戏机器人机器人(因为这需要大量的计算资源),而是构建一个像样的机器人,至少可以击败随机的Agent,以Chain Reaction游戏为例了解AlphaZero是如何工作的。

本节首先解释Chain Reaction游戏是如何工作的。如果你只是想了解AlphaZero的工作原理,请跳过下一节直接转到AlphaZero部分。

Chain Reaction

首先我们从理解Chain Reaction游戏开始,这是一个完美的信息游戏,经过几步之后的游戏对我们来说看起来非常混乱和不可预测。所以我很好奇AlphaZero在这游戏中训练后会有多强大。Chain Reaction可以在许多玩家中进行,但在本文中将局限于两个玩家。

游戏规则

让我们从这个游戏的规则开始。有一个M行N列的棋盘,两名玩家。每个玩家都有一种指定的颜色。出于本文的目的,假设我们有一个红色玩家和一个绿色玩家,红色玩家先走。下图显示了游戏中的一些中间状态。

游戏板(简称黑板)上有M行N列,在上图中,M=N=5。黑板上有M*N = 25个单元格。在游戏开始时,所有的格子都是空的。

这些红色和绿色的圆形物体在游戏中被称为球体。下图显示了我们在游戏中可以拥有的球体(1个,2个或3个,红色或绿色)。

在一次操作中,玩家点击任何空的或颜色或玩家相同的单元格,它将增加该单元格中的球的数量。下面的动图展示了游戏中的一些动作。

在一个特定的单元格中可以容纳多少个球是有限制的。一个单元格最多可以保存“该单元格的正交相邻邻居数-1”。对于中间的单元格,这个数字是3,对于边缘的单元格,这个数字是2,对于角落的单元格,这个数字是1。下图显示了5x5板中每个单元的最大球体数。

但当玩家点击一个已经拥有最多球体数量的单元格时会发生什么呢?那个单元格的球会分裂,把它所有的球推到邻近的单元格里。下面的动图显示了不同种类的球体的分割。

在分裂过程中,如果相邻单元格包含来自其他玩家的球,那么这些球的颜色将改变为当前玩家的颜色。如下图所示。

分裂后的单元格在其周围增加了球的数量,它可以导致进一步的多次分裂,开始分裂的连锁反应,这就是游戏名字的由来。单步操作后的连锁反应是这款游戏最终不可预测的原因。

现在我们知道了游戏是如何从一个状态发展到下一个状态的,可能会有分裂;或者在单个单元格中增加一个球体。但玩家如何获胜呢?游戏的目标很简单,玩家必须消灭棋盘上所有敌人的球。

游戏状态

我们需要存储什么信息来捕捉游戏的状态呢?有两样东西——首先,一个M × N数组,它告诉我们棋盘上每个M*N格子中的球的数量和类型,其次,轮到谁“红”或“绿”。我们可以用正数来表示红色球的数量,用负数来表示绿色球的数量。下图显示了如何表示状态的示例。

状态转换

我们知道了如何表示一个状态,下面要关注一个更重要的问题,在当前状态下,如何得到下一个状态。为了获得下一个状态,需要知道玩家点击的单元格。我们称这个单元格为事件单元格。

将在事件单元格上做一些处理,它看起来像这样。我们将向它添加一个球体,并检查球体的数量是否超过单元格的限制。如果球的数量超过了,我们就需要把球分裂开。

在分裂的情况下,事件单元格的每个邻居都将获得一个球体,然后我们将处理这些邻居,依此类推。我们观察到,我们首先处理事件单元格,然后处理事件单元格的邻居,然后处理事件单元格邻居的邻居,依此类推。在某个级别i的邻居,可以以任何顺序处理;以任何顺序处理第I级上所有邻居的最终结果都是相同的。下图就是一个例子。

两种不同的方式处理同一级别的单元格都会得到相同的最终状态。第i层的处理顺序不重要的原因是,第i层有两种单元格,分裂的单元格和没有分裂的单元格。那些没有分裂的单元格的球数只会增加一个,不管处理顺序如何。那些分裂的单元格,只会给i+1级的单元格增加一个球体。也就是说,第i级和第i+1级的单元格集合总是不相交的,因此第i级所有单元格的相加之和对于第i+1级的每个单元格总是相同的。

所以本质上是在做广度优先遍历,这可以借助队列来实现状态转换。

实现简单的游戏规则

状态

实现状态表示并不复杂。将棋盘信息存储为不同numpy数组中的球的数量和球的颜色。状态表示还包括玩家的回合。

可视化

这些代码,分别使用矩形和圆绘制网格和球体。

控制器

这里是最重要的代码段,即状态转换,即在给定当前状态和事件的情况下获得下一个状态。

有一种情况是,球持续分裂,而其他玩家的球消失,如下图所示。

这里需要检查玩家是否在广度第一次遍历while循环中赢得了游戏。通过跟踪红色和绿色的球体计数(作为myorbs和opporbs)来检查它,并在循环的每次迭代中更新它们。

AlphaZero

AlphaZero到做了什么呢

[5]是理解AlphaZero的一个很好的起点。人类的推理有两种思维模式——一种是慢思维模式,一种是快思维模式。快速模式由直觉引导,而慢速模式像传统计算机算法一样明确遵循某些规则或步骤引导。

在AlphaZero中,快速模式或直觉都是通过一个神经网络实现的,该神经网络获取棋盘状态并输出一个策略(操作的概率分布)和一个值(告诉当前玩家给定棋盘状态有多好的分数);慢速思维模式则通过蒙特卡罗树搜索实现。

对于一个游戏我们可能会有一些自己的理解(经验),知道哪些行为更好,哪些不好。这种最初的理解可以表示为行为的概率分布。我们会将较高的概率分配给好的行动,而较低的概率分配给坏的行动(好的行动是那些能够带给我们胜利的行动)。如果我们没有这样的经验,那么我们可以从均匀概率分布开始。

这个操作上的概率分布就是我们对于给定状态的“策略”。

有一种方法可以改进这一原始政策——提前考虑未来可能采取的行动。从我们当前的状态出发,我们可以思考自己可以下什么棋,对手可以下什么棋等等。这种情况下我们实际上是在讨论树搜索,这种树搜索可以通过使用我们最初的理解来评估中间板的状态(获取值)来改进,并且可能不会花费大量的时间来探索具有低值的节点。在完成这个树搜索之后,将更好地了解在当前棋盘状态下玩什么,或者说我们得到了一个改进的策略。这整个过程被称为放大,这是AlphaZero使用蒙特卡洛树搜索完成的。

下一篇文章我们将详细介绍AlphaZero的一个简单实现。

References

[1] Silver, D., Hubert, T., Schrittwieser, J., Antonoglou, I., Lai, M., Guez, A., Lanctot, M., Sifre, L., Kumaran, D., Graepel, T., Lillicrap, T., Simonyan, K., & Hassabis, D. (2018). A general reinforcement learning algorithm that Masters Chess, Shogi, and go through self-play. Science, 362(6419), 1140–1144. https://doi.org/10.1126/science.aar6404

[2] https://brilliant.org/wiki/chain-reaction-game/

[3] Wu, D. J. [PDF] accelerating self-play learning in go: Semantic scholar. https://www.semanticscholar.org/paper/Accelerating-Self-Play-Learning-in-Go-Wu/f244ffb549a61806d00f614e70fa1c3fbe5fffc6

[4] https://medium.com/oracledevs/lessons-from-implementing-alphazero-7e36e9054191

[5] “How to Keep Improving When You’re Better Than Any Teacher — Iterated Distillation and Amplification.” YouTube, uploaded by Robert Miles, 3 Nov. 2019, https://www.youtube.com/watch?v=v9M2Ho9I9Qo.

[6] Anthony, T., Barber, D., & Tia, Z. Thinking fast and slow with deep learning and Tree Search. https://arxiv.org/pdf/1705.08439.pdf

作者:Bentou

本文转载于网络 如有侵权请联系删除

相关文章

  • React报错之组件不能作为JSX组件使用

    原文链接:https://bobbyhadz.com/blog/react-cannot-be-used-as-a-jsx-component[1]作者:BorislavHadzhiev[2]正文从这开始~总览组件不能作为JSX组件使用,出现该错误有多个原因:返回JSX元素数组,而不是单个元素。从组件中返回JSX元素或者null以外的任何值。使用过时的React类型声明。返回单个JSX元素下面是一个错误如何发生的示例。//App.tsx //⛔️'App'cannotbeusedasaJSXcomponent. //Itsreturntype'Element[]'isnotavalidJSXelement. //Type'Element[]'ismissingthefollowingpropertiesfromtype'ReactElement<any,any>':type,props,key constApp=()=>{ return['a','b

  • macOS 下配置 OpenGL

    Moreinfoin从零开始的WebGL.Resource书籍计算机图形学(第四版)交互式计算机图形学基于OpenGL的自顶向下方法(第六版)OnlineLearnOpenGLCNopengl-tutorialProgressmacOSCLion:Across-platformIDEforCandC++gladbrewinstallglfw复制下载glad,macOS据说只支持3.3,所以我选择了gl:3.3和Profile:Core。 解压后将glad文件夹直接放入/usr/local/Cellar文件夹下。可以直接用命令copy或者,cd到文件夹下输入open.用finder打开文件夹。CLion新建C++相关默认项目,修改默认项目中的CMakeLists.txt即可。#CMakeLists.txt cmake_minimum_required(VERSION3.14) set(PROJECT_NAME"testOpenGL") project(${PROJECT_NAME}) set(CMAKE_CXX_STANDARD14) set(GLFW_H/usr

  • java-JDBC操作Mysql

    一、下载mysql驱动 http://central.maven.org/maven2/mysql/mysql-connector-java/packagetestJdbc; importjava.sql.Connection; importjava.sql.DriverManager; importjava.sql.ResultSet; importjava.sql.SQLException; importjava.sql.Statement; publicclasstest2{ publicstaticvoidmain(String[]args)throwsSQLException,ClassNotFoundException{ //1、加载驱动器 StringJDBCDriver="com.mysql.jdbc.Driver"; Class.forName(JDBCDriver); //2、连接数据库 Stringurl="jdbc:mysql://127.0.0.1:3306/school";//链接数据的

  • Spring Security 实战干货:图解Spring Security的过滤器体系

    1.前言我在SpringSecurity实战干货:内置Filter全解析对SpringSecurity的内置过滤器进行罗列,但是SpringSecurity真正的过滤器体系才是我们了解它是如何进行"认证"、“授权”、“防止利用漏洞”的关键。2.ServletFilter体系这里我们以ServletWeb为讨论目标,ReactiveWeb暂不讨论。我们先来看下最基础的Servlet体系,在Servlet体系中客户端发起一个请求过程是经过0到N个Filter然后交给Servlet处理。servlet过滤器链Filter不但可以修改HttpServletRequest和HttpServletResponse,可以让我们在请求响应的前后做一些事情,甚至可以终止过滤器链FilterChain的传递。publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain){ //请求被servlet处理前 if(condition){ //根据条件来进入下一个过滤器 chain.doFi

  • 【精华】洞悉MySQL底层架构:游走在缓冲与磁盘之间

    提起MySQL,其实网上已经有一大把教程了,为什么我还要写这篇文章呢,大概是因为网上很多网站都是比较零散,而且描述不够直观,不能对MySQL相关知识有一个系统的学习,导致不能形成知识体系。为此我撰写了这篇文章,试图让这些底层架构相关知识更加直观易懂:尽量以图文的方式描述技术原理;涉及到关键的技术,附加官网或者技术书籍来源,方便大家进一步扩展学习;涉及到的背景知识尽可能做一个交代,比如讨论到logbuffer的刷盘方式,延伸一下IO写磁盘相关知识点。好了,MySQL从不会到精通系列马上就要开始了(看完之后还是不会的话..请忽略这句话)。可能会有同学问:为啥不直接学更加先进的TiDB,或者是强大的OceanBase。其实,MySQL作为老牌的应用场景广泛的关系型开源数据库,其底层架构是很值得我们学习的,吸收其设计精华,那么我们在平时的方案设计工作中也可以借鉴,如果项目中用的是MySQL,那么就能够把数据库用的更好了,了解了MySQL底层的执行原理,对于调优工作也是有莫大帮助的。本文我重点讲述MySQL底层架构,涉及到:内存结构:bufferpool、logbuffer、changebuff

  • 【二进制安全】熊猫烧香病毒分析

    熊猫烧香这个病毒虽然过去很久了,但是这个病毒值得研究,在病毒出现的这个年代因为安全意识普遍不强,导致大范围被感染。本文带你跨进计算机病毒的大门0x00工具查壳:PEID、ExeInfoPE 动态分析:OllyDbg 静态反汇编分析:IDAPro 行为监控:ProcessMonitorPCHunter、火绒剑 资源查看:ResourceHacker PE解析:LoadPE 文本编辑:HexWrokShop 环境:win7虚拟机复制 0x01查壳我们用PEiD进行查壳,发现这个程序并没有加壳 0x02行为分析使用ProcessMonitor来进行行为检测:1.查看进程树可知panda.exe在C:\Windows\System32\drivers\下释放了spcolsv.exe文件,并创建了子进程2.spcolsv.exe使用cmd命令删除了系统磁盘的一些共享操作3.通过筛选Operation,也可以发现恶意软件在C:\Windows\System32\drivers\下释放了spcolsv.exe文件4.换对spcolsv.exe进行行为监控,发现其在注册表的自启动项设置了svcshar

  • python Exception(异常处

    python异常:   python在运行时错误称为异常     语法错误:软件的结构上有错误而导致不能被解释器解释或不能被编译器编译。     逻辑错误:由于不完整或不合法的输入所致,也可能是逻辑无法生成、计算或者出结果需要的过程无法执行等。   默认情况下:python脚本执行过程中出现异常后,脚本执行将被终止。   python异常是一个对象,表示错误或意外的情况   在python检测到一个错误时,将触发一个异常:     python可以通过异常传导机制传递一个异常对象,发出一个异常情况出现的信号。     程序员也可以在代码中托运触发异常   python异常也可以理解为:程序出现了错误,而在正常控制流以外采取的行为     第一阶段:解释器触发异常,此时当前程序流将被打断。     第二阶段:异常处理,如忽略非致命错误、减轻错误带来的影响等。 异常的功用   错误处理:     python的默认处理:停止程序,打印错误消息     使用try语句处理异常,并从异常中恢复   事件通知:     用于发出有效状态信号   特殊情况处理:     无法调整代码去处理的场

  • 在快速迭代的项目中减少测试返工

    概述  在互联网产品中,产品的迭代速度越来越快,项目中的测试同学面临着前期需求摇摆不定,中间各种开发进度死锁,而发布时间却无法推迟。项目的前期阶段似乎总是在压榨着测试的执行时间。如何减少测试返工,测试阶段的工作量的同时,保障项目质量?立项后  项目目标要明确,最好有量化指标。  产品需求是否为项目目标服务?有些项目,目标定的很好,但是需求列表,经不住推敲,与项目目标弱关联甚至没有关联。乃至于很多需求都是基于假设,但这种假设却经不起推敲。我们测试人员可以在项目前期,果断的拒绝这类项目,或砍掉部分不现实的需求。减少项目后期的需求变更。这样做,还可以减少上线后不必要的修复、缩减N次迭代,避免扯皮。需求分析阶段  需求一定要有优先级和重要程度。对于尝试性的需求,在保障质量的同时,尽量减少投入工作量。对核心功能,优先保障自动化覆盖。无论是在本次项目中,还是后续版本的迭代中需要不断的进行重复测试,保障最核心功能的质量。测试人在需求分析阶段尽可能细的拆分需求,通过场景法及各种异常分支流,验证产品的功能是否完善,提前发现问题。  在这个阶段,测试需要发挥自己的逻辑性思维优势,帮助产品经理和开发们理清细

  • 世界杯直播技术揭秘及视频云直播回源系统的应用

    背景近些年,视频直播应用蓬勃发展,带宽也是日渐新高,腾讯云旗下的视频云直播为斗鱼、快手、虎牙、龙珠、CNTV广大的企业客户提供了很大的支持,在行业内起到了引领的作用。视频云直播中,常见的流程是,客户侧应用推流到视频云上行接入服务,另一种情形是客户侧提供直播流源,视频云进行回源拉流,并最终通过CDN分发而这里针对第二种情形,介绍直播源站系统(又称三级源)的功能和设计,三级源的核心功能即从客户源站获取直播流,并最终交由CDN分发出去。架构介绍我们主要完成了直播常见协议,rtmp、flv、hls的回源和转封装,同时还针对特定客户做了私有协议的分发。也可以支持多种协议的推流和转推。系统内部架构如下,source_server负责从上一层获取数据,并给下一层提供拉取的功能,master负责调度工作。另外还有配置服务,预热服务等。那么设计一个这样的三级源需要注意哪些呢,首先客户关心的最重要的是服务的稳定性,其次对于直播来说播放质量也很重要,其次功能和价格也是要考虑的。那么对应到我们的设计标准就是,可用性,质量,功能和成本可用性首先,在调度策略上,具备负载均衡和过载保护的基本功能。通过一致性hash

  • 解密无人机飞手的高薪:什么样的才算合格?

    “我每天起床的第一件事就是查看是否获批飞行空域,如获批以后立刻进行飞行器安全检查。确认一切正常,进行空军飞前通报,获准后无人机上天。”天眼通航拍创始人、资深民用无人机持牌飞手刘士清饶有兴致地和记者讲述着他一天的工作流程。提到无人机,人们并不陌生,无人机飞手作为一项职业,也越来越多的得到人们的关注。近日,互联网研究机构艾瑞咨询发布了《2016年中国无人机行业研究报告》,称我国小型民用无人机市场进入快速成长期,预计到2025年,国内小型民用无人机市场总规模将达到750亿元。刘士清作为入行5年的资深飞手,在谈到行业现状时也表示:“无人机持牌飞手目前确实比较紧缺,截至2016年6月,国内无人机持牌飞手不到6000人,而市场对于这方面人才的需求至少是10万级别。并且无人机的应用范围也在不断扩大。”职业:高收益与高风险并存提到行业的薪资水平,刘士清微微一笑,指着咖啡厅外来回穿梭的车流说到:“无人机飞手好比汽车驾驶员,首先得有驾驶证,有了证以后,老司机一般比新手赚的多,懂得修车的老司机比普通老司机赚的多。”“无人机也是一样,仅仅会飞,每个月的薪水也就几千元。经验丰富的飞手,情况就各不相同了。有些资深

  • 【强烈推荐】:关于系统学习数据挖掘(Data Mining)的一些建议!!

    关键字全网搜索最新排名【机器学习算法】:排名第一【机器学习】:排名第一【Python】:排名第三【算法】:排名第四关于数据挖掘提到收据挖掘(DataMining,DM),很多想学习的同学大多数都会问我:什么是数据挖掘?怎么培养数据分析的能力?如何成为一名数据科学家?(简称数据挖掘工程师为DMer)我认为,在学习DM之前你至少需要明白以下几点:数据初期的准备通常占整个数据挖掘项目工作量的70%左右;数据挖掘本身融合了统计学、数据库和机器学习等学科,并不是新的技术;数据挖掘技术更适合业务人员学习(相比技术人员学习业务来的更高效);数据挖掘适用于传统的BI(BusinessIntelligence)无法支持的领域。国内DMer的工作领域1)数据分析师:在拥有行业数据的电商、金融、电信、咨询等行业里做业务咨询,商务智能,出分析报告。2)数据挖掘工程师:在多媒体、电商、搜索、社交等大数据相关行业里做机器学习算法实现和分析。3)科学研究:在高校、科研单位、企业研究院等高大上科研机构研究新算法效率改进及未来应用。各领域DMer需要掌握的技能数据分析师需要的技能如下:需要有深厚的数理统计基础,但是对程

  • 算法分析与设计(final)

    1、问题 设有\(n\)项任务,加工时间分别表示为正整数\(t_{1},t_{2},...,t_{n}\).现有2台同样的机器,从\(0\)时刻开始安排对这些任务的加工。规定只要有待加工的任务,任何机器就不得闲置。如果直到时刻\(T\)所有任务都完成了,总加工时间就等于\(T\)。设计一个算法找到使得总加工时间T达到最小的调度方案。 2、解析 观察所给问题,发现只要有代加工的任务,任何机器都不得空闲,那么即从\(0\)时刻开始,机器不停在运转,设两台机器的加工时间为\(T_{1},T_{2}\),有一下两个约束条件:1、\(T=max(T_{1},T_{2})\),2、\(T_{1}+T_{2}=\sum^{n}_{i=1}t_{i}\)。 那么显然问题就可以转化为把\(t_{1},t_{2},...,t_{n}\)划分成两部分,一部分之和为\(T_{1}\),另一部分之和为\(T_{2}\),使得\(max(T_{1},T_{2})\)最小。 因为\(\sum^{n}_{i=1}t_{i}\)是固定的,所以条件\(max(T_{1},T_{2})\)最小等同于\(ab

  • 【Android】九宫格的实现

    第一步,布局文件 <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".JokeTabHostActivity" android:orientation="vertical" > <GridView android:id="@+id/GridView" android:listSelector="@android:color/transparent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:columnWidth="90dp" android:gravity="center" android

  • Codeforces Round #723 (Div. 2)C1+C2. Potions(dp/贪心)

    传送门 题目大意:n瓶药水,从左到右开始喝,喝完一瓶健康值+a[i],(a[i]有可能是负数),要保证每喝完一瓶药水后健康值不能为负数。 问最多喝几瓶。 题解: 解法一:DPO(n^2) dp[i][j]表示前i瓶药水喝j瓶的最大健康值,则转移方程为dp[i][j]=max(dp[i-1][j-1]+a[i],dp[i-1][j])。 若dp[i][j]为负数,给它赋值一个负无穷,这样后续状态不会从这个状态转移过去。 解法二:贪心 能喝就喝,喝了变成负数了就把之前喝的最小的一瓶吐出来 #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> usingnamespacestd; #defineLLlonglong constLLINF=1e18; intn; LLdp[2020][2020]; inta[2020]; intmain() { scanf("%d",&n); for(inti=1;i<=n;i++) { sc

  • 关于结构体内存对齐方式的总结(#pragma pack()和alignas())

    最近闲来无事,翻阅msdn,在预编译指令中,翻阅到#pragmapack这个预处理指令,这个预处理指令为结构体内存对齐指令,偶然发现还有另外的内存对齐指令aligns(C++11),__declspec(align(#))(Microsoft专用),遂去探究两者之间的不同点。 1、#pragmapack 这个指令为预处理指令,所谓与处理指令执行在程序的预处理阶段,该指令对应着编译选项/Zp,可以在vs的工程属性中设置编译选项的内存对齐,也可以利用预处理指令来设置。 #pragmapack([show]|[push|pop][,identifier],n)  预处理指令的用法如上,其中必选参数n为内存对齐值,有效值为1、4、8、16,默认值为8。可选参数中,show代表右警告消息显示当前的内存对齐值,push|pop二者选其一,代表将当前的内存对齐值入、出栈。identifier跟随push|pop一同出入栈,作为表示使用。 2、aligns、__declspec(align(#)) aligns和alignof为c++标准的类型说明和运算符,其中aligns为内存对齐类型符,

  • ASP.NET Core 一步步搭建个人网站(3)_菜单管理

    上一章,我们实现了用户的注册和登录,登录之后展示的是我们的主页,页面的左侧是多级的导航菜单,定位并展示用户需要访问的不同页面。目前导航菜单是写死的,考虑以后菜单管理的便捷性,我们这节实现下可视化配置菜单的功能,这样以后我们可以动态的配置导航菜单,不用再编译发布网站程序了。 增加后台管理模块 第1步,左侧导航菜单中,添加后台管理模块,用作管理员登录后,可以进行一些后台管理的操作,当然,目前还没有权限控制(后期加入),所以对所有用户可见。大概菜单结构如下: 有了菜单项,我们还需要控制视图的跳转,所以,接下来需要写对应的控制器和视图。 为了将相关功能组织成一组单独命名空间(路由)和文件夹结构(视图),解决方案中右键添加区域(Area),取名后台管理(Configuration),代表后台管理模块,.NetCore脚手架(scaffold)自动帮我们实现了目录划分:控制器(Controllers)、模型(Models)、视图(Views) 菜单模型定义 菜单的基本属性有:菜单名称、菜单类型、菜单的图标样式、菜单url路径。另外,菜单在逻辑上是树状结构,但是要在物理数据库中存储,需要进行扁平化

  • gRPC流模式的实现和TLS加密通信[Go和asp.net core 5.0]

    gRPC主要有4种请求和响应模式,分别是简单模式(SimpleRPC)、服务端流式(Server-sidestreamingRPC)、客户端流式(Client-sidestreamingRPC)、和双向流式(BidirectionalstreamingRPC)。 1.简单模式(SimpleRPC):客户端发起请求并等待服务端响应。 2.服务端流式(Server-sidestreamingRPC):客户端发送请求到服务器,拿到一个流去读取返回的消息序列。客户端读取返回的流,直到里面没有任何消息。场景:.客户端要获取某原油股的实时走势,客户端发送一个请求, 服务端实时返回该股票的走势 3.客户端流式(Client-sidestreamingRPC):与服务端数据流模式相反,这次是客户端源源不断的向服务端发送数据流,而在发送结束后,由服务端返回一个响应。情景模拟:客户端大量数据上传到服务端 4.双向流式(BidirectionalstreamingRPC):双方使用读写流去发送一个消息序列,两个流独立操作,双方可以同时发送和同时接收。 情景模拟:双方对话(可以一问一答、一

  • window Appserv 2.5.10 php版本升级 由5.2.6版本升级到php-5.3.27-Win32-VC9-x86版本

    随着php版本的不断更新新版本功能越来越先进, 以及旧版本中那些重复功能的函数进行瘦身,精简. 所以现在很多开源的php项目都在升级php的新版本. Appserv2.5.10软件是我很喜欢的一个windows下快速搭建php开发环境的软件. 只是苦于他的php版本实在太低,而作者也直接从php5.2.6升级软件到6.0,7.0... 我们实在跟不上他的步伐所以才有了自己手动去升级php的版本而不改变其他的apache和mysql配置. 以下就是升级步骤   1.php.ini將;extension=php_pdo.dll註解起來。2.php-5.3.27-Win32-VC9-x86下载解压 取代原php5資料夾中的檔案3.無法連線資料庫之處理:(使用MySQL管理工具,執行以下語法) SETold_passwords=0; UPDATEmysql.userSETPassword=PASSWORD('資料庫管理者密碼')WHEREUser='root'; SELECTLENGTH(Password)FROMmysql.userWHEREUser='root';

  • BZOJ 4652 [Noi2016]循环之美

    题目链接 https://lydsy.com/JudgeOnline/problem.php?id=4652 题解 容易发现,若ij\frac{i}{j}ji​在kkk进制下为纯循环小数,那么必定有 ikl=imod&ThinSpace;&ThinSpace;jkl=1mod&ThinSpace;&ThinSpace;j ik^l=i\mod{j}\\ k^l=1\mod{j} ikl=imodjkl=1modj 因此gcd⁡(j,k)=1\gcd(j,k)=1gcd(j,k)=1。 那么题目要求的就是 F(n,m,k)=∑i=1n∑j=1m[gcd⁡(i,j)=1][gcd⁡(j,k)=1] F(n,m,k)=\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=1][\gcd(j,k)=1] F(n,m,k)=i=1∑n​j=1∑m​[gcd(i,j)=1][gcd(j,k)=1] 反演得到 F(n,m,k)=∑d∣kF(md,n,d) F(n,m,k)=\sum_{d|k}F(\frac{m}{d},n,d) F(n

  • autohotkey typora 快捷键

    C:\my_script\typora\typora-副本.ahk ;热键标记 ;!感叹号代表Alt键 ;#井号代表Windows键 ;^上三角号代表Ctrl键 ;+加号代表Shift键 ;执行 ;::代表按下前面快捷键后会执行后面的命令。 ;Typora ;快捷增加字体颜色 ;SendInput{Text}解决中文输入法问题 #IfWinActiveahk_exeTypora.exe { ;alt+0红色 ;!0::addFontColor("black") ;alt+1红色 !1::addFontColor("#ef7a82") ;alt+1橙色 !2::addFontColor("#ffa631") ;alt+3绿色 !3::addFontColor("#9ed900") ;alt+4紫色 !4::addFontColor("#cca4e3") ;alt+5蓝灰色 !5::addFontColor("#a1afc9") ;alt+6紫色 ;!6::addFontColor("purple") ;alt+7黄色 ;!7::addFontColor("yellow"

  • 第三章:web安全基础-IIS发布所遇问题的解决办法

    问题一、虚拟机的联网       ①桥接模式:与主机共用一个物理网卡,主机插着网线,手动配置IP,Netmask,网关,DNS,虚拟机也需要如此配置,还得跟主机同一个网段,但是不是一个网络号,还不能和这个网段其他主机冲突。 ②NAT模式:选择NAT模式,在虚拟机更改适配器设置里设置成自动获取,就可以上网了,有时候没分配好,就把本地连接禁用一下再开启一下。(VMware的dhcp服务会自动给虚拟机分配ip的,分配的ip和主机的ip不在一个网段,用的是NAT转换,虚拟机要上网,虚拟机的ip通过NAT转换为主机ip再去上网)。原理同家里一个路由器可以让手机电脑都上网)   PS:在计算器网络中,网络地址转换(NetworkAddressTranslation,缩写为NAT),也叫做网络掩蔽或者IP掩蔽(IPmasquerading),是一种在IP数据包通过路由器或防火墙时重写来源IP地址或目的 IP地址的技术。这种技术被普遍使用在有多台主机但只通过一个公有IP地址访问因特网的私有网络中。它是一个方便且得到了广泛应用的技术。当然,NAT也让主机之间的通信变得复杂,

相关推荐

推荐阅读