图嵌入概述:节点、边和图嵌入方法及Python实现

年来基于图的机器学习有了很大的发展。基于图的方法在数据科学中的许多常见问题中都有应用,例如链接预测、社群发现、节点分类等。根据如何组织问题和所拥有的数据,有许多解决问题的方法。本文将提供一个基于图的嵌入算法的高层次的概述。最后还将介绍如何用Python库(如node2vec)来在图上生成各种嵌入。

基于图的机器学习

人工智能有各种分支,从推荐系统、时间序列、自然语言处理、计算机视觉、图机器学习等。有多种方法可以通过基于图的机器学习来解决常见问题。包括社群发现、链接预测、节点分类等。

与图机器学习的一个主要问题是找到一种表示(或编码)图结构的方法,以便机器学习模型可以轻松地利用它[1]。一般情况下机器学习中解决这个问题需要通过与模型相关联的结构化表格数据来学习某种表示,这在以前是通过统计测量或核函数来进行的。近年来趋势已经转向对图进行编码以生成嵌入向量来训练机器学习模型。

机器学习模型的目标是训练机器在数据集中大规模学习和模式识别。在处理图时这一点会被放大,因为图提供不同而复杂的结构,这是其他形式的数据(如文本、音频或图像)所不具备的。基于图的机器学习可以检测并解释重复出现的潜在模式[2]。

我们可能对确定与社交网络上的用户相关的人口统计信息感兴趣。人口统计数据包括年龄、性别、种族等。像Facebook或Twitter这样的公司的社交媒体网络范围从数百万-数十亿的用户和数万亿的边。肯定会有几个与该网络中用户的人口统计信息相关的模式,这些模式不容易通过人类或算法检测到,但模型应该能够学习它们。类似地,我们可能想推荐一对用户成为朋友,而他们目前还不是朋友。这就为链接预测(基于图的机器学习的另一个应用)提供了素材。

什么是图嵌入?

特征工程是指处理输入数据形成一组特征的常用方法,这些特征提供了原始数据集的紧凑且有意义的表示。特征工程阶段的结果将作为机器学习模型的输入。这是在表格结构化数据集的处理时必备的过程,但在处理图数据时却是一种难以执行的方法,因为需要找到一种方法来生成与所有图数据相关联的合适表示。

有多种方法可以从图中生成表示结构信息的特征。最常见和最直接的方法是从图中提取统计数据。这可以包括识别度分布、page rank、centrality metrics、jaccard 分数等。然后通过内核函数将所需属性合并到模型中,但是核函数的问题是生成结果的相关时间复杂度很高。

最近的研究趋势已经转向寻找有意义的图表示,对图生成嵌入表示。这些嵌入学习了保持网络原始结构的图表示。我们可以将其视为旨在将离散图转换为连续域的映射函数。一旦学习了函数,就可以将其应用于图,并且生成的映射可以用作机器学习算法的特征集 [2]。

图嵌入的类型

对图的分析可以分解为 3 个粒度级别。节点级别、边缘级别和图级别(整个图)。每个级别由生成嵌入向量的不同过程组成,所选过程应取决于正在处理的问题和数据。下面介绍的每个粒度级别的嵌入都有附图来直观地彼此不同。

节点嵌入

在节点级别,生成与图中的每个节点关联的嵌入向量。这个嵌入向量可以容纳图的表示和结构。本质上说彼此接近的节点也应该有彼此接近的向量。这是流行的节点嵌入模型(如Node2Vec)的基本原则之一。

边嵌入

在边缘层中,生成一个与图中的每条边相关的嵌入向量。链路预测问题是使用边嵌入的一个常见应用。链接预测是指预测一对节点之间是否有一条边连接的可能性。这些嵌入可以学习图提供的边属性。例如在一个社交网络图中,可以有一个多边图,其中节点可以根据年龄范围、性别等用边连接。表示该边的相关向量可以学习这些边属性。

图嵌入

图级别的嵌入并不常见,它们包括生成一个表示每个图的嵌入向量。例如一个有多个子图的大图,每个对应的子图都有一个表示图结构的嵌入向量。分类问题是图嵌入可能有用的常见应用。这些类型的问题将包括将图分类到特定类别。

