精华内容
下载资源
问答
  • SMILES化学式解析

    千次阅读 2019-01-16 13:41:23
    解析和匹配 一,建立对象 (一)键 package com.Demo2; import java.util.ArrayList; public class ChemicalKey { //键的名称 private String key; //键的指向的对象 private ArrayList&...

    解析和匹配

    一,建立对象

    (一)键
    package com.Demo2;
    
    import java.util.ArrayList;
    
    public class ChemicalKey {
        //键的名称
        private String key;
        //键的指向的对象
        private ArrayList<ChemicalElement> chemicalElements;
        public static String[] allKeys;
        //构造函数
        public ChemicalKey(String key) {
            this.key = key;
            chemicalElements = new ArrayList<ChemicalElement>(2);
        }
    
        /**键,两边的元素
         * @param
         */
        public void setTarget(ChemicalElement target1,ChemicalElement target2) {
            try{
                chemicalElements.add(target1);
                chemicalElements.add(target2);
            }catch (Exception e){
                System.out.println("键连接的元素超过2个了!");
            }
        }
        //获得键两边元素
        public ArrayList<ChemicalElement> getChemicalElements() {
            return chemicalElements;
        }
        public void print(){
            for(int i=0;i<2;i++){
                System.out.print(chemicalElements.get(i).getLabel());
                System.out.print('-');
            }
            System.out.println();
        }
       //把一些常见的键,存起来,String形式,不是对象
        private static void  SetterAllKeys(){
            allKeys = new String[6];
            allKeys[0]=".";
            allKeys[1]="-";
            allKeys[2]="=";
            allKeys[3]="#";
            allKeys[4]="/";
            allKeys[5]="\\\\";
        }
    
        public String getKey() {
            return key;
        }
    
        /**获得所有的Key字符
         * @return
         */
        public static String[] getAllKeys(){
            SetterAllKeys();
            return allKeys;
        }
    }
    
    (二)元素

    每个元素都是独立的对象,元素有属性:1,元素名字 label 2,元素的临近的元素environments_2 3,临近元素相应的键keys_2
    其他为了方便设置的 4,元素的整体序号 mark 5 所有元素的符号,string类型,6,断键
    缺少:离子键的带的电荷量

    package com.Demo2;
    
    import java.util.ArrayList;
    
    public class ChemicalElement {
        //元素名称
        private String label;
        //元素的整体序号
        private int mark;
        //周围的元素和相应的键
    
        private ArrayList<ChemicalElement> environments_2;
    
        private ChemicalKey[] Keys;
        private ArrayList<ChemicalKey> Keys_2;
        //是元素的个数
        public int count=0;
        private static String[] allElement;
        //断开的键的类型
        private ChemicalKey disconnectKey;
    
    
        public ChemicalElement(String label, int mark) {
            this.label = label;
            this.mark = mark;
            this.Keys = new ChemicalKey[4];
            this.Keys_2  =new ArrayList<>();
            this.environments_2 = new ArrayList<>();
        }
    
    
    
    
        //设置断键
        public void setDisconnectKey(ChemicalKey disconnectKey) {
            this.disconnectKey = disconnectKey;
        }
        //设置断键的数字,这里假设一个原SMILES表示最多一个断键
        public void setMark(int mark) {
            this.mark = mark;
        }
        /**添加key的方法,同时把键连接的元素也添加进去
         * @param key
         */
        public void addToKeys(ChemicalKey key,ChemicalElement ce){
            Keys_2.add(key);
            this.environments_2.add(ce);
    
        }
        //返回,list,周围的元素
        public ArrayList<ChemicalElement> getEnvironments_2() {
            return environments_2;
        }
    
        /**返回所有的键
         * @return
         */
        public ArrayList<ChemicalKey> getKeys_2() {
            return Keys_2;
        }
    
    //获得断键的序号,默认为0
        public int getMark() {
            return mark;
        }
    //获得断键信息
        public ChemicalKey getDisconnectKey() {
            return disconnectKey;
        }
        /**获得元素名称
         * @return
         */
        public String getLabel() {
            return new String(label);
        }
        //获得与之相连元素的键对象
        public ChemicalKey getKeyy(ChemicalElement ce){
    
            for(ChemicalKey ck:Keys_2){
                if(ck.getChemicalElements().contains(ce)){//某个键,包含这个元素,返回这个键的对象
                    System.out.println("!!!!!检测到元素在键:"+ck.getKey()+"中");
                    return ck;
                }
            }
            return null;
        }
    
    
        public static void main(String[] args) {
            ChemicalElement c1 = new ChemicalElement("H",0);
    
        }
    
        private static void SetAllElement(){
            allElement = new String[100];
            allElement[0]="C";
            allElement[1]="N";
            allElement[2]="O";
            allElement[3]="F";
            allElement[4]="Br";
            allElement[5]="Cl";
            allElement[6]="H";
            allElement[7]="S";
        }
        public static String[] getAllElement() {
            SetAllElement();
            return allElement;
        }
    
    }
    
    (三)化学式

    化学式,所有的元素(键信息在元素中)

    package com.Demo2;
    
    import java.util.ArrayList;
    
    public class ChemicalFormula {
        private ArrayList<ChemicalElement> Formula;
    
        /**
         * @return
         */
        public ArrayList<ChemicalElement> getFormula() {
            return Formula;
        }
    
        /**
         * @param formula
         */
        public void setFormula(ArrayList<ChemicalElement> formula) {
            Formula = formula;
        }
    }
    

    二,解析

    解析没有达到的一些地方:

    • Aromaticity 芳香环的结构识别。小写的字母表示 未识别
    • 离子键等带 [] 这个结构的
    • @符号,立体结构
    • 断键合并,默认是没有重复数字的如1212 ,像1111这种不行。
      简单说,本程序识别,仅仅是带括号,大些字母的那种
    Input:   String  s, //待解析的字符串
           Int  count, //当前解析的位置
    Parse(S,Position)   
    While(count<s长度){
    判断是不是断开的键——数字  
    判断是不是键——-=#.\/         
    判断是不是元素——CNOFSBrCl[]++
    判断是不是括号
       Parse(s',position')
       (出现括号“[”,将括号当成规模小一点的子问题,仍用这个方法。因此,这个方法要返回头元素,或者第一个元素;
    出现括号“]”,终结条件,返回头元素)
    }
    

    在这里插入图片描述

    package com.Demo2;
    
    import java.util.ArrayList;
    
    public class ParseChain {
        /**
         * 待解析的字符串对象
         */
        private String smiles;
    
        /**
         * 解析字符串的位置标记
         */
        private int position;
    
    
        /**
         * 解析后存放的位置
         * cmf:化学式存放
         * MyElements_2 以前的list存放
         */
        private ArrayList<ChemicalElement> MyElements_2;
        private ChemicalFormula cmf;
    
        /**MyElement 要删除的
         * 构造函数
         * @param smiles
         */
        public ParseChain(String smiles) {
            this.smiles = smiles.toUpperCase();
            String[] smilesList =this.smiles.split("");
            MyElements_2 = new ArrayList<ChemicalElement>();
            cmf = new ChemicalFormula();
        }
    
        
        public ArrayList<ChemicalElement> getMyElements_2() {
            return MyElements_2;
        }
    
        public ChemicalFormula getCmf() {
            return cmf;
        }
    
        public ChemicalElement Parsing(){
            String[] smilesList =this.smiles.split(""); //将字符串转成数组
            //第一步,完成图示解C步骤
            ChemicalElement st = subParsing(smilesList,null,null);
            //第二步,从C步骤,完成B步骤,对数字相同的进行拼凑;断键合并
            Combine();
            cmf.setFormula(MyElements_2);  //解析完,将元素存到化学键中
            return st;
        }
        private ChemicalElement subParsing(String[] smileList,ChemicalElement formerElement,ChemicalKey formerKey){
            //头元素,记录信息
            ChemicalElement start = null;
            while(position<smileList.length){
                System.out.print(smileList[position]);
                //是否是数字,表示断键
                if((position<smileList.length) && Character.isDigit(smileList[position].charAt(0))){
                    formerElement.setMark((int)smileList[position].charAt(0));  //旧-将数字加进去
                    formerElement.setDisconnectKey(formerKey);  //将断键的类型加上去
                    formerKey = new ChemicalKey("-");            //将标记键置为默认
                    position++;
                }
                //是键
                else if(isKey(smileList[position])){
                    formerKey = new ChemicalKey(smileList[position]);//将键对象保存
                    position++;
                }
                //是元素
                else if(isElement(smileList[position])){
                    ChemicalElement current=null;
                    if(smileList[position].equals("[")) {  //离子情形
                        ArrayList<String> Ion = new ArrayList<>();
                        for (int i = position; i < smileList.length; i++) {
                            if (smileList[position].equals("]")) {  //结束的情形
                                position++;
                                break;}
                            if (smileList[position].equals("[") || smileList[position].equals("+") || smileList[position].toUpperCase().equals("H")) {
                                continue;
                            }
                            Ion.add(smileList[position]);
                        }
                        current = new ChemicalElement(Ion.toString(), 0);
                    }else {
                        current = new ChemicalElement(smileList[position], 0); //旧-将元素添加进去
                    }
                    MyElements_2.add(current);         //新-将元素添加到MyElements_2
    
                    if(start==null){    //第一个元素
                        start=current;
                    }
                    if(formerElement==null){   //旧-前面是空的,第一个元素情形;此时,键也应该是空的
                        formerElement = current;
                        formerKey = new ChemicalKey("-");
                    }else {
    
                        //新 添加元素
                        formerKey.setTarget(current,formerElement); //键 ---(m,n)
                        formerElement.addToKeys(formerKey,current);  //元素---添加键
                        current.addToKeys(formerKey,formerElement);
    
                        //旧-更新前一个元素;更新键值
                        formerElement = current;
                        formerKey = new ChemicalKey("-");
                    }
                    position++;
                }
                   //括号内() 迭代,返回头元素
                else if(smileList[position].equals("(")){
                    //旧-此时第一个元素应该被外面的吸纳,其他的循环就好;此时前置的元素依然不能变,即使出现了)符号,这个也是不能变的。
                    position++;
                    //判断后面的元素是不是键,如果是,要提前存起来,更新。
                    if(isKey(smileList[position])){
                        formerKey = new ChemicalKey(smileList[position]);
                    }
                    ChemicalElement ce =  subParsing(smileList,null,null);
                    if(formerElement!=null){  //括号前面的部分处理
    
                        //新的添加方式
                        formerKey.setTarget(ce,formerElement);
                        formerElement.addToKeys(formerKey,ce);
                        ce.addToKeys(formerKey,formerElement);
                    }else{
                        formerElement = ce;
                        formerKey = new ChemicalKey("-");
                    }
                    //括号后面部分的处理
                    formerKey = new ChemicalKey("-");
                    position++;
                }
                else if(smileList[position].equals(")")){  //这里不对位置进行操作 留在109处理
                    // 但是要对formerkey做处理 留在109 循环出来后
                    return start;
                }
            }
            return start;
        }
    
        //判断是否是键
        String[] allKeys = ChemicalKey.getAllKeys();
        public boolean isKey(String element){
            for(String c:allKeys){
                if(element.equals(c)){
                    //  System.out.println("是键");
                    return true;
                }
            }
            return false;
        }
        //判断是否是元素  
        //两位的元素没搞,比如Br Cl
        String[] elements = ChemicalElement.getAllElement();
        public boolean isElement(String element){
            for(String s:elements){
                if(element.equals(s)){
                    //   System.out.println("是元素");
                    return true;
                }
                if(element.equals("[")){
                    return true;
                }
            }
            return false;
        }
    
        //将断开的键合起来
        // 断键信息1111 这种形式标记的 没搞
        private void Combine(){
            int maxNumber =0;
            for(ChemicalElement ce :MyElements_2){
                if(ce.getMark()>maxNumber)
                    maxNumber =ce.getMark();
            }
            for(int i=0;i<MyElements_2.size();i++){
                if(MyElements_2.get(i).getMark()!=0){
                    for(int j=i+1;j<MyElements_2.size();j++){
                        if(MyElements_2.get(i).getMark()==MyElements_2.get(j).getMark()){
                            MyElements_2.get(i).getDisconnectKey().setTarget(MyElements_2.get(i),MyElements_2.get(j));
                            MyElements_2.get(i).addToKeys(MyElements_2.get(i).getDisconnectKey(),MyElements_2.get(j));
                            MyElements_2.get(j).addToKeys(MyElements_2.get(i).getDisconnectKey(),MyElements_2.get(i));
                            break;
                        }
                    }
                }
            }
    
        }
    }
    
    

    三,匹配

    经过查资料,这是一个NP问题,属于图的同构问题。采用一个类似深度优先遍历加回溯的方案,算法叫VF算法。算法流程:
    在这里插入图片描述
    中文文章解释:(百度吧)
    1,SMILES表达式的子结构关系检测算法_彭彬
    2,VF算法在化学结构检索中的应用_李琰
    3,基于VF2算法的分子二维子结构检索_李欣
    英文原文:
    1,An_Improved_Algorithm_for_Matching_Large_Graphs
    2,(Sub)Graph Isomorphism Algorithm for Matching Large Graphs Luigi P. Cordella, Pasquale Foggia, Carlo Sansone,and Mario Vento
    过程主要设计的概念:

    • SSR 状态空间。上面说到这是一个图问题,所以深度遍历过程中会有一个解空间树。这个SSR状态空间,就是真正解的一个子集空间,用来记录路径的。
    • 候选状态集。 当进行到某个元素,这个候选状态集就是:接下来的所有的可选路径。
    • Feasibility Rules 。回溯的条件,对于问题,不满足一定条件,就回溯。
    package com.Demo2;
    
    import java.util.*;
    
    public class VFMatch {
        //query和db图   dbG=databaseGraph
        private ChemicalFormula quG;
        private ChemicalFormula dbG;
        //Ms用于存放空间状态点,也应该是个Map才对
        //由于匹配过程,一一对应,不会出现一对多,所以mapde 键是元素是可以的
        private Map<ChemicalElement,ChemicalElement> Ms;
    
        public VFMatch(ChemicalFormula quG, ChemicalFormula dbG) {
            this.quG = quG;
            this.dbG = dbG;
        }
    
        /**
         * @param state  临时的态
         * @param quG     query
         * @param dbG     dbG
         * @return         boolean
         */
        public boolean Match(HashMap<ChemicalElement,ChemicalElement> state, ChemicalFormula quG, ChemicalFormula dbG){
            boolean flag = false;
            //Mqu 已经在state中的query元素  Mdb 已经在state中的db元素
            Set<ChemicalElement> quG_Mid0 = state.keySet();
            ArrayList<ChemicalElement> Mqu = new ArrayList<>(quG_Mid0);
            Collection<ChemicalElement> dbG_Mid0 = state.values();
            ArrayList<ChemicalElement> Mdb= new ArrayList<>(dbG_Mid0);
            //IF M(S)cover all the nodes of G2
            if(Mqu.size()!=0 && Mqu.size()==quG.getFormula().size()){
                    System.out.println("到了最后+++++++++++++++++++++++++++++++++++++");
                    flag =  true;
            }else{
                //compute the candidate of inclusion of Ms
                Map<Integer,ArrayList<ChemicalElement>> P = new HashMap<>();
                CandidateP(P,quG,dbG,Mqu,Mdb);
                System.out.println("计算完成候选的结果");
                Set<Integer> entry = P.keySet();
                //Foreach p in P:
                for(int number:entry){
                    ChemicalElement que = P.get(number).get(0); //query
                    ChemicalElement dbe = P.get(number).get(1);  //db
                    //IF the feasibility rules succeed for inclusion of p in Ms
                    if(FeasibilityRules(que,dbe,Mqu,Mdb,state)){
                        //compute the state s'
                        state.put(que,dbe);  //添加进去
                        //call match(s')
                        flag = Match(state,quG,dbG);
                        state.remove(que);  //回溯,要删除之前的状态
                    }
                    if(flag==true){ 
                        break;//找到一个解,就返回解,不再探索
                    }
                }
                //从这里出来,就是说明没有那走到最后,所以返回
            }
            return flag;
        }
    
    
        /**搜索的空间P Candidate Pair Set
         * @param result 所有可能性集合容器
         * @param quG  query
         * @param bgG  database
         * @param Mqu  M_query
         * @param Mdb  M_database
         * @return
         * <1,<C,N>>  <2,<C,C>> ...
         */
        public void CandidateP(Map<Integer,ArrayList<ChemicalElement>> result, ChemicalFormula quG, ChemicalFormula bgG,
                                                               ArrayList<ChemicalElement> Mqu, ArrayList<ChemicalElement> Mdb){
            int count=0;
            for(ChemicalElement ce:quG.getFormula()){
                if(!Mqu.contains(ce)) {  //query元素没被选的元素
                    for (ChemicalElement qe : bgG.getFormula()) {
                        if(!Mdb.contains(qe)){ //db元素,没被选的元素
                            System.out.print(ce.getLabel()+"-"+qe.getLabel()+" ");
                            ArrayList<ChemicalElement> res = new ArrayList<>();
                            res.add(ce);
                            res.add(qe);
                            result.put(count,res);
                            count++;
                        }
                    }
                }
            }
        }
    
        /**
         * @param quG query
         * @param dbG dataBase
         * @param Mqu  已经加入的结点集合
         * @param Mdb
         * @param match 已经匹配好的对象
         * @return
         */
        public boolean FeasibilityRules(ChemicalElement quG,ChemicalElement dbG,ArrayList<ChemicalElement> Mqu,ArrayList<ChemicalElement> Mdb,
                                        Map<ChemicalElement,ChemicalElement> match){
    
            if(!quG.getLabel().equals(dbG.getLabel())){       //两个元素名称是否一致
                return  false;
            }
            if(quG.getEnvironments_2().size()>dbG.getEnvironments_2().size()){  //quG的度要小于等于dbG的度
                return false;
            }
            if(Mqu.size()==0){   //如果是第一对元素,
                System.out.println("   是第一个元素");
                return true;
            }
            //接下来检测,M中是否已经有跟quG相连的元素,如果相连,必须满足条件:
            //1)quG_vID和dbG_vID与已经match的那些节点对中的【至少】一对(quVid,dbVid)分别相邻(quG_vID和dbG_vID分别是已经match的节点quVid和dbVid的“neighbor节点”)
            //2)如果存在多个相邻对(quVid,dbVid),则必须要求【所有的】邻接边对( edge(quG_vID,quVid), edge(dbG_vID,dbVid) )的label一样
    
            for(ChemicalElement quG_Mid:Mqu){
                if(quG_Mid.getEnvironments_2().contains(quG)){ //quG_Mid是quG的连接元素  
                    ChemicalElement dbG_Mid = match.get(quG_Mid);  //映射的元素
                    if(!dbG_Mid.getEnvironments_2().contains(dbG)){  //映射元素dbG_Mid与dbG之间没有连接
                        return false;
                    }
                    /***
                     * 下面是需要改正的,键对象创建的太多了。
                     * 需要把键当成元素的属性,目前是元素是键的属性,用一个map比较好
                     */
                    if(!quG.getKeyy(quG_Mid).getKey().equals( dbG.getKeyy(dbG_Mid).getKey())){  //同一个键对象
                        return false;
                    }
                }
            }
            //从这里出来,
            //1)可能是不存在与Mqu相连接的情况,因此 return true
            //2) 存在于Mqu相连接的情况,且验证符合
            return true;
        }
    }
    
    
    展开全文
  • excel生成趋势线函数关系式

    万次阅读 2016-05-18 10:43:53
    本文以excel2007为例,演示下生成趋势线函数关系式的步骤。 1. 选择一组数据: 2. 选中这组数据,插入图表: 新插入的图表如下所示: 3. 选中图表中所有的数据点(数据点都要处于选中状态),右键...

    本文以excel2007为例,演示下生成趋势线和函数关系式的步骤。

    1. 选择一组数据:


    2. 选中这组数据,插入图表:


    新插入的图表如下所示:


    3. 选中图表中所有的数据点(数据点都要处于选中状态),右键-->添加趋势线:


    添加趋势线后的样子如下:



    4. 下面到了最关键的一步,选中趋势线(是趋势线不是数据点哦,选中后趋势线处于选中状态),右键-->设置趋势线格式:


    在弹出的对话框中选择曲线类型,并选中显示公式和显示R平方值:


    其中,公式为趋势线的函数表达式,R平方值表示这组数据和函数表达式的吻合度,它的值越接近1表示这组数据与公式越吻合。

    最终效果如下图所示:

    .


    展开全文
  • 根据基尔霍夫定律、交流等效电路,导出了并联负反馈放大器下限截止频率f的解析关系式。新关系式能直观、准确描述...显示出f解析式会因电路级间耦合电容的多少而有不同形式;证明了原关系式给出的实际上是一种模糊关系式
  • 产生规则Rete算法解析

    千次阅读 2018-03-13 19:10:20
    Rete可以发音为REH-te或者RAY-tay,在拉丁语中有“网络”的含义,Rete算法是Charles Forgy博士1974年发明的一个算法。后来成为了产生规则系统(Production Rule ...的形式表现了因果关系。这种形式的规则反映了...

        Rete可以发音为REH-te或者RAY-tay,在拉丁语中有“网络”的含义,Rete算法是Charles Forgy博士1974年发明的一个算法。后来成为了产生式规则系统(Production Rule System)的大脑。Drools就是基于产生式规则系统演化而来的。

    产生式规则

        产生式规则是一种常用的知识表示方法,它以"IF-THEN"的形式表现了因果关系。这种形式的规则反映了人类求解(一类?)问题的行为特征,可以通过循环的应用这些规则来解决问题。

    ……
    R3:IF 某动物是有蹄类动物 AND 有长脖子 AND 有长腿 AND 身上有暗斑点 THEN 该动物是长颈鹿(问题解决)
    R4:IF 某动物是有蹄类动物 AND 身上有黑色条纹 THEN 该动物是斑马(问题解决)
    ……
    R8:IF 动物是哺乳动物 AND 嚼反动物 THEN 该动物是有蹄类动物
    ……
    R10:IF 某动物有奶 THEN该动物是哺乳动物
    ……

        例如有以上一些产生式规则,给出"有奶"、"嚼反"、"长脖子"、"长腿"、"身上有暗斑点"条件(也称为事实 facts),就可以求解出问题的答案是“长颈鹿”。

        对于此类问题,自然想到的实现方法是逐条检查规则,但是如上面的例子,有些知识是在推理的过程中得到的,如“哺乳动物”、“蹄类动物”,而规则不一定按照理想的顺序排列,为了能解决问题,只能循环多次,直到解决问题。对于庞大的规则集,这样做显然效率是非常低的。Rete算法为产生式规则系统提供了非常高效的实现。

    产生式规则系统结构

        在介绍Rete算法之前,简单介绍以下产生式规则系统的结构。如图所示,规则存储于产生式内存(Production Memory),需要评估的事实(facts)被插入工作内存(Working Memory)中,在其中被修改或撤出。一个含有大量规则和事实的系统可能导致在一次事实评估中,多条规则为真,这种情形被称为冲突。代理(Agenda)将使用冲突解决策略管理冲突规则的执行顺序。


    Rete算法

        Rete算法可以分为规则编译和运行时执行两个部分,其中编译算法是Rete算法的精髓所在,描述了如何处理规则生成一个高效的鉴别网络(Discrimination network)。鉴别网络可以理解为用于过滤在其中传递的数据的网络。Forgy博士描述了Rete算法网络中的四类节点:


    • 根节点:所有对象进入网络的入口,在一个网络中只有一个根节点。
    • 单输入节点:可分为ObjectTypeNode, AlphaNode, LeftInputAdapterNode等。
    • 双输入节点:包含JoinNode和NotNode。JoinNode和NotNode也属于用于比较两个对象和其域的BetaNodes。
    • 终端节点:到达一个终端节点,表示单条规则匹配了所有的条件,网络中有多个终端节点。当单条规则中有or时,也会产生多个终端节点。

    ObjectTypeNode

    事实从根节点进入Rete网络后,会立即进入ObjectTypeNode节点,ObjectTypeNode提供了按对象类型过滤对象的能力,通过此类节点可使规则引擎不做额外的工作。如下图,Cheese类型的事实进入网络后,只需经过Cheese ObjectTypeNode之后的节点。

    AlphaNode

    AlphaNode节点的作用是评估字面的条件,如下图,评估了Cheese事实的name和strength属性值。AlphaNode之间是串行的,即只要其中一个节点不满足,事实就被过滤掉了。

    JoinNode和LeftInputAdapterNode

    如前所述,双输入节点JoinNode是一类BetaNode,BetaNode的输入被称作左输入和右输入,其中左输入通常是一个对象列表(元组),而右输入是一个单个对象,可以实现对象是否在列表中存在的检查。LeftInputAdapterNode的作用是输入一个对象,传播为一个单对象列表(元组)。如图所示,JoinNode的左输入为一个经过LeftInputAdapterNode传播后的列表,右输入为一个Person对象。

    Drools规则和Rete算法的例子

    // rule 1
    when
        Cheese( $cheddar : name == "cheddar" )
        $person : Person( favouriteCheese == $cheddar )
    then
        System.out.println( $person.getName() + " likes cheddar" );
    end
    // rule 2
    when
        Cheese( $cheddar : name == "cheddar" )
        $person : Person( favouriteCheese != $cheddar )
    then
        System.out.println( $person.getName() + " does not like cheddar" );
    end


        图示的Rete网络除了展示了代码块中的Drools规则,还体现了Rete算法中节点共享的特征,此特征减少了网络中结点的冗余。

    参考资料

    1. 产生式规则表示法

    2. 产生式表示法

    3. Drools官方文档

    4. Rete算法

    展开全文
  • 应用系统中交互报表功能解析

    千次阅读 2014-04-24 14:46:48
    从报表需求的整个发展历程来看,可以分为...2、交互报表:解决终端用户分析数据的需要,通常会用到数据可视化、向下钻取、贯穿钻取、数据过滤、数据排序等功能。这篇文章主要介绍交互报表中常用到的数据分析方法。

    从报表需求的整个发展历程来看,可以分为两个阶段:

    1、静态报表:解决显示、打印、导出报表数据的需要。

    2、交互式报表:解决终端用户分析数据的需要,通常会用到数据可视化、向下钻取、贯穿钻取、数据过滤、数据排序等功能。

    这篇文章主要介绍交互式报表中常用到的数据分析方法。

    (一) 数据可视化

    数据可视化技术是将数据以图形化的方式进行显示,让数据更易于阅读、理解和分析。早期的数据可视化以图表(Chart)为主,现代商业报表中逐渐加入迷离图(Sparkline)、数据条(Bullet)、图标集(Icon)、仪表盘(Gauge)、地图(Map)用于数据可视化,而数据可视化常用作交互式报表的基本载体。实现步骤

    image

    (二) 向下钻取

    向下钻取是根据终端用户的需求,动态的显示或隐藏报表数据,常用于汇总类型报表。向下钻取报表在设计模板时,所有的数据显示均在同一个报表内完成。在运行时,可以通过终端用户点击的操作来折叠或展开明细数据。实现步骤

    image

    (三) 贯穿钻取

    贯穿钻取是通过点击一级报表区域,跳转至二级报表的一种报表数据分析方式。报表设计时需要完成一级、二级两个报表的模板,并通过参数建立两级报表之间的关系。常见的一级报表可以使用交互式图表来实现,通过点击图表区域可以跳转至二级报表。实现步骤

    image (1)

    (四) 数据过滤

    动态过滤是在运行时为用户提供数据过滤的功能,用户可以根据自己的需要选择关系的数据进行查看。通过这种方式可更准确的提供用户关系的报表数据。常用的过滤分为单条件过滤、组合条件过滤、级联条件过滤。实现步骤

    image

    (五) 数据排序

    动态排序是为最终用户提供对报表数据排序的能力。虽然该功能在应用系统中经常用到,比如用表格显示数据时可以很方便的完成数据排序操作,但是,早期的静态报表中生成的报表不具备用户交互能力,所以,这也是现代商业报表中具有的一个功能。实现步骤

    image (3)

    展开全文
  • bootstrap响应布局特点以及解析

    万次阅读 2018-03-21 17:01:54
    一、bootstrap介绍当提到响应布局,我们脑子里会出现bootstrap的概念,它有哪些特点呢? (1)响应(@media媒体布局) (2)移动设备优先(meta name="viewport" content="width=device-width,...
  • Java之函数接口源码解析

    千次阅读 2020-09-28 20:23:17
    函数接口 只包含一个抽象方法的接口,称为函数接口。 你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)。 ...
  • Vue的响应原理(MVVM)深入解析

    万次阅读 2018-07-10 09:42:09
    如何实现一个响应对象 最近在看 Vue 的源码,其中最核心基础的一块就是 Observer/Watcher/Dep, 简而言之就是,Vue 是如何拦截数据的读写, 如果实现对应的监听,并且特定的监听执行特定的回调或者渲染逻辑的。总...
  • 偏光与快门3D液晶解析

    千次阅读 2012-02-26 20:41:45
     从前面的分析可以看到,主动快门式和偏振光两种3D技术优点缺点都比较鲜明,从画面质量层面看:由于分辨率关系,偏光3D技术的图像效果要比快门3D略差,不过偏光的3D显示器不会闪烁,画面稳定性更好。...
  • 很多事情无巧不成书,无意中在python交互式解析器中输入 import this,按回车,这回,结果大了。 什么情况?网上查了下,这个居然是圣经一般的东西。 以下译文抓自网络: Python之禅 下面是翻译解释: ...
  • 用 Java 实现组合式解析

    千次阅读 2010-06-28 13:50:00
    在本文中,我们将展示一个组合式解析器的设计、实现过程,最终的代码是优美的,极具扩展性,就像是为了解析特定的语法而存在的。我们还会选取 H.248 协议中的一个例子,用上述的组合式解析器实现其语法解析器。读者...
  • Android沉浸状态栏完全解析

    千次阅读 2016-08-23 07:31:08
    隐藏状态栏ActionBar的方式在4.1系统之上4.1系统之下还是不一样的,这里我就不准备考虑4.1系统之下的兼容性了,因为过于老的系统根本就没有提供沉浸体验的支持。 修改MainActivity中的代码,如下所示...
  • Wireshark中的名字解析

    千次阅读 2019-12-18 21:12:17
    在启发表TCP那一项中能够查询到Hypertext Transfer Protocol HTTP的对应关系,如图9: 图9 http报文在报文栏具体解析栏的可以看到存在一定的不同,如图10: 图10 即有的时候只会显示简写的HTTP,有...
  • 如需转载请注明出处:python–爬虫–获取和解析存储网页内容–以薄荷网为例 我们在之前的文章中已经学习了如何进行数据抓包截取 以及分析 访问网页。 例如: 抓取app数据教程–fiddler抓包数据截取-薄荷app为例 本章...
  • 实现折叠Toolbar:CollapsingToolbarLayout 使用完全解析

    万次阅读 多人点赞 2016-10-20 12:29:51
    大家可能会经常见到这样一个效果:Toolbar是透明的,有着一个背景图片以及大标题,随着页面向上滑动,其标题逐渐缩放到Toolbar上,而背景图片则在滑动到一定程度后变成了Toolbar的颜色,这种效果也即是折叠效果。...
  • 列表推导与字典推导,滚雪球学 Python

    千次阅读 多人点赞 2021-03-03 21:50:58
    列表推导、字典推导、集合推导、生成器初识
  • 解析搜索引擎检索的构建

    千次阅读 2006-10-22 01:06:00
    网络搜索中的关键词是一个广义的概念,属于非受控自由词,凡是具有实际意义的表达及其书写形式,如字、词、词组、短语字母、数字、符号、公式等,都可以用作搜索关键词。 网络搜索,实际上是在搜索引擎的索引...
  • 现在我们可以探究另一个非常重要的概念(行列)与线性方程组的解的情况之间的关系。 1 行列 首先,我们需要了解什么是行列。 行列,是一个相对于矩阵的概念,并且必须是方阵才有行列的概念。重要的话说三...
  • 分页存储管理中逻辑地址到物理地址的转换过程解析
  • 内存磁盘的关系

    千次阅读 2020-02-06 11:43:05
    文章目录内存磁盘的区别程序,内存磁盘的交互关系磁盘缓存缓存虚拟内存分页虚拟内存分段虚拟内存从代码编写角度来节约内存磁盘的物理结构固态硬盘 VS 传统硬盘固态硬盘 VS 内存经典提问环节 内存磁盘的...
  • Vue响应式和双向绑定的原理

    千次阅读 2019-03-06 23:33:48
    Vue.js的目标是通过尽可能简单的API实现响应的数据绑定组合的视图组件。(摘自百度百科)这段Vue的定义明确了Vue的几大特点:数据驱动、渐进、响应、组件化、声明渲染。 &nbsp;&nbsp;&nbsp;&...
  • 解析函数

    万次阅读 2018-11-22 12:46:44
    文章目录一、解析函数的概念学习目标1...函数可导与解析关系(一点与区域) 会判别函数的解析性 奇数的定义以及与不可导点的关系 会求函数的奇点 1、复变函数的导数     定义: 设函数 w=f(z)w=f(z)w=f...
  • 高中数学必修二平面解析几何重点介绍两直线的位置关系基础知识易误点,并用平面解析几何两直线3个经典习题2017年高考试题归纳与整理。 一、 基础知识 1、 两直线的平行、垂直与其斜率的关系 2.两条直线的交点 ...
  • 本系列其他文章见:《响应Spring的道法术器》。 前情提要:响应流 | lambda与函数 | Reactor快速上手 1.3.3 Spring WebFlux Spring WebFlux是随Spring 5推出的响应Web框架。 1)服务端技术栈 ...
  • 在最前面推荐一个大佬的讲解,真的很浅显易懂,建议先看了解大概PID:链接 什么是PID P:Proportion(比例),就是输入偏差乘以一个常数。...稳定性(PI降低系统稳定性,D提高系统稳定性):在平衡
  • 求 FIRSTVT 集 LASTVT 集的步骤及例题解析 算符优先关系表的构造中涉及到求 FIRSTVT 集 LASTVT 集。 表示及含义: FIRSTVT(T) 非终结符T的最左终结符集合 LASTVT(T) 非终结符T的最右终结符集合 定义:...
  • 日志自动分析和解析开源工具

    千次阅读 2019-12-18 17:03:42
    论文原文 https://arxiv.org/pdf/1811.03509.pdf 翻译原文 ... GitHub 日志解析:https://github.com/logpai/logparser ...自动日志分析的工具基准 ...Abstract——在许多软件系统的开发维护过程中,日志是...
  • 电商大数据——用数据驱动电商商业案例解析(国内第1本将大数据与电商完美结合的权威之作!) 雪鹰传奇 著  ISBN 978-7-121-22556-7 2014年3月出版 定价:98.00元 360页 16开 编辑推荐 (1)《电商...
  • Apriori算法解析

    万次阅读 2017-03-09 10:46:22
    背景介绍 维克多迈尔在《大数据时代》中,提出了大数据时代跟传统的信息时代相比,最本质的三个...相关关系,其实是数据中蕴含的最直接的知识,而对这种相关关系的挖掘,如今也早已应用到推荐系统,个性化检索,机器学

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 189,721
精华内容 75,888
关键字:

关系式和解析式一样吗