累积分布函数与概率密度函数的区别

本文简要介绍统计学中PDF (probability density function) 和 CDF (cumulative distribution function) 之间的差异。 随机变量 再讨论PDF 和 CDF之前,我们首先需要理解随机变量。 随机变量通常用x表示,表示一些随机过程中产生的数值类型结果,分为两类:离散和连续。 离散随机变量 离散随机变量(discrete random variable) 仅能够表示可数的离散值,如1,2,100,1000等。 离散随机变量的示例包括: 抛20次硬币,正面朝上的次数扔骰子100次,其中为4点的次数 连续随机变量 连续随机变量(continuous random variable)有无数取值可能,举例: 身高体重跑3公里所需时间 身高为170cm,170.01,169.98 等等,身高值有无限可能的值。 经验法则:如果你能够数出结果的个数,则为离散随机变量(例如,计算硬币正面落地的次数)。但如果你能够测量结果,则为连续的随机变量(例如测量,身高,体重,时间等)。 概率密度函数(Probability Density Functions) 概率密度函数(pdf)随机变量取某个值的概率。举例扔骰子,用x表示获得的点数,那么PDF可以描述结果的分布情况: P(x < 1) : 0 P(x = 1) : 1/6 P(x = 2) : 1/6 P(x = 3) : 1/6 P(x = 4) : 1/6 P(x = 5) : 1/6 P(x = 6) : 1/6

OpenFOAM一种批量修改参数计算算例的方法

在需要大量修改参数计算算例的时候,脚本能帮我们省下很多功夫。参考一篇知乎文章的做法,并作出改进。现在可以编辑特定的文件名字,而不是用参数来作为文件名了,这样在后期批量后处理的时候会更方便。 直接放脚本: #!/bin/bash list=(Ur1 Ur2 Ur4 Ur5 Ur6 Ur7 Ur8 Ur9) listPara=(1 2 4 5 6 7 8 9) len=${#list[*]} for (( i = 0; i <=len; i++)) { cp -r Ur3 ${list[i]} cd ${list[i]} foamDictionary -entry "caseUr" -set "${listPara[i]}" ./Ur ./Allrun cd .. } list表示文件夹名字列表,listPara表示要修改的参数列表。${#list[*]}表示list的长度。这里以文件夹Ur3为basefile,复制到list里对应名字的文件夹,通过foamDictionary指令修改caseUr对应的参数,然后./Allrun开始计算,最后cd ..返回上一级。 参考 Linux 中数组的使用_少奶奶的猪的博客-CSDN博客_linux 数组 OpenFOAM初学心得(三)——批量操作与并行计算 - 知乎

IDEA Eval Reset 使用方法

安装插件 离线安装方式 1、下载插件 下载地址:https://plugins.zhile.io/files/ide-eval-resetter-2.1.6.zip 2、安装插件 直接下载插件 zip 包(macOS 可能会自动解压,然后把 zip 包丢进回收站) 通常可以直接把 zip 包拖进 IDE 的窗口来进行插件的安装。如果无法拖动安装,你可以在Settings/Preferences... -> Plugins 里手动安装插件(Install Plugin From Disk...) 插件会提示安装成功 在线安装方式 Fiel -> Setting > plugins ​ 添加仓库地址: https://plugins.zhile.io ​ 然后搜索 IDE Eval Reset 安装即可 使用插件 点击Help,选择 Eval Reset (如果没有显示出来,重复以上操作)。 唤出来的插件主界面包含一些显示信息,2个按钮,一个勾选项: ​ 按钮: Reload 用老刷新界面上的显示信息。 ​ 按钮: Reset 点击会询问是否重置使用信息并重启 IDE。 选择Yes 则执行重置操作并重启IDE生效,选择No则什么也不做。(此为手动重置方式) ​ 勾选项:Auto reset before per restart 如果勾选了,则自勾选后每次重启/退出 IDE 时会自动重置使用信息,无需做额外的事情。(此为自动重置方式)。

pytorch 细节 多GPU卡训练 一个可在windows单GPU独立运行的DDP

an vanilla example for DDP on lunix # main.py import torch import torch.distributed as dist import torch.multiprocessing as mp mp.spawn(main_worker, nprocs=4, args=(4, myargs)) def main_worker(proc, nprocs, args): dist.init_process_group(backend='nccl', init_method='tcp://127.0.0.1:23456', world_size=4, rank=gpu) torch.cuda.set_device(args.local_rank) train_dataset = ... train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=..., sampler=train_sampler) model = ... model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank]) optimizer = optim.SGD(model.parameters()) for epoch in range(100): for batch_idx, (data, target) in enumerate(train_loader): images = images.cuda(non_blocking=True) target = target.cuda(non_blocking=True) .