Python实现

使用python代码实现我们需要以下的这些库

 Python=3.9
 networkx>=2.5
 pandas>=1.2.4
 numpy>=1.20.1
 node2vec>=0.4.4
 karateclub>=1.3.3
 matplotlib>=3.3.4

如果您没有安装node2vec包,请参考它的文档。安装karateclub包,也类似

节点嵌入

 import random
 import networkx as nx
 import matplotlib.pyplot as plt
 
 from node2vec import Node2Vec
 from node2vec.edges import HadamardEmbedder
 from karateclub import Graph2Vec
 
 plt.style.use("seaborn")
 
 # generate barbell network
 G = nx.barbell_graph(
     m1 = 13,
     m2 = 7
 )
 
 # node embeddings
 def run_n2v(G, dimensions=64, walk_length=80, num_walks=10, p=1, q=1, window=10):
     """
     Given a graph G, this method will run the Node2Vec algorithm trained with the
     appropriate parameters passed in.
     
     Args:
         G (Graph) : The network you want to run node2vec on
     
     Returns:
         This method will return a model 
     
     Example:
         G = np.barbell_graph(m1=5, m2=3)
         mdl = run_n2v(G)
     """
     
     mdl = Node2Vec(
         G,
         dimensions=dimensions,
         walk_length=walk_length,
         num_walks=num_walks,
         p=p,
         q=q
     )
     mdl = mdl.fit(window=window)
     return mdl
 
 mdl = run_n2v(G)
 
 # visualize node embeddings
 x_coord = [mdl.wv.get_vector(str(x))[0] for x in G.nodes()]
 y_coord = [mdl.wv.get_vector(str(x))[1] for x in G.nodes()]
 
 plt.clf()
 plt.scatter(x_coord, y_coord)
 plt.xlabel("Dimension 1")
 plt.ylabel("Dimension 2")
 plt.title("2 Dimensional Representation of Node2Vec Algorithm on Barbell Network")
 plt.show()

上图是由barbell graph 生成的节点嵌入可视,有许多计算节点嵌入的方法,如node2vec、deep walk、random walks等。这里使用node2vec。

边嵌入

 edges_embs = HadamardEmbedder(
     keyed_vectors=mdl.wv
 )
 
 # visualize embeddings
 coordinates = [
     edges_embs[(str(x[0]), str(x[1]))] for x in G.edges()
 ]
 
 plt.clf()
 plt.scatter(coordinates[0], coordinates[1])
 plt.xlabel("Dimension 1")
 plt.ylabel("Dimension 2")
 plt.title("2 Dimensional Representation of Edge Embeddings on Barbell Network")
 plt.show()

