精华内容
下载资源
问答
  • 为什么说C++太复杂复杂的必要性是为什么?

    万次阅读 多人点赞 2020-05-05 09:54:01
    文章目录1 常见观点2 反驳观点3 为什么要解决的问题越复杂,工具就不得不复杂?3.1 类库和语言语意3.2 折中方案3.3 复杂度的守恒 1 常见观点 可以轻易的找出许多文献说明C++太复杂了,例如学习C++的书籍的厚度。 ...

    1 常见观点

    可以轻易的找出许多文献说明C++太复杂了,例如学习C++的书籍的厚度。
    这样以至于C++的设计者Bjarne都曾怀疑具有类的C是不是已经太庞大了。
    因为,总有大量对语言的新特性的要求:

    • 对如何利用现有特性完成某些任务没有足够的了解
    • 天生喜欢评价主流编程语言的人
    • 许多使用者遇到了实际的问题,确实需要语言本身提供支持来解决这些问题(大部分)

    2 反驳观点

    但是C++只在被孤立看待的时候,才会觉得复杂性。设计任何一门语言都是有背景的。
    C++面向的是这样的特定用户:

    • 应对各种复杂问题
    • 写出运行相当长时间的解决方法
    • 解决方案要满足任意的性能要求
    • 工作在不同的硬件和操作系统上
    • 和许多已存在的系统共存

    虽然人们都希望有简单的语言,但是人们真正需要的是有助于解决问题的语言。
    由于C++相当流行,因此得到结论,人们愿意为了语言所提供的强大表现力和高效率而放弃对简单性的要求。

    3 为什么要解决的问题越复杂,工具就不得不复杂?

    3.1 类库和语言语意

    例如C++中的赋值和初始化,在很多语言中都没有区别,比如C。
    为什么在C++中却如此重要呢?
    C++允许变量“拥有”一定的资源,如果值改变,就必须放弃这些资源。
    当我们在编写那些要处理分配在别处的数据结构的类时,差异就很重要。

    class String{
    private:
    	cha* data;
    	int len;
    	//...
    }
    
    String s = "jiangxuehan";
    

    下面的代码给s赋值时,s早就已经有一个值了(默认构造函数)。在赋值时,s必须要放弃旧值占用的内存。

    String s;
    s = "jiangxuehan"
    

    原则上我们没有必要划清两者的界限,可以在初始化后紧跟一个析构操作,这样会简化很多程序,但是会使某些类的抽象变得难以实现。

    例如

    有些C++的库提供了一种叫的类,如果某个对象包括了某种数据结构,通常我们可以创建一个指向该数据结构的某部分的片,给这个片赋值会影响原数据结构中的被选中的那部分。

    String s = "the dog";
    s(4,3) = "cat";//s(m,n)表示从字符m开始的n个字符长的s的一片
    //s的值为"the cat"
    s(4,0) = "big, fluffy"
    //s的值为the big, fluffy cat
    

    如果赋值总是等价于紧跟初始化后的析构操作,那么此类的抽象就比较难实现。

    3.2 折中方案

    再有比如界面设计,C++中有很多都是给类设计提供简化的工具,帮助他们解决用户界面的问题。因此用C++设计类比用其他语言难得多,但是解决方案更广泛,给库设计者提供了更策略化的可能性,使他们能考虑的更多。精心设计的C++库会非常好用。

    大家都觉得设计一个优秀的变长字符串和复数类很困难,但是如果把这些东西补充到编译器中,那么会更加困难。因为用户很少有权利和能力去修改自己的编译器,更别提把这种改变移植到不同的编译器上。

    因此C++提供了一个折中的方案,它允许我们在无需改变编译器内部的工作模式,就能详细地定义抽象概念的具体行为。

    3.3 复杂度的守恒

    计算机系统复杂而有阶段性,如果忽略这种复杂性,并不能消除复杂性,而且通常要付出代价。

    例如计算3个浮点数相加的问题:

    double add(double x, double y, double z){
    	return x+y+z;
    }
    

    这段代码并不能对1020、-1020、1的所有排列提供精准的答案。1020+1和-1020将等于1020,1最终会被完全丢掉。

    解决这个问题时,我们可以处理或者忽略复杂性,如果决定处理,就要通过确保最精确的可能答案来完成这一点,如果忽略复杂性,那么复杂性会转移到用户那里。

    处理复杂问题的软件肯定要面对复杂性。有些语言假装复杂性不存在而忽略它,提供给用户一个干净整洁的接口,如果世界上有些地方不符合他们所设想的模型,就干脆忽略而不见,忽略掉。还有些语言则是将复杂性扔给用户(如果用户可能不管行,就赢得了博弈,这就是为什么那么多不完善的软件产品在尚不完善时就交付了)。

    C++采用的则是折中办法,它允许我们编写对操作环境实施最底层控制的程序,但也允许我们忽略大多数不重要的细节。为了更加灵活,它付出的代价更为庞大。(这就是生活

    灵活性对类库的设计者来说尤其宝贵,他们因此能给用户提供使用不同的抽象级的广泛应用领域的功能。长远看,抽象仍然是世界的最有力的工具。

    展开全文
  • HBase高性能复杂条件查询引擎

    万次阅读 多人点赞 2014-06-17 20:10:36
    该方案设计之初仅寄希望于通过二级索引提升查询性能,由于在前期架构时充分考虑了通用性以及对复杂条件的支持,在后来的演变中逐渐被剥离出来形成了一个通用的查询引擎。HBase在大数据领域的应用越来越广泛,成为...

    推荐:博主历时三年倾注大量心血创作的大数据平台架构与原型实现:数据中台建设实战一书已由知名IT图书品牌电子工业出版社博文视点出版发行,真诚推荐给每一位读者!点击重磅推荐:建大数据平台太难了!给我发个工程原型吧!了解图书详情,扫码进入京东手机购书页面!

     

    写在前面


    本文2014年7月份发表于InfoQ,HBase的PMC成员Ted Yu先生参与了审稿并于给予了肯定。该方案设计之初仅寄希望于通过二级索引提升查询性能,由于在前期架构时充分考虑了通用性以及对复杂条件的支持,在后来的演变中逐渐被剥离出来形成了一个通用的查询引擎。Ted Yu对“查询决策器”表示了关心,他指出类似的组件同时也是Phoenix, Impala用于支持SQL查询的核心组件,但是这类组件很难引入到HBase中,因为HBase专注于byte[]的操作。对此,方案在设计时避开了“SQL解析”和“在各种数据类型与byte[]之间进行转化”的棘手问题,而是使用了一组可以描述查询的Query API,这与Hibernate中提供Criteria接口的做法非常相似,在Hibernate中既支持HQL语句的查询又支持使用Criteria接口以编程方式描述的查询,对于我们来说选择类似后者的做法实现起来要快速和容易的多,而查询条件中的值在构造之初就以byte[]的形式传递,避免了决策器解析时的类型判定和转化问题。本文原文出处: http://blog.csdn.net/bluishglc/article/details/31799255 严禁任何形式的转载,否则将委托CSDN官方维护权益!

    题记

    ——索引的实质是另一种编排形式的数据冗余,高效的检索源自于面向查询特别设计的编排形式,如果再辅以分布式的计算框架,就可以支撑起高性能的大数据查询。

    正文

    Apache HBase™是一个分布式、可伸缩的NoSQL数据库,它构建在Hadoop基础设施之上,依托于Hadoop的迅猛发展,HBase在大数据领域的应用越来越广泛,成为目前NoSQL数据库中表现最耀眼,呼声最高的产品之一。像其他NoSQL数据库一样,HBase也有其适用范围,就应对复杂条件的查询来说,一般认为它并不是非常适合[i],熟悉HBase的开发人员对此应该有一定的体会,但是基于普遍的需求,开发者们希望HBase在保持高性能优势的同时能对复杂条件的查询给予一定的支持,而本文将要介绍的正是一种在HBase现行机制下以非侵入式实现的基于二级多列索引的高性能复杂条件查询引擎。

    问题

    目前HBase主要应用在结构化和半结构化的大数据存储上,其在插入和读取上都具有极高的性能表现,这与它的数据组织方式有着密切的关系,在逻辑上,HBase的表数据按RowKey进行字典排序, RowKey实际上是数据表的一级索引(Primary Index),由于HBase本身没有二级索引(Secondary Index)机制,基于索引检索数据只能单纯地依靠RowKey,为了能支持多条件查询,开发者需要将所有可能作为查询条件的字段一一拼接到RowKey中,这是HBase开发中极为常见的做法,但是无论怎样设计,单一RowKey固有的局限性决定了它不可能有效地支持多条件查询。通常来说,RowKey只能针对条件中含有其首字段的查询给予令人满意的性能支持,在查询其他字段时,表现就差强人意了,在极端情况下某些字段的查询性能可能会退化为全表扫描的水平,这是因为字段在RowKey中的地位是不等价的,它们在RowKey中的排位决定了它们被检索时的性能表现,排序越靠前的字段在查询中越具有优势,特别是首位字段具有特别的先发优势,如果查询中包含首位字段,检索时就可以通过首位字段的值确定RowKey的前缀部分,从而大幅度地收窄检索区间,如果不包含则只能在全体数据的RowKey上逐一查找,由此可以想见两者在性能上的差距。

    受限于单一RowKey在复杂查询上的局限性,基于二级索引(Secondary Index)的解决方案成为最受关注的研究方向,并且开源社区已经在这方面已经取得了一定的成果,像ITHBase、IHBase以及华为的hindex项目,这些产品和框架都按照自己的方式实现了二级索引,各自具有不同的优势,同时也都有一定局限性,本文阐述的方案借鉴了它们的一些优点,在确保非侵入的前提下,以高性能为首要目标,通过建立二级多列索引实现了对复杂条件查询的支持,同时通过提供通用的查询API,以及完全基于配置的索引结构,完全封装了索引的创建和使用细节,使之成为一种通用的查询引擎。

    原理

    “二级多列索引”是针对目标记录的某个或某些列建立的“键-值”数据,以列的值为键,以记录的RowKey为值,当以这些列为条件进行查询时,引擎可以通过检索相应的“键-值”数据快速找到目标记录。由于HBase本身并没有索引机制,为了确保非侵入性,引擎将索引视为普通数据存放在数据表中,所以,如何解决索引与主数据的划分存储是引擎第一个需要处理的问题,为了能获得最佳的性能表现,我们并没有将主数据和索引分表储存,而是将它们存放在了同一张表里,通过给索引和主数据的RowKey添加特别设计的Hash前缀,实现了在Region切分时,索引能够跟随其主数据划归到同一Region上,即任意Region上的主数据其索引也必定驻留在同一Region上,这样我们就能把从索引抓取目标主数据的性能损失降低到最小。与此同时,特别设计的Hash前缀还在逻辑上把索引与主数据进行了自动的分离,当全体数据按RowKey排序时,排在前面的都是索引,我们称之为索引区,排在后面的均为主数据,我们称之为主数据区。最后,通过给索引和主数据分配不同的Column Family,又在物理存储上把它们隔离了起来。逻辑和物理上的双重隔离避免了将两类数据存放在同一张表里带来的副作用,防止了它们之间的相互干扰,降低了数据维护的复杂性,可以说这是在性能和可维护性上达到的最佳平衡。

    图1:Sample表Region 1的数据逻辑视图

    让我们通过一个示例来详细了解一下二级多列索引表的结构,假定有一张Sample表,使用四位数字构成Hash前缀[ii],范围从0000到9999,规划切分100个Region,则100个Region的RowKey区间分别为[0000,0099],[0100,0199],……,[9900,9999],以第一个Region为例,请看图1,所有数据按RowKey进行字典排序,自动分成了索引区和主数据区两段,主数据区的Column Family是d,下辖q1,q2,q3等Qualifier,为了简单起见,我们假定q1,q2,q3的值都是由两位数字组成的字符串,索引区的Column Family是i,它不含任何Qualifier,这是一个典型的“Dummy Column Family“,作为区别于d的另一个Column Family,它的作用就是让索引独立于主数据单独存储。接下来是最重要的部分,即索引和主数据的RowKey,我们先看主数据的RowKey,它由四位Hash前缀和原始ID两部分组成,其中Hash前缀是由引擎分配的一个范围在0000到9999之间的随机值,通过这个随机的Hash前缀可以让主数据均匀地散列到所有的Region上,我们看图1,因为Region 1的RowKey区间是[0000,0099],所以没有任何例外,凡是且必须是前缀从0000到0099的主数据都被分配到了Region 1上。接下来看索引的RowKey,它的结构要相对复杂一些,格式为:RegionStartKey-索引名-索引键-索引值,与主数据不同,索引RowKey的前缀部分虽然也是由四位数字组成,但却不是随机分配的,而是固定为当前Region的StartKey,这是非常重要而巧妙的设计,一方面,这个值处在Region的RowKey区间之内,它确保了索引必定跟随其主数据被划分到同一个Region里;另一方面,这个值是RowKey区间内的最小值,这保证了在同一Region里所有索引会集中排在主数据之前。接下来的部分是“索引名”,这是引擎给每类索引添加的一个标识,用于区分不同类型的索引,图1中展示了两种索引:a和b,索引a是为字段q1和q2设计的两列联合索引,索引b是为字段q2和q3设计的两列联合索引,依次类推,我们可以根据需要设计任意多列的联合索引。再接下来就是索引的键和值了,索引键是由目标记录各对应字段的值组成,而索引值就是这条记录的RowKey。

    现在,假定需要查询满足条件q1=01 and q2=02的Sample记录,分析查询字段和索引匹配情况可知应使用索引a,也就是说我们首先确定了索引名,于是在Region 1上进行scan的区间将从主数据全集收窄至[0000-a, 0000-b),接着拼接查询字段的值,我们得到了索引键:0102,scan区间又进一步收窄为[0000-a-0102, 0000-a-0103),于是我们可以很快地找到0000-a-0102-0000|63af51b2这条索引,进而得到了索引值,也就是目标数据的RowKey:0000|63af51b2,通过在Region内执行Get操作,最终得到了目标数据。需要特别说明的是这个Get操作是在本Region上执行的,这和通过HTable发出的Get有很大的不同,它专门用于获取Region的本地数据,其执行效率是非常高的,这也是为什么我们一定要将索引和它的主数据放在同一张表的同一个Region上的原因。

    架构

    在了解了引擎的工作原理之后来我们来看一下它的整体架构:

    图2:引擎的整体架构

    引擎构建在HBase的Coprocessor机制之上,由Client端和Server端两部分构成,对于查询而言,查询请求从Client端经由HTable的coprocessorExec方法推送到所有的RegionServer上,RegionServer接收到查询请求后使用“查询决策器”分析查询条件,比对索引元数据,在找到适合该查询的最优索引后,解析索引区间,然后委托“索引查询器”基于给定的最优索引和解析区间进行数据检索,如果没有找到合适的索引则委托“全表查询器”进行全表扫描。当各RegionServer的局部查询结果返回之后,引擎的Client端还负责对它们并进行合并汇总和排序,从而得到最终的结果集。对于插入而言,当主数据试图写入时会被Coprocessor拦截,委托“索引构造器”根据“索引配置文件”创建指向当前主数据的所有索引,然后一同插入到数据表中。

    让我们来深入了解一下引擎的几个核心组件。对于引擎的客户端来讲,最重要的组件是一套用于表达复杂查询请求的Query API,在这套API的设计上我们借鉴了IHBase的一些做法,通过对查询条件(Condition)进行抽象和建模,得到一套典型的基于“复合模式”(Composite Pattern)的Class Hierarchy,使之能够优雅地表达基于AND和OR的多重复合条件。以图1所示的Sample表为例,使用Query API构造一个查询条件为“(q1=01 and q2<02) or (q1=03 and q2>04)”的Java代码如下:

    图3:引擎客户端的Query API示意代码

    查询请求到达Server端以后,由Coprocessor委派查询决策器进行分析以确定使用何种查询策略应对,这是查询处理流程上的一个关键结点。查询决策器需要分析查询请求的各项细节,包括条件字段、排序字段和排序,然后和索引的元数据进行比对找出性能最优的索引,有时候对于一个查询请求可能会有多个适用索引,但是查询性能却有高下之分,因此需要对每一个候选索引进行性能评估,找出最优者,性能评估的方法是看哪个索引能最大限度地收窄检索区间。索引的元数据来自于索引配置文件,图4展示了一份简单的索引配置,配置中描述的正是图1中使用的索引a和b的元数据,索引元数据主要是由索引名和一组field组成,filed描述的是索引针对的目标列(ColumnFamily:Qualifier)。实际的索引配置通常比我们看到的这份要复杂,因为在生成索引时有很多细节需要通过索引配置给出指引,比如如何处理不定长字段,目标列使用正序还是倒序(例如时间数据在HBase中经常需要按补值进行倒序处理),是否需要使用自定义格式化器对目标列的值进行格式化等等,完全配置化的索引元数据使创建和维护索引的成本大大降低,为上层应用根据实际需求灵活设计索引提供了保障。

    图4:一份简单的索引配置文件

    在确定最优索引之后,查询决策器开始基于最优索引对查询条件进行解析,解析的结果是一组索引区间,区间内的数据未必都满足查询条件,但却是通过计算所能得到的最小区间,索引查询器就在这些区间上进行检索,通过配备的专用Filter对区间内的每一条数据进行最后的匹配判断。图5展示了一个条件为q1=01 and 01<=q2<=03的查询请求在Sample表Region 1上的解析和执行过程。

     

    图5 :查询请求q1=01 and 01<=q2<=03在Sample表Region 1上的解析和执行过程示意

    对于那些找不到索引的查询请求来说,查询决策器将委派全表查询器处理,全表查询器将跳过索引区,从主数据区开始通过配备的专用Filter进行全表扫描。显然,相对于索引查询,全表扫描的执行效率是很低的,它的存在是为了在所有索引都不适用的情况下起“托底”作用,以此保证任意复杂条件的查询都能得到处理,所以这里引出一个非常重要的问题,就是在索引查询和全表扫描之间的选择与权衡问题。通常人们总是希望所有的查询都越快越好,虽然从理论上讲建立覆盖任意条件查询的索引是可能的,但这是不现实的,因为创建索引是有代价的,除了占用大量的存储空间之外还会影响到数据插入的性能,所以不能无节制地创建索引,理性的做法是分析并筛选出最为常用的查询,针对这些查询建立相应的索引,优化查询性能,而对于那些较为“生僻”的查询则使用全表扫描的方式进行处理,以此在存储成本、插入性能和查询性能之间找到一种理想的平衡。最后要补充说明的是,不管是使用索引查询还是进行全表扫描,这些动作都是通过Coprocessor机制分发到所有Region上去并发执行的,即使是全表扫描其性能也将远超过HBase原生的Scan操作!

    应用

    由于引擎设计之初就以非侵入性为前提,所以引擎的部署与集成就与引入第三方类库无异,唯一需要上层应用提供的是面向数据表的索引配置文件。设计索引主要以业务需求为导向,先分析并梳理出常用的查询用例,然后针对查询用例所涉及的字段和排序要求按相似性进行分组,尽可能让单个索引同时支持多种相近的查询,减少索引的种类和数量,提升索引复用率。在这方面如下设计原则可供参考(注:以下原则均以“不考虑排序”为前提):

    • N个字段组合的查询只需要建立一个包含该N个字段的索引,建立按这个N字段其他顺序排列的索引是没有意义的。因此,以N个字段组合为条件的查询只需要C(n, n)=1个索引。
    • 一个包含N个字段的索引同时是以从第1到第N-1个字段为条件的查询索引,以及从第1到第N-2个字段为条件的查询索引,依此类推,也是仅以第1个字段为条件的查询索引。因此,包含N个字段的索引总计可以支持C(n,1)=n种查询组合。
    • 基于上述两点,任意一个索引的字段组合不应该是另一个索引字段组合的前缀部分,这样设计的索引才会有较高的复用率。

    假如某表有A、B、C、D四个字段,在不考虑排序的前提下,如果要用索引支持以任意字段或字段组合为条件的查询,则索引的设计方法如下:四字段索引只需要一个,假定取ABCD(它将同时支持ABCD、ABC、AB和A四种查询)。三字段索引分别以A、B、C、D开头向后循环取足三个字段,得到:ABC、BCD(它将同时支持BCD、BC和B三种查询)、CDA(它将同时支持CDA、CD和C三种查询)和DAB(它将同时支持DAB、DA和D三种查询),其中ABC是ABCD的前缀,故舍弃。按照同样的方法,两字段索引要分别从保留下来的三个三字段索引中依次以每一个字段开头取足两个字段,然后去除重复和前缀重叠的索引,最终得到DB(它将同时支持DB和D两种查询)和AC(它将同时支持AC和A两种查询),总计是6个索引,最后可以再根据实际需求剪裁掉不需要的索引。

    在上述原则的表述中特别注明了“不考虑排序“这个前提,对于索引来说,”排序“是一个很“敏感”的要求,索引本身只有一种排序(即按索引首字段进行的字典排序),如果查询请求的排序与索引排序不同,则索引直接出局,即使它们的字段完全匹配,也就是说排序会极大地消弱索引的复用度,对于我们的引擎来说,排序字段应该受到严格的控制。实际上,很多大数据系统都需要对排序进行限制,比如淘宝上的商品检索,可供排序的字段只有人气,销量,信用和价格,因为排序需要针对数据全集进行计算,如果不是针对有限的排序字段建立索引或是离线计算并缓存结果,按任意字段排序的查询是很难在线返回的。

    小结

    综合前文所述,方案主要有如下几个显著的优势:

    •  高性能:引擎的高性能源自两方面,一是二级多列索引,二是基于Coprocessor的并行计算
    • 非侵入性:引擎构建在HBase之上,既没有对HBase进行任何改动,也不需要上层应用做任何妥协
    • 高度可配置:索引元数据是完全基于配置的,可以轻便灵活地创建和维护索引
    • 通用性:引擎的前端查询接口和后端索引处理都是基于通用目标设计的,不依赖于任何具体表

    限于HBase自身的特点,方案本身也有一定的局限性,一是它不能随意地支持任意的条件查询,这一点前文已经给出了分析和建议,二是在插入主数据时需要伴随插入多份索引从而对写入性能产生了一定的影响,如何控制写入和查询的竞争关系需要根据系统的读写比进行权衡,对于数据写入实时性要求不高或者数据是离线导入的系统来说,可以考虑使用批量导入工具,特别是以直接生成HFile的方式导入的话可以在很大程度上消除引入索引后的写入压力。


    [i]理论上基于HBase的 Filter机制可以实现任意复杂条件的查询,但是那样做就彻底放弃了RowKey作为索引的利用价值,大多数查询的性能都将变得非常差。

    [ii]Hash前缀的长度和Region数量有着密切的关系,由于索引和主数据的分配高度依赖RowKey前缀和Region的RowKey区间,引擎严禁Region进行自动切分,开发人员需要在前期对Region数量和前缀长度进行规划,本例中取四位前缀意味着最多可以支持10000个Region。

    相关阅读:

    OpenTSDB设计解读

    HBase Block Cache的重要实现细节和In-Memory Cache的特点

    关于近期HBase系统设计开发和性能调优的一些小结

    Hadoop源码解析之: HBase Security

     

     

     

    展开全文
  • 复杂网络

    千次阅读 2018-09-06 13:54:36
    NetworkX是一个用Python语言开发的图论与复杂网络建模工具,内置了常用的图与复杂网络分析算法,可以方便的进行复杂网络数据分析、仿真建模等工作。networkx支持创建简单无向图、有向图和多重图(multigraph);内置...

    NetworkX是一个用Python语言开发的图论与复杂网络建模工具,内置了常用的图与复杂网络分析算法,可以方便的进行复杂网络数据分析、仿真建模等工作。networkx支持创建简单无向图、有向图和多重图(multigraph);内置许多标准的图论算法,节点可为任意数据;支持任意的边值维度,功能丰富,简单易用。

    1.安装networkx包

    2.

    G = nx.Graph()                 #建立一个空的无向图G
    G.add_node(1)                  #添加一个节点1
    G.add_edge(2,3)                #添加一条边2-3(隐含着添加了两个节点2、3)
    G.add_edge(3,2)                #对于无向图,边3-2与边2-3被认为是一条边
    print "nodes:", G.nodes()      #输出全部的节点: [1, 2, 3]
    print "edges:", G.edges()      #输出全部的边:[(2, 3)]
    print "number of edges:", G.number_of_edges()   #输出边的数量:1

    有向图:

    G = nx.DiGraph()
    G.add_node(1)
    G.add_node(2)
    G.add_nodes_from([3,4,5,6])
    G.add_cycle([1,2,3,4])
    G.add_edge(1,3)
    G.add_edges_from([(3,5),(3,6),(6,7)])

    有向图转无向图与无向图转有向图:

    • Graph.to_undirected()
    • Graph.to_directed()

    加权图:

    有向图和无向图都可以给边赋予权重,用到的方法是add_weighted_edges_from,它接受1个或多个三元组[u,v,w]作为参数,其中u是起点,v是终点,w是权重

     

     

    3.以中医方向为例

    例如构建中医方剂网络:方剂学是研究中药方剂租房、变化和临床应用规律的一门学科,主要包括方剂组成的原则、使用及变化等。中药方剂学网络的构建主要有中药-中药、中药-方剂以及方剂-方剂三种。中药-中药网络中将方剂中每一味药抽象为节点,根据是否在同一方剂中确定各味药节点之间是否存在边关联,因此由不同方剂抽象出的完全图相互关联,进而形成中药复杂网络。

    中药-方剂网络构建则将单味药及方剂分别作为节点,根据单味药与方剂的从属关系进行关联。

    方剂-方剂网络则视方剂为节点,根据不同方剂间是否存在同味药进行关联

     
























     

    展开全文
  • bpmn复杂网关

    万次阅读 2020-06-30 17:50:02
    本文章主要讲解了工作流中的复杂网关,系列文章中包含工作流、工作流系统、工作流引擎的相关讲解,涉及的到Camunda BPM、BPMN规范、activit的基础性知识,对于流程自动化、业务流程等进行了深入研究探讨。

    2.复杂的网关

    复杂网关是一个不同的类别。虽然它不常被使用,但在某些情况下它的使用是合理的。例如:我们想要订披萨。我们仔细阅读我们最喜欢的供应商的菜单。在研究了两种来源之后,一旦我们找到了想要的东西,就会开始。

    我们如何建立模型呢?图2.1展示只有对两个源对比研究之后才订购比萨饼。

    图2.1披萨研究与合并。

    在图2.2中,两者都不是选项:基于令牌概念,我们将执行两次订披萨的任务。

    图2.2:使用xor合并的披萨研究。

    图2.3中的or合并也没有解决这个问题:当一个令牌到达or合并时,流程会等待可能永远不会到达相应的令牌那里。or合并行为因此与and网关相同。

    图2.3:披萨研究与或合并。

    解决方案是结合注释的复杂网关,如图2.4所示。一旦其中一个任务完成,复杂的合并就会将令牌发送披萨订单的任务。当下一个令牌到达复杂合并时,它被消耗。它就消失了。

    图2.4:具有复杂合并的披萨研究。

    下面是类似的情况:假设我们一次执行四个任务。第5个任务将在前四个任务中的3个完成后执行。例如,我们问四个朋友他们想在哪家披萨店点餐。一旦三位朋友提出了意见,我们就会做出决定。我们可以用一个复杂的网关来建模我们的同步行为。(参见图2.5。)

    图2.5:使用复杂网关实现n个合并中的m个。

    原则上,一个复杂的网关也可以作为分割来应用,例如,将几个不同的网关汇总在一个符号中,以节省一些空间。通过在注释中编写分割语义,可以用一个复杂的网关替换分离出来的or。但这并没有真正意义,而且我们从来没有将复杂网关用作分割,也没有在任何实际模型中看到过它的使用。


    本文会持续更新,欢迎关注,技术支持:盘古BPM 

    展开全文
  • easyexcel 复杂表头、动态表头、复杂数据导出easyexcel 生成动态复杂表头+数据填充实现代码生成效果图 easyexcel 生成动态复杂表头+数据填充 实现代码 @Test public void test() throws IOException { // 文件...
  • 技术之巅|抛开复杂框架,快速实现一个具备oauth2.0功能的服务
  • MySQL常用SQL(含复杂SQL查询)

    万次阅读 多人点赞 2018-04-09 08:26:59
    1、复杂SQL查询 1.1、单表查询 (1)选择指定的列 [例]查询全体学生的学号和姓名 select Sno as 学号,Sname as 姓名 from student; select Sno,Sname from student; (2)查询全部列 [例]查询全体学生的详细...
  • 06-Spring复杂对象的创建

    万次阅读 2020-11-01 11:15:09
    什么是复杂对象? 不能通过new的方式创建出来的对象就是复杂对象。 下面试对简单对象和复杂对象的说明,这样的话对简单对象和复杂对象就有了具体的认识。这里非常重要。学习一定要有调性,有节奏,这样掌握起来就...
  • 复杂网络分析总结

    万次阅读 多人点赞 2018-04-08 15:31:40
    复杂网络的特点2. 社区检测3. 结构平衡4. 影响最大化5. 网络传播6. 补充7. 参考文献 在我们的现实生活中,许多复杂系统都可以建模成一种复杂网络进行分析,比如常见的电力网络、航空网络、交通网络、计算机网络...
  • 复杂性思维第二版 一、复杂性科学

    万次阅读 2017-10-27 21:44:26
    一、复杂性科学 原文:Chapter 1 Complexity Science 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 这本书的论点是,复杂性科学是一种“新型科学”,我借鉴自 Stephen Wolfram。2002年,Wolfram ...
  • 复杂网络的研究

    千次阅读 2018-11-04 21:53:53
    1. 复杂网络定义 : 复杂网络概念最开始的时候是相对于规则网络和随机网络提出来的,即介于规则网络和随机网络之间的网络都可以称之为复杂网络。—狭义的复杂网络 从广义上说,任何网络都可以称之为复杂网络,...
  • 复杂网络综述

    万次阅读 多人点赞 2016-11-05 09:44:55
    本人毕业设计是关于复杂网络的,之前完全没听说过的概念,于是就在网上找了一些论文来看,顺便做下笔记,这篇文章主要讲了复杂网络的一些基础概述。 这里的网络不是(不仅仅是)计算机网络这门课中的网络,它表示的...
  • 一文读懂复杂网络(应用、模型和研究历史)

    万次阅读 多人点赞 2018-05-02 09:40:05
    摘要:随着近几年关于复杂网络(Complex network)理论及其应用研究的不断深入,已有大量关于复杂网络的文章发表在Science,Nature,RL,NAS等国际一流的刊物上,侧面反映了复杂网络已经成为物理界的一个新兴的研究...
  • RecycleView 实现复杂首页布局三种方式

    千次下载 热门讨论 2016-04-08 11:40:21
    RecycleView 实现复杂首页布局三种方式:嵌套、自定义布局管理器、三方控件。实现效果如淘宝,美团,bilibili等
  • Layui复杂表格

    千次阅读 2019-06-08 01:24:28
    常见的表格只有一行表头的,但我们今天做一个复杂表格,先看看单表头的效果,等一会写完复杂表格再看复杂的表格。 把控制器搭建好了就开始写页面的代码,这里要把layui表格用到的css、js插件拷贝到项目,然后显示...
  • 复杂网络概述

    千次阅读 2017-11-28 09:47:46
    复杂网络概述 1研究背景 通信网络、电力网络、生物网络、和社会网络等分别是通信科学、电力科学、生命科学、和社会学等不同学科的研究对象,而复杂网络理论所要研究的则是各种看上去互不相同的复杂网络之间的共性...
  • 复杂链表的复制

    万次阅读 2020-02-21 14:46:06
    复杂链表的复制题目描述题目分析哈希表法python代码节点分裂法代码总结   自己在看书的过程中学到的一种套路,事实上一开始也都没想到,所以在这里总结一下。 题目描述   输入一个复杂链表(每个节点中有节点值...
  • 常见复杂网络分析方法

    千次阅读 2019-09-18 15:38:07
    常见的复杂网络分析方法基本分析方法关联分析方法 注:本文部分内容来自《复杂网络分析与应用》与《中国航空复杂网络的结构特征与应用分析》 1.赵正旭,郭阳,等.复杂网络分析与应用[M]北京:科学出版社,2018. 2.陈...
  • 复杂问题简单化以及简单问题复杂化并不矛盾,而是在项目的不同阶段。  在项目设计阶段,要考虑的是“简单问题复杂化”。说的通俗点,就是在给定需求的基础上尽量扩展,考虑更多的可能,做尽可能大的设计,来...
  • 【计算机笔记】Java 复杂链表的复制

    万次阅读 2019-12-16 21:45:35
    35. 复杂链表的复制 题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的 head。 public class RandomListNode { ...
  • java解析复杂json数据

    万次阅读 热门讨论 2018-10-27 18:15:56
    java如何解析复杂的json数据 关于json处理的包有好几个,比如jackson、Gson、Fastjson。Gson是谷歌做的,功能强大;Fastjson是阿里巴巴做的,性能更快。具体用哪个,开心就好。我这里两个都没用,用的是java的一个...
  • C++ Qt进阶之复杂控件自定义

    千人学习 2019-05-05 13:36:47
    写出高质量,复杂的交互?这是困扰很多中高级开发人员,很头疼的一个问题。在这个课程中,我们会给出非常好的答案。 为什么很多同学学了很多年编程,看了很多书,教程,还是不会写,只能在网络上copy代码?或者自己...
  • mysql 复杂排序

    千次阅读 2018-08-16 23:29:48
    目前工作遇到的比较复杂排序如下: 排序一, 表A中某个字段,按指定的顺序排列。不是简单的升序或者降序 例如 某部门表department 有如下数据 员工表employee 有如下数据 目前,需要将员工信息 按照 软件部...
  • 复制复杂链表

    千次阅读 2016-06-25 00:58:44
    什么是复杂链表???  如图,这是一个复杂链表,每个结点包含两个指针域,其中next指针域相互连接构成一个单链表,而另一个指针域Sibling则随意指向链表中的任意位置,或者指向NULL。 复制复杂链表!...
  • markdown中编辑复杂表格

    万次阅读 2018-07-13 16:32:12
    markdown中编辑复杂表格 使用markdown自带语法 markdown中自带了基本的表格编辑语法: 如: | name | age | gender | money | |-------|:---:|-----------|-------:| | rhio | 384 | robot | $3,000 | | ...
  • 复杂网络】自学笔记整理

    千次阅读 2020-06-29 17:15:45
    一、复杂系统与复杂网络 1.研究目的        复杂网络是研究复杂系统的一种角度和方法,它主要关注系统中个体相互关联的作用。(一种拓扑结构) 2.当今应用    &...
  • 设置复杂又好记的密码

    万次阅读 2019-07-05 17:38:57
    那么怎么才能设计一个复杂又好记的密码呢? 方法要简单,规则单一,否则就不好记了。我的方法就是用一句话的首字母再做适当变换即可。首先选择一些诗词或者名人名言,每个字首字母合在一起,再将语句中的数字拼音首...
  • 复杂网络简单理解

    万次阅读 多人点赞 2017-11-28 09:42:18
    通俗易懂的复杂网络 1 什么是复杂网络 1.1 直观理解 什么是复杂网络?对普通人而言,在媒体上看到复杂网络,首先想到的是互联网,实际上网络已经成为Internet的代名词,确实Internet从只有几个结点的简单的网络,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,500,928
精华内容 1,400,371
关键字:

复杂