Ansible管理机密

ansible-vault ansible-vault [create|decrypt|edit|encrypt|encrypt_string|rekey|view] [options] [vaultfile.yml] create:创建 edit:编辑 encrypt:加密 decrypt:解密 view:查看 rekey:重新该秘钥 1.创建加密文件 [devops@workstation ansible]$ ansible-vault create file New Vault password: Confirm New Vault password: 内容: username: tom password: 123456 2.查看加密文件 [devops@workstation ansible]$ ansible-vault view file Vault password: username: tom password: 123456 免密码 [devops@workstation ansible]$ echo 123456 > pass [devops@workstation ansible]$ ansible-vault view file --vault-password-file=pass username: tom password: 123456 3.编辑加密文件 [devops@workstation ansible]$ ansible-vault edit file --vault-password-file=pass 4.重置密码 [devops@workstation ansible]$ ansible-vault rekey file Vault password: New Vault password: Confirm New Vault password: Rekey successful 5.

2022年第十三届蓝桥杯JAVA B组 试题C:字符统计

试题 C: 字符统计 时间限制: 1.0s 内存限制: 512.0MB 本题总分:10 分 【问题描述】 给定一个只包含大写字母的字符串 S,请你输出其中出现次数最多的字母。 如果有多个字母均出现了最多次,按字母表顺序依次输出所有这些字母。 【输入格式】 一个只包含大写字母的字符串 S . 【输出格式】 若干个大写字母,代表答案。 【样例输入】 BABBACAC 【样例输出】 AB 【评测用例规模与约定】 对于 100% 的评测用例,1 ≤ |S | ≤ 10的6次方 这里 仅以自己笨拙的方法解一下这道题,对于评测10的6次方不敢保证在时间、空间限制之内。 思路分析 //第1步.存次数 // 可以选择 数组arr 来存大写字母出现的次数 // 1.1 将String -> char[] 然后遍历char[] // 1.2 利用char类型做运算会自动升为int类型 // 即 'B' - 'A' = 66 - 65 =1 // 就可以用 数组 来存大写字母出现的次数 // 即c[0] 存A出现的次数 、c[1] 存B出现的次数 // 第1步做完,可以验证代码

关于服务器并发量的简单计算

最简单的计算方式就是根据服务器带宽与页面的大小 1.假设机房带宽为10Mbs,页面的大小为20KB(包含所有的js、css、图片) 同时并发量的理论值: 10*1024/(8*20) = 64个请求/秒 理论上1秒钟同时可以有64个请求访问页面。 注意:10Mbs是位(b),1个字节8位,所以要除8。 2. 假设进来的人是匀速的增加, 根据”三秒定律”(页面打开速度3秒),可得出并发量在单位时间内应是192个请求; 一分钟的请求量在3840。 3.根据二八定律,即80%的访问量发生在20%的时间里 3840*24*60*0.2/0.8=1382400 人次 而发生在每天的高峰期(大约5小时)内的在线人次在110万人次,一个小时为22W人次。 4.当然以上的计算都是理论值,如每个访问者停留页面的平均时间为1分钟左右,访问者的进入和退出都是比较符合正态分布.。 如果是特殊情况服务器肯定是支撑不了这么多人的,例如同一时间有大批量的访问者进入,例如考试系统。又或者同时刷新页面。 而且在实际过程中,现在的页面都肯定超过20KB,那么对带宽的要求也就更大,还有同一个局域网访问情况也要考虑。 以笔者的实际项目来说,我的项目是考试系统。出现过2次比较极端的情况。 本考试系统,登陆的页面容量比较大,所有的js,css以及图片未优化前在400KB左右,我们就以400KB为基准,所有后面要用的文件是在首页一次性加载下来的。 我用的是2台服务器,均为10Mbs带宽。 按照上面的计算方式可得出 2台服务器单位时间内应可以处理19个请求,一天能承载的测评人次是14W左右,而发生在每天的峰值时间(大约5小时)内在线人次在11W左右。 高峰期一个小时的在线人次在2.2W左右。 第一次我们测评人数是7949人,而这些测评者主要使用的是自己的手机分散测评,测评的时间线如下 高峰期是在11点期间,而从这一个小时的日志中查到与实际的服务器数据库的写入人次是17783人次(测评系统的特点是除了极少的几个页面不参数数据库数据写入,其他都是要写入答案或者个人信息)。这一天的测评情况非常顺利,服务器没有任何压力。 第二次,总共只测了2433人,但其中有1200人左右是在局域网且同时登陆系统,第一次导致其中一台机器几乎卡死,后来查看服务器日志,发现瞬时峰值有150个请求/秒,并且我是将所有的静态资源如 JS\CSS\图片都存放在一台服务器中的,也导致这台服务器的带宽一直很高。为了解决这个问题,只好每隔10秒登陆200个考生,一分钟内全部登陆完毕,后面1200人同时进行测评没有任何问题。主要瓶颈就是集中登陆环节。第一次出现问题的时间是下午13点,第二次分批次登陆是17点。测评的时间线如下 而这2个时间段的测评人次分别是和。 可以看出,出问题的时段,与数据库交互的次数其实很少,而下午17点有近27000次的交互,由此也可以得出主要瓶颈就是集中登陆系统导致的,而实际的数据也符合上面的通过计算得出的结果。 -----------------------------------