通过barbell graph查看边嵌入的可视化,Hammard Embedder的源代码可以在这里找到(https://github.com/eliorc/node2vec/blob/master/node2vec/edges.py#L91)。

图嵌入

 n_graphs = 10
 Graphs = [
     nx.fast_gnp_random_graph(
         n = random.randint(5,15),
         p = random.uniform(0,1)
     ) for x in range(n_graphs)
 ]
 
 g_mdl = Graph2Vec(dimensions=2)
 g_mdl.fit(Graphs)
 g_emb = g_mdl.get_embedding()
 
 x_coord = [vec[0] for vec in g_emb]
 y_coord = [vec[1] for vec in g_emb]
 
 plt.clf()
 plt.scatter(x_coord, y_coord)
 plt.xlabel("Dimension 1")
 plt.ylabel("Dimension 2")
 plt.title("2 Dimensional Representation of Graph Embeddings on Randomly Generated Networks")
 plt.show()

这是一个由随机生成的图的图嵌入可视化,graph2vec算法的源代码可以在这里找到。(https://karateclub.readthedocs.io/en/latest/_modules/karateclub/graph_embedding/graph2vec.html)

总结

嵌入是一个将离散图映射到向量表示的函数。从图数据中可以生成多种形式的嵌入,节点嵌入、边嵌入和图嵌入。所有三种类型的嵌入都提供了一种向量表示,将图的初始结构和特征映射到X维的数值。

本文的源代码在这里:

https://github.com/vatsal220/medium_articles/blob/main/graph_embeddings/graph_emb.ipynb

引用

  • [1] https://www-cs.stanford.edu/people/jure/pubs/graphrepresentation-ieee17.pdf
  • [2] Graph Machine Learning by Aldo Marzullo, Claudio Stamile and Enrico Deusebio
  • [3]https://karateclub.readthedocs.io/en/latest/_modules/karateclub/graph_embedding/graph2vec.html

作者:Vatsal

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

相关文章

  • 视频抽帧实践---openCV和decord视频编解码

    背景:剪辑平台中需要处理大量的视频,对视频内容的理解,离不开对视频的降维操作,一般流程是进行抽帧。抽帧操作是很多视频处理的第一步,也是基础数据的一步,大量算法模型离不开帧数据的训练,而高质量的视频,它的fps(每秒帧数)很大,这就造成了处理高清视频时,抽帧速度会成为整个视频处理的瓶颈,本文将对比目前主流的两个视频读取库,openCV和decord进行对比。流程:我们以m3u8文件流进行测试,m3u8视频流,是有多个连续的ts文件组成,浏览器加载ts序列,每个ts是一定的时间连续不断的进行播放,我们按照固定帧率进行抽取,并裁减,最后保存图片,流程如下: 一.使用opecv进行抽帧cap=cv2.VideoCapture(ts_url) fra_num=cap.get(cv2.CAP_PROP_FRAME_COUNT)#获取帧数 rate=cap.get(cv2.CAP_PROP_FPS)#获取帧率 logger.info(f'帧数{fra_num}') logger.info(f'帧率{rate}') duration=fra_num/rate l

  • 【程序源代码】餐饮点餐外卖小程序

     “ 关键字: “餐饮点餐外卖的开源小程序" 01————【总体介绍】 餐饮点餐外卖小程序,基于微信小程序原生的设计与实现 本项目为专业的小程序项目,我们没有能力和计划为该项目配套开发接口及后台管理程序,为了更好的展示、演示本小程序的运行效果,本项目的api接口及后台管理直接嫁接使用的api工厂的免费云接口和云后台,在此先表示感谢!02 ————【安装使用】软件架构api工厂右上角注册免费开通您的专属后台建议将上面扫码演示的小程序的测试数据一键克隆到你自己的后台,方便测试,调试完毕后,再在后台重新修改/发布数据登录后台,左侧菜单“工厂设置”-->“数据克隆”,选择“将别人的数据克隆给我”,对方商户ID,填写13886,接口完成数据克隆设置小程序名称mallName 上传banner轮播图片 设置小程序appid和secret 数据维护 修改本项目源码根目录下config.js文件,noodles为您的专属域名module.exports={ version:"0.0.1", note:'构建项目', subDomain:"

  • MAC电脑添加打印机设置

    在桌面下方找到系统偏好设置选项 然后选择打印机与扫描 单击左下角添加按钮 选择ip选项按钮 输入打印机IP地址然后单击添加按钮  在弹出的选项卡选择好选 此时打印机添加完毕就可以查看打印机当前的状态和打印你的文档了

  • 设计模式之外观(门面)模式

    外观(门面)模式外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。类似的实际例子有消息中间件,把一个数据丢到消息中间件,谁需要,谁去消息后中间件去拿。这种设计模式可以用于解耦。我们举个栗子,你要去工厂制造一辆汽车,你需要先从门口去一楼制造引擎,再从门口去二楼制造底盘,最后从门口去五楼制造变速箱,然后去四楼制造轮胎,这样整个流程会特别繁琐,外观模式就提供一个门面接口(Facade),门面内把原来的逻辑流程进行封装,你只需要从门口去到这个门面,门面内部分工帮你去管理汽车的制造流程。回归代码世界,如果我们不使用门面模式,需要调用发动机制造的对象、底盘制造的对象变速箱制造的对象等等,这样你的业务逻辑便显得杂乱无章并且代码各个子系统之间的耦合度很高,显然这样做不是最优方案。 门面解决方案:将汽车制造流程逻辑进行封装,只提供一个汽车制造接口,当客户访问汽车接口(Facade)时,工厂内部流水线制造组装完成一辆用户所需的汽车。这样做的优点就是:

  • Spring MVC HTTP406 Not Acceptable

    今天在搞前后端分离用springmvc传递json数据的时候,第一步就卡主了,本着完事开头难的做法(哈哈哈),报了个406?什么鬼?百度之后发现很多人也同我一样遇到过这个问题,记录下。找到的处理方案有:1、没有启用注解标签在配置文件中<mvc:annotation-driven/>2、是controller中方法返回时候没有使用@ResponseBody3、没有加上jackson的json处理依赖,那么我们只需要在maven配置文件里面加上<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.54</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-dat

  • Python_关于pymongo与bso

    __PyMongo模块主页 下载PyMongo模块时它会有一个相对应bson模块也就是说PyMongo模块的实现是基于和它一起的bson模块的 该bson模块并非我们用pipinstallbson安装的bson。 当你的系统环境下同时具备这两个模块时PyMongo模块和bson模块的相对应功能便会挂掉. 比如说报错:ImportError:Nomodulenamedbson.code 解决方案:在需要bson模块时将其下载好放置自己项目的目录下并改名使用 如: 当然如果你有更好的解决方法欢迎指出 **bson模块** 是一种类json的一种二进制形式的存储格式,简称BinaryJSON,它和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型; BSON有三个特点:轻量性、可遍历性、高效性,但是空间利用率不是很理想 MongoDB使用了BSON这种结构来存储数据和网络数据交换; 比如 这是MongoDB中的一条记录也是一个简单的BSON结构体,其中每一个element都是由key/value对组成的 把这种格式转化成文

  • Flutter | 如何实现一个水波纹扩散效果的 Widget

    先来看图:我们在日常使用APP当中,肯定会遇到这种效果,那么这种效果是如何实现的呢?确认需求首先还是老套路,先确定一下需求,捋一下思路,然后才好写代码:1.首先要有一个圆2.这个圆会边扩散边消失3.当这个圆扩散到一定程度的时候再绘制一个圆4.有限循环/无限循环5.可以有/无Child捋好了思路,下面我们来开始实现。首先要有一个圆首先有一个圆,这个圆应该怎么画?我想到了两种方案:1.CustomPaint2.ClipOver这两种方式都很简单,所以我选择了后者,因为后者更简单(23333)。代码我就不贴了,不过代码我已经提交到了https://github.com/wanglu1209/WFlutterDemo,可以随时查看。这个圆会边扩散边消失一边扩散,一边消失。没错,这里也是使用这种evaluate来计算大小和透明度。代码如下:Container(width:_radiusTween.evaluate(animation),height:_radiusTween.evaluate(animation),child:ClipOval(child:Opacity(opacity:_opa

  • CTF从入门到提升之约束条件的安全测试报错注入

    关于基于约束的SQL攻击在创建数据库的时候,一般会先定义整个表的结构,假设我要做的是登录入口,先简单地创建一个用户表。(用户表中,我这里是定义了三个字段,第一个是ID,然后第二个是用户名)表已经建完之后,看起来也没什么问题,那么如果说我开发完了之后,应该有个登录入口。对没有账号的人来说,需要有一个注册入口。注册的本质是一个insert的过程,就是往里插入一条数据。假如里面数据库没有数据,我就要往里加一个管理员账户。这个管理员我就会对它设置成admin,密码是12346789。(在这里我做一个演示,如果大家想看可以到安全牛课堂的视频里看动手操作  CTF从入门到提升  课时2:3分0秒)先去创建这张数据表,看一下,然后去创建一张,对吧?只有两张表,然后我就去对uc。里面是空的,对吧?我接下来就往里插条数据insert。刚才我们提到了去注册的时候,它的本质其实是我们一起插入一条数据,它的长度是有限制的,它限制了30位,如果说我们插入31位会这样,它会自动的把31位就是说大于30的东西给吃掉,就是相当于抹掉了,它只会插入前30位。那么查出去插入的时候,它肯定会先去查一下,你去操作数据在表中原

  • blocked for more than 120 seconds

    现象:系统hang住,可以ping通,但ssh无响应在导入数据的时候,服务器突然无反应,连接不上,基本上就判定死掉了,重启服务器后查看日志如下:Mar2608:13:01localhostkernel:INFO:taskflush-8:0:26079blockedformorethan120seconds. Mar2608:13:01localhostkernel:Tainted:P---------------2.6.32-431.el6.x86_64#1 Mar2608:13:01localhostkernel:"echo0>/proc/sys/kernel/hung_task_timeout_secs"disablesthismessage. Mar2608:13:01localhostkernel:flush-8:0D000000000000000102607920x00000080 Mar2608:13:01localhostkernel:ffff8804359118c000000000000000460000000000000000ffff8804

  • CLion 2022 for Mac(C和C ++ IDE智能代码编辑器)v2022.2.4激活版

    CLion2022forMac是一款专为开发C及C++所设计的跨平台IDE。在与CMake和CMake预设集成方面,CLion2022.2版本更出色。QuickDocumentation(快速文档)弹出窗口已成为C++和CMake代码的实用知识来源。增强的静态和动态代码分析、更出色的调试器集成以及针对远程和Docker工具链的性能改进将帮助您更高效地开发。CLion2022forMacclion2022mac中文激活版特色功能 电动工具1、用于电动语言智能C和C++编辑器由于本机C和C++支持,包括现代C++标准,libc++和Boost,CLion一直都知道您的代码,并在您专注于重要事项时处理例程。2、导航立即导航到符号的声明或上下文用法,在整个项目中按名称搜索类,文件或符号,通过结构和层次视图查找代码库。3、代码生成添加类成员,覆盖/实现函数,生成构造函数/析构函数,getter/setter,相等,关系和流输出操作符,用语句包装代码块,或者从实际使用中生成声明-所有这些都通过简单的键盘快捷键完成。4、重构重命名符号,在层次结构中上/下移动成员,更改函数签名,并确保CLion的自动

  • 【Java面试】面试遇到宽泛的问题,这么回答就稳了,谈谈你对Redis的理解

    “谈谈你对Redis的理解”! 面试的时候遇到这类比较宽泛的问题,是不是很抓狂? 是不是不知道从何开始说起? 没关系,今天我用3分钟教你怎么回答。 大家好,我是Mic,一个工作了14年的Java程序员。 这个问题面试官考察的目的是什么?希望得到什么样的回答? 考察目标 对于某某技术的理解这一类问题,它是一种比较宽泛的问题 在面试过程中,考察这类问题有两个很重要的目的: 在面试的过程中,面试官希望求职者能多说一些东西,从而更好的对你的整体情况和能力有一个清晰的判断,因此这类问题,可以找到一些了解你的突破口。 这种问题其实没有标准答案,更多的是基于你对它的理解的一个总结这反而能够更好的考察你的技术积累和逻辑表达能力。 所以,求职者在回答的过程中,需要尽可能逻辑清晰,简单明了的表述出来。 否则很难得到认可。 问题解析 关于Redis是什么,想必大部分人都能脱口而出。 它是一个分布式缓存中间件?可这样回答有问题吗?当然有 准确来说,Redis是一个基于内存实现的Key-Value数据结构的Nosql数据库。 注意,这里有三个关键点。 内存存储 key-value结构 Nosq

  • ubuntu16.04下安装docker

    原文地址:传送门   本文开发环境为Ubuntu16.04LTS64位系统,通过apt的docker官方源安装最新的DockerCE(CommunityEdition),即Docker社区版,是开发人员和小型团队的理想选择。 开始安装 由于apt官方库里的docker版本可能比较旧,所以先卸载可能存在的旧版本: $sudoapt-getremovedockerdocker-enginedocker-cedocker.io复制 1 更新apt包索引: $sudoapt-getupdate复制 1 安装以下包以使apt可以通过HTTPS使用存储库(repository): $sudoapt-getinstall-yapt-transport-httpsca-certificatescurlsoftware-properties-common复制 1 添加Docker官方的GPG密钥: $curl-fsSLhttps://download.docker.com/linux/ubuntu/gpg|sudoapt-keyadd-复制 1 使用下面的命令

  • SQl数据操作和查询

    概括的内容包括: Oracle数据类型 SQL建表和约束 SQL对数据删改 SQL查询 Oracle伪例  1、首先说一下SQL的语句:      在Oracle数据开发中,客户端把SQL语句发送给服务器,服务器对SQL语句进行编译、执行,把执行的结果返回给客户端,OracleSQL语句有一下命令组成:     数据定义语句(DDL):create(创建命令)、alter(修改命令)、drop(删除命令)等;     数据操作语言(DML):insert(插入命令)、update(跟新命令)、delete(删除命令)、select...fromupdate(查询命令); ------数据操作之后需要commit提交才能在前端显示出信息      数据查询语言(DQL):基本查询语句、orderby子句、groupby分组语句;     事物控制语言(TCL):commit(提交命令)、savepoint(保存点命令)、rollback(回滚命令);  就我用过的数据库有:SQLServer、MySQL、Oracle,每个数据库都有各自独特的特

  • tensorflow中的kernel/Adam 变量的来源

       原因是使用Adam优化函数时,Adam函数会创建一个Adam变量,目的是保存你使用tensorflow创建的graph中的每个可训练参数的动量, words/_word_embeddings:0 bi-lstm/bidirectional_rnn/fw/lstm_cell/kernel:0 bi-lstm/bidirectional_rnn/fw/lstm_cell/bias:0 bi-lstm/bidirectional_rnn/bw/lstm_cell/kernel:0 bi-lstm/bidirectional_rnn/bw/lstm_cell/bias:0 proj/W:0 proj/b:0 bi-lstm_secondLayer/bidirectionalt_rnn/fw/lstm_cell/kernel:0 bi-lstm_secondLayer/bidirectional_rnn/fw/lstm_cell/bias:0 bi-lstm_secondLayer/bidirectional_rnn/bw/lstm_cell/kernel:0 bi-l

  • HashMap、TreeMap、LinkedHashMap、hashtable的区别

    Map主要用于存储健值对,根据键得到值,因此不允许键重复(重复了覆盖了),但允许值重复   hashMap是hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许有空键值,由于非线程安全,效率上面可能高于Hashtable。   HashMap允许将null作为一个entry的key或者value,而hashtable不允许   hashMap把hashtable的contains方法去掉了,改成了containsvalue和containsKey因为contains方法容易让人引起误解。    Hashtable继承自Dictionary类,而HashMap是java1.2引进的Map interface的一个实现。最大的不同是,Hashtable的方法是synchronize的,而HashMap不是,在多个线程访问 Hashtable时不需要自己为它的方法实现同步,而HashMap就必须为之提供外同步。Hashtable和HashMap采用的 h

  • Flume 详解&amp;实战

    Flume 1.概述 Flume是一个高可用,高可靠,分布式的海量日志采集、聚合和传输的系统。Flume基于流式架构,灵活简单。 Flume的作用 Flume最主要的作用就是,实时读取服务器本地磁盘的数据,将数据写入到HDFS Flume的特性 有一个简单、灵活的基于流的数据流结构 具有负载均衡机制和故障转移机制 一个简单可扩展的数据模型 三大核心组件 Agent是一个JVM进程,它以事件的形式将数据从源头送至目的 Agent主要有3个部分组成,Source、Channel、Sink source数据源 从外界采集各种类型数据,将数据传递给channel 类型很多:文件、目录、端口、Kafka等 ExecSource:实现文件监控,注意tail-F和tail-f的区别,前者根据文件名后者根据文件描述进行跟踪 NetCatTCP/UDPSource:采集指定端口(tcp、udp)的数据 SpoolingDirectorySource:采集文件夹里新增的文件 KafkaSource:从Kafka消息队列中采集数据 channel临时存储数据的管道 接受Source发

  • 一、项目策划 —— "快应用 + Spring Cloud"组合拳-技术社交快应用实战教程

    概述 项目创意策划工具:xmind。 项目由三部分组成: 终端用户客户端,采用快应用构建; 系统管理员客户端,也采用快应用构建,对系统中的数据进行维护(增删改查); 服务端RestApi,采用Java编写代码,使用SpringCloud架构,应对高并发时系统负载均衡。  1.用户快应用客户端  2.管理员快应用客户端  3.Java后端RestApi服务 后面教程详述。 H-UI——做体验最好的快应用UI库,让快应用开发就像搭积木!

  • 截屏、录像、同屏(通过libyuv进行像素转换、裁剪)

    本篇文章借鉴的博客比较多,有些忘记原出处了,还请原作者谅解   主要用到ImageReader、VitrualDisplay、libyuv库   ImageReader接收VirtualDisplay投屏的手机屏幕数据,然后通过libyuv进行像素转换、裁剪  (RGBA_8888->I420 ->裁剪I420->NV21)   直接上核心代码 //获取imageReader中的最新数据 image=mImageReader.acquireLatestImage(); //非空判断,如果为空,使用缓存的上一帧数据 if(image==null){ returnlastFrame; } finalImage.Plane[]planes=image.getPlanes(); finalintwidth=image.getWidth(); finalintheight=image.getHeight(); intpixelStride=planes[0].getPixelStride();//像素之间间隔 fin

  • 算法类书籍汇总

    入门类算法书籍: 大话数据结构算法图解 面试经典书籍 编程之美剑指offer编程珠玑编程之美微软面试心得 经典书籍 数据结构与算法分析C语言描述数据结构与算法分析C++语言描述算法导论算法C语言描述 圣经级著作 计算机程序设计艺术 这些书啃下来,对于书籍基本上够了。 基本收集了这些经典类算法书籍,如有需要可扫描关注下面二维码,关注嵌入式客栈,后台发送:“算法”即可获取百度链接 为节约时间,文章同步自公众号(首发) 如需学习资料,请用微信关注文中公众号二维码,后台发送"领取",可免费获取海量学习资料,涵盖单片机技术,信号处理,人工智能,嵌入式linux,C/C++编程,数据结构与算法

  • 面向切面AOP

     在传统的编写业务逻辑处理代码时,我们通常会习惯性地做几件事情:日志记录、事务控制及权限控制等,然后才是编写核心的业务逻辑处理代码。当代码编写完成回头再看时,不禁发现,扬扬洒洒上百行代码中,真正用于核心业务逻辑处理才那么几行,如图6-4所示。方法复方法,类复类,就这样子带着无可奈何遗憾地度过了多少个春秋。这倒也罢,倘若到了项目的尾声,突然决定在权限控制上需要进行大的变动时,成千上万个方法又得一一"登门拜访",痛苦"雪上加霜"。   如果能把图6-4中众多方法中的所有共有代码全部抽取出来,放置到某个地方集中管理,然后在具体运行时,再由容器动态织入这些共有代码的话,最起码可以解决两个问题: Java EE程序员在编写具体的业务逻辑处理方法时,只需关心核心的业务逻辑处理,既提高了工作效率,又使代码变更简洁优雅。 在日后的维护中由于业务逻辑代码与共有代码分开存放,而且共有代码是集中存放的,因此使维护工作变得简单轻松。 面向切面编程AOP技术就是为解决这个问题而诞生的,切面就是横切面,如图6-5所示,代表的是一个普遍存在的共有功能,例如,日志切面、权限切

  • Centos7 上安装mysql遇上的问题:mysql无法正常启动

    第一次在Centos上安装mysql遇到的一些问题。 第一步就遇到问题,安装mysql-server报错没有可用包。  【解决方法】 先要安装mysql #wgethttp://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm #rpm-ivhmysql-community-release-el7-5.noarch.rpm复制 1 2 之后再安装mysql-server #yum-yinstallmysql-server复制 1 然后systemctlenablemysqld设置mysql自启动之后systemctlstartmysqld这时候出问题了,运行之后一直卡着没有反应,如下 [root@localhost~]#systemctlstartmysqld Redirectingto/bin/systemctlstartmysql.service复制 1 2 systemctlstatusmysqld查看mysql服务的状态如下 [root@localhostsbin]#systemctl

相关推荐

推荐阅读