【C++】vector容器详解&&迭代器失效问题

目录 vector介绍: vector常用接口: 1、构造函数(constructor) 2、析构(destructor) 3、迭代器(iterator) 4、容量相关 5、元素访问 6、修改相关 迭代器失效问题 什么是迭代器? 迭代器与指针: 迭代器的分类和操作: 为什么对迭代器分类? 迭代器失效问题即解决方法 vector介绍: 1、vector是表示可变大小的序列容器 2、就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。 3、本质讲,vector使用动态分配数组来存储它的元素。当元素插入的时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。 4、vector分配空间粗略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于再末尾插入一个元素的时候是在常数时间的复杂度完成的。 5、因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态曾张。 6、与其他动态序列容器相比(deques、lists and forward _lists), vector在访问元素时候更加高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_lists统一的迭代器和引用更好。 vector常用接口: 1、构造函数(constructor) const allocator_type & alloc = allocator_type()是一个配置器相关内容,它是用于指定要使用的空间配置器的,STL提供的默认的空间配置器,我们基本不用管这个参数,除非是我们自己实现了一个空间配置器,然后希望使用我们自己写的空间配置器。暂时忽略即可。 ①explicit vector(const allocator_type & alloc = allocator_type()):构建一个没有元素的空容器 ②explicit vector(size_type n, const value_type& val = value_type(), const allocator_type & alloc = allocator_type()):构造n个值为val的容器 ③template<class InputIterator> vector(InputIterator first, InputIterator last, const allocator_type & alloc = allocator_type()):根据给定的范围构造容器v3,这个范围也可以是数组的一部分。 ④vector(const vector& x):拷贝构造,用容器x的内容来构造新的容器

vector<string>的应用

参考 vector<string>_赤饭睡觉的博客-CSDN博客_vector<string>是什么类型 目的:搞懂 vector<string> a a[0].size() 和a.size()的区别 2022.4.14 结论: 1、a[0].size 计算存放在vector中第一个元素有多长 2、a.size 计算存放了多少个元素在vector中 3、可以将vector<string> a 看作是二维数组 4、a[3][2]=s a[4][4]=j a[行][列] 行->a.size() 列->a[某行].size() #include<iostream> #include<string> #include<vector> using namespace std; int main() { vector<string> a ={"aasd7777","bbasd","asdal","dasdas", /*第四个元素:"a"*/ "adsajsadada","sda","dsa"}; int b = a[0].size();//计算第1个位置上总共多长,vector数组从0开始存放第一个元素 int c = a.size();//计算vector中总存放了几个元素 int d = a[6].size();//计算第7个位置 cout << a[3][2] << endl;//s cout << a[4][4] << endl;//j //超过第四个元数的长度 报错 subscript out of the range cout << b<<endl;//8 cout << c << endl;//7

树莓派配置opencv环境(包含c++和python)

文章目录 基本设置1、把根目录扩展到整个SD卡2、配置摄像头设备 配置环境3、安装opencv所需库3.1 安装numpy3.2 安装opencv依赖 4、安装opencv4.1 python环境4.2 c++环境及python环境(11以及11之前的系统版本)均可 5、设置Cmake参数6、编译7、测试7.1 python环境测试7.2 c++环境测试 基本设置 1、把根目录扩展到整个SD卡 命令行输入: sudo raspi-config 选择Advanced Options(光标移动,Tab键选择,空格键确认) 选择Expand Filesystem 设置完成后退出重启树莓派。 如果没有出现重启选项,在命令行输入: sudo reboot 2、配置摄像头设备 在OpenCV中,读取摄像头数据,需要开启v4l2(video for linux 2),开启方法如下: 命令行输入: sudo vim /etc/modules 打开后在文件最后添加一行: bcm2835-v4l2 配置环境 3、安装opencv所需库 3.1 安装numpy sudo pip3 install numpy 3.2 安装opencv依赖 sudo apt-get install build-essential git cmake pkg-config -y sudo apt-get install libjpeg8-dev -y sudo apt-get install libtiff5-dev -y sudo apt-get install libjasper-dev -y sudo apt-get install libpng12-dev -y sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev -y sudo apt-get install libgtk2.

函数内部:this详解(重点)

文章目录 一、引入this二、this绑定规则 1.默认绑定2.隐性绑定3.new绑定4.call()、apply()、bind()显性绑定三、箭头函数总结 一、引入this this是JavaScript的关键字之一,作为函数内部的一个特殊对象,我们通常所说的this值指的是把包含它的函数被当作方法调用时的上下文对象。 听着有点绕口,于是我简单粗暴地将上面这句话拆分成三大块,便于理解: this是函数内部的一个对象(类似于arguments)当该函数被xxx对象调用时this的值就是xxx对象 二、this绑定规则 当你理解了上文概括的三句话后,此时this已经向你打开了一扇门!以下我们将通过多种多样的栗子,了解this的各类令人作呕的操作 1.默认绑定 直接不带任何修饰的赤裸裸的函数调用,this将默认绑定,一般是绑定到window象上(当函数在全局上下文中调用) 注意:在严格模式下,调用函数时如果没有指定上下文对象,this值不会指向window,除非使用apply()或call()把函数指定给一个对象,否则this值会变成undefined 举个栗子: window.color = 'pink'; function sayColor() { let color = 'blue'; console.log(this.color); } sayColor(); 输出结果:pink 分析:根据上栏2、3,首先找到sayColor()的调用对象是谁,很明显sayColor()在全局上下文中被调用,调用对象为window对象,此时this的值就是window对象,this.color相当于window.color 2.隐性绑定 函数调用时有了自己的上下文对象,函数的this绑定该上下文对象上 举个栗子: window.color = 'pink'; function sayColor() { let color = 'blue'; console.log(this.color); } let obj = { color: 'red', sayColor: sayColor }; obj.sayColor(); 输出结果:red 分析:同理,找到sayColor()的调用对象是谁,显然是对象obj,此时this值就是对象obj,this.color相当于obj.color 补充:如果是链式的关系,如:xxx.obj.sayColor(),则采取就近原则,函数里的this默认绑定挨着最近的上下文对象 3.new绑定 在JavaScript机制中,当我们的函数通过new关键字修饰时候,该函数作为构造函数调用,通过new关键字创建构造函数时,JavaScript为我们做了以下工作: 创建一个新对象把该对象的_proto_指向原函数的prototype属性(继承原函数的原型) -------后续文章介绍原型与原型链该新对象上绑定到构造函数的this上返回新对象,在该构造函数不返回其他对象的情况下 举个栗子: window.name = "Matt"; function Person() { this.name = "

基于深度学习的表计识别方案

基于深度学习的表计识别方案 识别类型:单指针单表盘 多指针单表盘 多指针多表盘 数字表(ocr) 识别要求:误差<5 真实达标:97% 算法运行速度:20+ fps 硬件:jetson nx / hisi3559a 大致流程: 素材案例:

依赖注入之@Value原理(placeholder解析)

resolveEmbeddedValue是doResolveDependency方法处理@Value注解的第二步,resolveEmbeddedValue解析@Value注解中设置value的placeholder,将${xxx}替换为application.properties中配置的值。 回顾一下doResolveDependency方法,如下 public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { Class<?> type = descriptor.getDependencyType(); Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ?

Typora图片自动上传

Typora图片上传(PicGo + Gitee) 1.在码云新建一个仓库 2.设置私人令牌 这里的私人令牌一般都是没有设置过的,新建一个就可以了,新建完成后,复制token 3. 下载PicGo https://github.com/Molunerfinn/PicGo/releases/tag/v2.3.0-beta.3 4.安装PicGo并且安装gitee插件 5.配置插件 在typora中设置: 6.验证 成功后,插入一张图片,然后右击图片上传。 = = = = = = = = = = = = = = == = = = = = = == = = == = = = = = = = = = = = = = = = = = = = = == = = 2022年3月开始,gitee图床不能使用了,报错如下: 直接使用github或者其他付费的图床 使用github图床 1、生成token 直接访问 https://github.com/settings/tokens , 点击 Generate new token ,填写 token 的信息、选择token 的过期时间、并勾选repo。

Java程序员面试为什么失败?面试挂掉的5大原因

4月是程序员面试最为火热的时间阶段,我最近也是有很多小伙伴去大厂面试过了,但是通过的寥寥无几,那么Java程序员面试为什么失败?下面是Java程序员面试失败最有可能的5大原因,当然也许这5点原因适用于所有的程序员,所以,如果你是程序员,请认真阅读以下内容。 Java程序员面试为什么失败? 01说得太少 尤其是那些开放式的问题,如“请介绍下你自己”或“请讲一下你曾经解决过的复杂问题”。 面试官会通过你对这些技术和非技术问题的回答来评估你的激情。他们也会通过模拟团队氛围和与你的交流互动来判断你的经验和能力。 所以,仅仅只用两三句话来回答不但不能显示出你对这个专业的兴趣,还会让整个面试过程显得非常无聊。 如果你不能很好地说明你的经验、成就和技能可以给企业带来的价值,那么你的竞争力毫无疑问就高不起来。 所以,你需要对一些最常见的开放式问答作充分的准备,学会推销自己。 02说得太多 不断地说,不断地说,却并没有什么实质性的内容。换句话说,就是废话连篇,言之无物。 如果你不能简洁的解释问题,那么面试官就会怀疑你在工作时的表现是不是也会像你的谈话一样拖泥带水? 可以先问问面试官,确定是否真的需要详细解释。 解释也是一门艺术,关键是确定重点,如果需要的话再深入到细节。 当聊到业务的时候,就应该从业务的角度看问题,不要涉及任何技术术语。 学会用简洁明了的方式解释问题。如果你能时刻把握主旨,那么这一点也不是问题。 03回答不出一些必知的基本技术问题 面试不是技术竞赛,不是看谁答对的问题多,但是有一些“必须知道”的核心 Java 和 Web 基础知识,你不能不知。 例如,对于 Java 开发人员 1)不知道“==”和 equals() 之间的区别。 2)不知道 equals() 和 hashCode() 方法被隐式调用时的约定。 3)不知道 OO 的概念和设计原则。 4)不能很好地处理多线程。 5)不知道如何在 HTTP 客户端与服务器端之间保持状态。 6)不能解释曾投入精力过的应用程序的高层体系结构。 7)不知道 SQL。 04既写不好简单的代码,又回答不出如何解决棘手的问题 作为一个开发人员,你应该根据自己的经验水平,来针对给定的问题和情况编写代码。 特别是如果碰到一个比较棘手的问题,那么即使你还没有解决方案,也应该将你的思路讲给面试官听。 当然这在面试时会让人特别紧张,尤其是在还有时间限制的情况下,但是你也必须保持冷静,至少应该说明你将如何试着去解决问题的方法。 05糟糕的礼仪和态度 迟到,不适宜的着装,抖手抖脚,没有眼神接触,过于紧张,没有提问,显示不出对这份职业的兴趣; “我什么都知道”的高傲态度,贬低你的现在和以前的雇主; 遇到技术问题时烦躁不安或者垂头丧气,为自己找理由而不是虚心接受错误; 与面试官发生争执,不好的肢体语言; 随波逐流而没有自己的看法,过于呆板; 撒谎,嗓门太大,无法成为良好的倾听者,等等。 以上五点面试中较为常见的失败原因,如果同学们还碰其它的原因,可以写在下方的留言区,帮助其他同学避开那些面试的“坑”。 其中大多数坑都是自己的性格问题,只有技术问题我有办法帮你解决,这里免费分享一份GitHub 上标星 120k的Java核心进阶知识全面解析,不论是用于巩固基础,还是在面试中提高竞争力都很有用,下面展示部分截图。 点击文末名片,扫码即可免费获取! (一). 基础 1、Java 基本功 Java 入门(基础概念与常识)Java 语法基本数据类型方法(函数) 2、Java 面向对象 类和对象面向对象三大特征修饰符接口和抽象类其它重要知识点 3、Java 核心技术

强化学习模型研讨班

强化学习的模型:马尔科夫决策过程 1. 强化学习的定义 强化学习(Reinforcement Learning. RL)又称为鼓励学习、评价学习或增强学习,是机器学习的重要组成部分之一,用于描述和解决智能体(Agent)在与环境(Enviroment)交互过程中通过学习策略(Policy)以达到回报(Reward)最大化或实现特定目标的问题。 2、强化学习和其他机器学习领域的区别和联系 强化学习是和监督学习、非监督学习并列的第三种机器学习方法。 强化学习和监督学习的区别:强化学习不需要事先准备好训练数据,更没有输出作为监督来指导学习过程。强化学习只有奖赏值,但这个奖赏值和监督学习的输出不一样,它并不是事先给出的,而是延后给出的。同时,强化学习的每一步与时间顺序前后关系密切,而监督学习的训练数据一般是相互独立的,相互之间没有依赖关系。 强化学习与非监督学习的区别:非监督学习只有输入数据,没有输出值,也没有奖励值,同时非监督学习的数据之间也是相互独立的,相互之间没有依赖关系。 3. 强化学习建模 基本模型 基本组成元素: 智能体(Agent):强化学习的本体,作为学习者或决策者存在;环境(Enviroment):智能体以外的一切,主要指周围的所有状态;状态(State):表示环境的数据,状态集是环境中所有可能状态的集合;动作(Action):智能体可以做出的动作,动作集是智能体可以做出的所有动作的集合;奖励(Rewards):智能体在执行一个动作后,获得的正负奖励信号;策略(Policy):从状态到动作的映射,智能体基于某种状态选择某种动作的过程。 学习过程: Step 1:智能体感知环境状态; Step 2:智能体根据某种策略做出动作; Step 3:动作作用于环境导致环境状态改变; Step 4:同时,环境向智能体发出一个反馈信号(奖励或惩罚); 强化学习目标:智能体寻找在连续时间序列里的最优策略。最优策略是指使得长期累计奖励最大化的策略。 4、马尔科夫决策过程(Markov Decition Process, MDP) 马尔科夫性质(无后效性):在时间步 t + 1 t+1 t+1 时,环境的反馈仅取决于上一时间步 t t t 的状态 s s s 和动作 a a a,与时间步 t − 1 t-1 t−1 以及 t − 1 t-1 t−1 步之前的时间步都没有关联性。 P ( s t + 1 ∣ a t s t , a t − 1 s t − 1 , .

红黑树的插入与删除

一、红黑树的删除 情况一:删除的结点D(黑色)不存在左右孩子 被删除的结点分为其父结点的左孩子和右孩子,然后再分为下面这5种情况: 1.1.兄弟结点为红色(一定存在两个黑侄子): 1.2兄弟结点为黑色,近侄子为红色: 1.3兄弟结点为黑色,远侄子为红色: 1.4兄弟结点为黑色,两个红色侄子: 1.5兄弟结点为黑色,没有侄子: 情况二:删除的结点D(红色)不存在左右孩子:直接删除(最简单的情况) 情况三:删除的结点D只有一个左孩子(结点一定是黑色,孩子一定是红色):左孩子替换掉D,删除左孩子。 情况四:删除的结点D只有一个右孩子(结点一定是黑色,孩子一定是红色):右孩子替换掉D,删除右孩子。 情况五:删除的结点D有左右孩子(红黑都可以,一样分析):找到左子树的最大值,用该值替换要被删除的值,然后删除这个找到的最大值,这个最大值要么有一个左孩子,要么没有子结点,所以可以转换成上面的四种情况。 写代码的时候这样分:左右孩子都存在(情况五),只有一个孩子(情况三和情况四),左右孩子都不存在(2*10+1种情况,见上面的情况一和情况二) 插入比删除的情况少很多。 插入位置的父结点如果为红色,就需要进行修复。 先分颜色,然后在判断父亲,叔叔,自己的位置。 叔叔为红。叔叔为黑(或者不存在)。 父左,自己左。父左,自己右。父右,自己左。父右,自己右。 其实插入和删除最主要的是在插入和删除之后对红黑树的修复,因为在插入和删除操作之后,有可能会破坏红黑树的特性,找到需要修复的那几种情况,其他的正常删除和插入就好了。

udp协议

udp协议(user datagram protocol) 1. UDP协议简介 UDP(User Datagram Protocol),是基于IP协议的一种位于传输层的面向无连接的非可靠传输协议。udp协议虽然不可靠(unreliable)但是传输速度快,因此,通常被用于流媒体应用(因为对差错率要求低,但对传输速度要求高),udp还用于DNS和SNMP。 1.1 为什么需要udp协议? -----速度快 通信延迟低(无需建立连接)实现简单,无需维护连接状态头部开销少(8个字节)没有拥塞控制,应用可以更好地控制发送时间和速率 1.2 udp的应用场景 包总量较小的通信(DNS、SNMP等)对差错容忍度比较高的即时通信,如视频,音频等多媒体通信限定于LAN等特定网络的应用通信广播通信(广播,多播) 1.3 udp报文格式 1.2.1 udp报文长度(length) length字段记录了udp报文首部+数据的字节长度。该字段最小值为8字节,即数据部分为空。 1.2.2 udp校验和(checksum) udp校验和(checksum)都校验了哪些内容? 校验的内容包括伪首部,首部,数据三部分,校验和在发送端和接收端分别需要计算一次。 校验和(checksum)的校验方式及计算方法 发送端 把伪首部添加到udp数据报上,构成一个包含完整端点信息的数据报将首部校验和字段的16个bit全部置为0将整个数据报以16-bit按二进制反码算数求和。如果总的字节数不是偶数,则添加一个全0字节作为填充来辅助求和。 接收端 1. 如果接收端对数据报校验失败,udp协议会怎么处理该数据报? ​ 有两种情况会导致数据报被丢弃,一是发送端没有对数据报计算校验和,也就是checksum字段为全0,而接收端又对该字段值做了验证。二是接收端校验失败,数据报在传输过程中存在差错。 校验和(checksum)字段对udp协议来说是必须的吗? ​ udp的校验和(checksum)字段是可选的。在局域网中,由于数据报不需要通过路由器,产生差错的概率较小,此时不使用这个字段是可以接受的,因为可以大大提高传输速率(比较适用于流媒体文件的传输)。但如果数据报通过路由器时,数据产生差错的概率会大大增加,这个时候为了保证数据报的可用性,checksum字段就变得比较重要了。 校验和(checksum)校验通过就说明数据报一定不存在传输差错吗? 不一定,校验和校验通过只能说明,接收端有很高的自信度认为该数据报不存在差错,但并不是百分之百的,思考这样一种情景:数据报中多个位置产生差错,但是这些个位置的差错结合起来又恰巧使得接收端计算的校验和等于发送端,这个时候,这种差错检测机制就失效了,也就说明,校验机制并不能百分百保证数据一致性。 1.2.3 填充字节(Padding bytes) 填充字节只是为了辅助计算校验和,计算完毕后即丢弃,并不会随数据发送给接收端。 3. 关于udp协议的一些常见问题 使用udp协议,发送端是如何确定数据报有没有被接收端接收的? ​ 不能确定,发送端只负责发送,至于接收端有没有成功接收到,发送端是不负责的。反之,当接收端成功接收到消息时,也不会反馈给发送端。 议,发送端是如何确定数据报有没有被接收端接收的? ​ 不能确定,发送端只负责发送,至于接收端有没有成功接收到,发送端是不负责的。反之,当接收端成功接收到消息时,也不会反馈给发送端。 既然udp提供的服务是非可靠的,那采用udp协议的应用要如何实现可靠数据传输? 在应用层增加可靠性机制应用特定错误恢复机制

PHP面向对象简介

面向对象就是将要处理的问题抽象为对象,然后通过对象的属性和行为来解决对象的实际问题。我们通常所说的面向对象准确的说应该叫面向对象编程(OOP),它是面向对象的一部分。 面向对象主要分为三个部分,如下所示: 面向对象分析(Object Oriented Analysis,OOA);面向对象设计(Object Oriented Design,OOD);面向对象编程(Object Oriented Programming,OOP)。 本节我们主要介绍的是面向对象编程。 什么是面向对象编程 面向对象编程(Object-Oriented Programming,OOP)是一种编程思想,起源于 20 世纪 60 年代,直到 20 世纪 90 年代才成为应用软件开发的主流,并且逐渐从应用软件领域过渡到了 Web 领域。 在很多现代计算机语言中都有面向对象编程的概念,在不同的计算机语言中,这一思想所表现的内容丰富程度是不完全相同的,例如,Java 语言从一开始就设计成面向对象的编程语言,可以说面向对象就是其本质内涵。 面向对象就是将要处理的问题抽象为对象,然后通过对象的属性和行为来解决对象的实际问题。面向对象中两个重要的基本概念就是类和对象,接下来分别介绍一下。 1) 类 世间万物都具有其自身的属性和方法,通过这些属性和方法可以将不同事物区分开来。例如,人具有身高、体重和肤色等属性,还可以进行吃饭、学习、走路等活动,这些活动可以说是人具有的功能。可以把人看作程序中的一个类,那么人的身高可以看作类中的属性,走路可以看作类中的方法。 也就是说,类是属性和方法的集合,是面向对象编程方式的核心和基础,通过类可以将零散的用于实现某项功能的代码进行有效管理。例如,创建一个运动类,其中包括 5 个属性;姓名、身高、体重、年龄和性别,定义 4 个方法:踢足球、打篮球、举重和跳高。 总而言之,类是变量(类的属性)与作用于这些变量的函数(类的方法)的集合,属性与方法是构成类的基础。 2) 对象 类是具备某项功能的抽象模型,实际应用中还需要对类进行实例化,这样就引入了对象的概念。 对象是类进行实例化后的产物,是一个实体。仍然以人为例,“黄种人是人”这句话没有错误,但反过来说“人是黄种人”,这句话一定是错误的。因为除了黄种人,还有黑人、白人等。那么“黄种人”就是“人”这个类的一个实例对象。 可以这样理解对象和类的关系:类是对象的抽象,在类中可以定义对象的属性和方法;对象是类的实例,类只有被实例化后才能使用。 面向对象编程的特性 面向对象编程具有封装、继承、多态三大特性,它们迎合了编程中注重代码重用性、灵活性和可扩展性的需要,奠定了面向对象在编程中的地位。 1) 封装 封装就是将一个类的使用和实现分开,只保留有限的接口(方法)与外部联系。对于用到该类的开发人员,只要知道这个类该如何使用即可,而不用去关心这个类是如何实现的。这样做可以让开发人员更好地把精力集中起来专注于别的事情,同时也避免了程序之间的相互依赖而带来的不便。 例如,在使用计算机时,我们并不需要将计算机拆开了解它每个部件的具体用处,只需要按下电源键就能将计算机启动,这就体现了封装的好处。 2) 继承 继承就是派生类(子类)自动继承一个或多个基类(父类)中的属性与方法,并可以重写或添加新的属性或方法。继承这个特性简化了对象和类的创建,增加了代码的重用性。 例如,已经定义了 A 类,接下来准备定义 B 类,而 B 类中有很多属性和方法与 A 类相同,那么就可以用 B 类继承 A 类,这样就不用再在 B 类中定义 A 类中已有的属性和方法,从而可以在很大程度上提高程序的开发效率。 继承分为单继承和多继承,PHP 目前只支持单继承,也就是说一个子类有且只有一个父类。 3) 多态

ArcGIS中克里金插值操作

准备好存有坐标信息的Excel表格。 2.点击ArcMap菜单栏的“文件”—“添加数据”—“添加XY数据”,打开添加XY数据界面。 3.在添加XY数据界面,点击浏览按钮,选择存有坐标信息的Excel表格。 4. 设置X坐标和Y坐标对应的Excel表格列,设置坐标系信息,点击“确定”,将Excel表格添加到空白地图。 5.打开ArcMap的工具箱,选择“工具箱”—“系统工具箱”—“数据管理工具”—“要素”—“要素转点”,打开要素转点界面。 6.在要素转点界面,选择输入要素为刚刚添加的Excel文件,选择输出要素类的存储位置及名称,点击“确定”。 7.在要素转点界面,选择输入要素为刚刚添加的Excel文件,选择输出要素类的存储位置及名称,点击“确定”。 8. 先将降水量数据和行政区划数据,加入到arcmap中。 9.在菜单栏空白处,右键打开【Geostatistical Analyst】,再打开【统计向导】 10.选择【克里金法】,在右边数据集中选择【降雨量】字段,如果有和【降雨量】相关联的字段,如高程,可以依次添加在数据集2...,然后点击下一步 11.完成后发现范围未覆盖全图。 12.双击打开结果图层,将范围选择要覆盖的【行政区】。 13.要使结果范围和行政区匹配,先将行政区导出后合并为一个裁剪图层。 14.将clip图层,画一个覆盖行政区的矩形,反向裁剪后,样式设置成白色。 15. 最后克里金结果导出值会变,暂时只能在arcmap里面用。