硬盘安装Fedora 9时死机?

前天晚上在Fedora9下装完ATI显卡的驱动以后,升级系统,昨天早晨起来一看,我的本本过热休眠了(发现Fedora下经常出现这种情况,而Windows下很少出现,可见Linux的电源管理确实还有问题),当时没有管它。

昨天晚上到了半夜,决定切换到Fedora下玩一玩,结果发现进不了图形界面了,字符界面也还闪来闪去的,实在没办法,重装。非常不幸的是,重装到一半的时候,CPU过热又歇菜了。

这时重启发现只能进grub控制台,无法进Windows了。顿时傻了。

今天早晨来实验室上网搜索修复MBR的方法,最简单的就是用Windows安装盘。拿出Win2003的盘插到光驱一试,没反应,My God!光驱又坏了!!!难道我辛辛苦苦好几年积攒的文档就眼看要人间蒸发付诸东流了吗?

我不甘心,继续搜索grub的使用方法,试着敲入如下的命令:

kernel (hd0,6)/isolinux/vmlinuz <br  />initrd (hd0,6)/isolinux/initrd.img <br  />boot

成功了,终于可以进入继续安装Fedora 9的界面了!
只要能够进入一个操作系统就好说了,不管它是Windows还是Linux!

EMC-CBR故障诊断研究(四)

1、系统组成
   本系统是由
CBRRBR组成的混合系统。系统结构如下图所示。系统的核心是推理机,推理机根据用户输入的故障描述,既可以将故障描述转化为新的案例,从而进行对案例库进行操作;又可以将故障描述转化为事实,对规则库进行操作。但CBRRBR的地位并不是等同的,CBR起主导作用,RBRCBR起监督作用,二者的推理结果由综合机制进行综合。本系统采用友好的人机界面,普通用户输入故障描述后,系统经推理后给出诊断建议,并对给出的建议进行解释。另外,为了便于对系统知识(案例库、知识库和事实库)进行管理,系统可以由知识工程师进行修改。

2、案例表示与存储

参见博文“EMC-CBR故障诊断研究(一、二)”

3、案例检索

参见博文“EMC-CBR故障诊断研究(三)”

4、案例重用

案例重用的主要任务是对检索到的案例的结论进行修正。基本思想就是将案例库中与目标案例最相似的案例的结论与次相似的案例的结论进行对比,如果二者仅仅是谓词函数的参数不同,可以认定无需对最佳匹配案例进行修改;如果二者不仅参数不同而且有谓词上的出入,则需启用基于规则的推理,最终利用CBRRBR的综合机制利用RBR的结论对最佳匹配案例的结论进行修正。

5、

案例的保存

    在案例保存时要进行模式归纳(Schema Induction)。模式归纳的含义就是指:如果类比导致了一个解,则执行两类似体的泛化过程,以便形成一个抽象的案例模式。简而言之,就是寻找两类似体的共性,然后加以抽象和泛化。

案例保存的过程可以看作一个归纳学习的过程,很多归纳学习的方法都可以应用于案例保存,如产生预测试方法(INDUCE1.2)。

6、案例的维护

心理学家在研究记忆机理时,提出了著名的遗忘曲线理论,即长期不用的信息将会被逐渐遗忘。在基于案例推理中,案例库的维护很重要,必须将长期不用的案例删除,因为这种案例很可能是噪声案例,例如误诊的病例、误判的案件等。Aha建议对案例库中的每个案例建立一个匹配记录,就可以删除那些噪声或无用的案例,以维护案例库的有效性。Aha提出案例求精算法IB3,表述如下[51]

输入:案例库S和测试案例集T

输出:精化案例库S’

过程:

(1)    从测试案例集T中任选一个测试案例t

(2)    设法从案例库S中找到一个案例s,它与t有最佳匹配,其相似度超过某个阈值;

(3)    如果找不到这样的s,则转到(8);

(4)    若确认ts属于同一类,则转(9);否则把t加上它所属的类c的标志后存入库S

(5)    从库S中找出所有这样的案例si,它们和t的相似程度至多不大于st的相似程度,所有这些si的匹配记录要扣分;

(6)    从库S中删除记录分数小于某个规定值的所有案例;

(7)    如果测试集的案例已经用完,则算法结束,否则转(1);

(8)    从库S中任选一个案例s,转到(4);

(9)    从库S中找出所有这样的案例si,它们和t的相似程度至少不亚于st的相似程度;

(10)转到(7)。

       7、

基于规则的推理

基于规则推理(RBR)子系统是一个简化的专家系统。RBR子系统由事实库和规则库组成,规则库中存放由专家经验中提取出来的专家规则,以产生式表示;事实库是由推理机通过人机界面从用户的输入中提取出来的事实,以命题逻辑表示。

例如,和上面讨论的case6相关的规则有“使用导电橡胶、衬垫之类的屏蔽材料时,不但要保证接触面上的良好的导电性(接触面去除所有漆),而且还要保证一定的压缩量。”,可以用产生式规则表述如下:

Shielding(product, conductive_tape) Shielding(product, condutive_gasket) => Wipe_off(interface, lacquer) (Compress(conductive_tape) Compress(conductive_ gasket))

   RBR的推理采用不确定性推理。不确定推理包括前提条件的不确定性、结论的不确定性以及推理过程的不确定性。根据电磁兼容知识的特点,必须综合利用这三种不确定性才能比较确切的模拟电磁兼容专家的推理过程。不确定推理的通用表示方法为[20]

                            IF [(p1, f1, t1) AND (p2, f2, t2) ANDAND (pm, fm, tm)]

                            THEN [((q1, g1, s1), (q2, g2, s2)…)] WITH CF(R)

其中,pi表示模糊前提条件,qi表示模糊结论及动作,CF(R)为可信度,fi是表达前件的可能性分布,ti是前件的确信程度,gi是表达结论的可能性分布,s1是结论的确信程度。

    对于前件,可以采用表达方案:,p为模糊命题,x为对象名,Ax的属性名,D是确定性状态表达,p的相应的确定性命题,是命题的不确定性度量。

例如,某模糊命题为:

如果为感应耦合(可信度0.9),且电路频率很高(模糊数0.8),则耦合为容性耦合(可信度0.7)

则该命题可以表述为:

                          IF [(p1,0.9) AND (p2,0.8)] THEN[(q1, 0.7)] WITH CF(R)

其中,

R为根据不确定推理理论计算出的整个命题的可信度。

     8、

CBRRBR的综合机制       

   当目标案例和CBR案例库中的源案例的相似度低于阈值时,启用RBR。如果利用RBR能够推导出结果,则将RBR的结论作为最终诊断结果,将CBR的结论作为建议一同提交给用户;如果由于规则的不完整RBR无法推导出结论,则将CBR的结论作为诊断结果提交给用户,但此时必须注明该结论的可信度(可信度可以用目标案例和源案例的相似度表示)。

 

逻辑表达式词法分析器分析结果的显示


      上篇博客文章《简易逻辑表达式词法分析器》讲到设计了一个逻辑表达式词法分析器,这次以那个词法分析器作为后端,利用VC搭建前端界面,展示一下分析效果。

      分析结果以树的形式表示:同一级节点表示具有相同的等级,参数比它的谓词的等级要高,比如Missile(x)中Missile等级为0级,x为1级。分析之后各个节点存储在Parser.list中,可以根据该链表的节点的level属性将各节点插入树种的相应位置。
     分析以上逻辑表达式可知,各个节点的等级如下:
      Missile  x  AND  Owns  Nono  Sub  x  =>  Sells  West  x  Nono
         0         1   0         0           1         1    2  0      0          1      1      1
     可见,利用堆栈来辅助将节点插入树中是最理想的方法。思路如下:将树的TVI_ROOT压栈;若当前节点的等级大于其前一个节点,将前一个节点压栈;若当前节点等级小于前一个节点,出栈前一节点等级 和  当前节点等级之差次;若当前节点等级等于前一节点等级,既不压栈也不出栈。每个当前节点的父节点为栈顶元素。

      源代码如下:

void CPPageFaultLogicExpression::OnBnClickedButtonParse()
{
    
// TODO: 在此添加控件通知处理程序代码
    UpdateData(TRUE);

    
if(m_strLogicExpression==L"")
    
{
        MessageBox(L
"请输入逻辑表达式!");
    }

    
else
    
{
        m_parser.Parse((wstring)m_strLogicExpression); 
// 进行词法分析
        m_bIsParsed=TRUE;

        
//// 向词法分析树种添加分析结果    ////
        m_tLexer.DeleteAllItems(); // 清除所有节点

        NodeList_It it
=m_parser.list.begin();
        NodeList_It tmp_it
=it;
        wchar_t tmp[
128];
        wcscpy(tmp,it
->content.c_str());

        stack
<HTREEITEM> st;    // 定义堆栈

        TVINSERTSTRUCT tvInsert;
        tvInsert.hParent 
= TVI_ROOT;
        tvInsert.hInsertAfter 
= TVI_LAST;
        tvInsert.item.mask 
= TVIF_TEXT;
        tvInsert.item.pszText 
= tmp;

        HTREEITEM hcur
=TVI_ROOT;
        st.push(hcur);
        hcur
=m_tLexer.InsertItem(&tvInsert); // 插入根节点
        
        HTREEITEM hprev;
        hprev
=hcur;
//        int level=0,max_level=0;

        it
++;

        
for(it;it!=m_parser.list.end();it++)
        
{
            wcscpy(tmp,it
->content.c_str());

            
if(it->level > tmp_it->level)    // 当前节点深度大于前一节点时,前一节点所在的树的位置入栈
            {
                st.push(hprev);
                hcur
=m_tLexer.InsertItem(tmp,hprev,TVI_LAST); // 插入新的节点
                
            }

            
else if(it->level < tmp_it->level) // 当前节点深度小于前一节点时,根据两节点深度之差将保存的节点出栈
            {
                
int level=tmp_it->level;
                
while(it->level < level--)
                
{
                    st.pop();
                }

                hprev
=st.top();
                hcur
=m_tLexer.InsertItem(tmp,hprev,TVI_LAST); // 插入新的节点
            }

            
else if(it->level == tmp_it->level) // 当前节点深度等于前一节点时,根据栈顶元素插入新节点
            {
                hprev
=st.top();
                hcur
=m_tLexer.InsertItem(tmp,hprev,TVI_LAST);
            }


            hprev
=hcur;
            tmp_it
=it;
        }


        UpdateData(FALSE);
    }
// end of else
}

   PS1:  当初考虑到中文的支持,利用wstring定义节点内容,现在发现是个错误,在字符转换的过程中很是麻烦,耽误了不少时间,走了不少弯路。
  PS2: 也许因为我对STL不是很熟悉,感觉比较麻烦,不知道如何被C++标准委员会接纳的?

利用VC设计简易逻辑表达式词法分析器

简易逻辑表达式词法分析器

待分析的逻辑表达式如下:

                EXISTS(x)(Missile(x) AND Owns(Father(Nono),Part_of(x))) => Sells(West,x,Nono)

为了处理逻辑表达式,必须首先提取出逻辑表达式的各个部分:关键字(AND, OR, NOT, FORALL, EXISTS, =>)、谓词和参数,同时必须对于表达式中多余的空格必须删除。这项工作由一个词法分析器完成。

该词法分析器最基础的部分是一个自定义节点Node,定义如下:

class Node
{
public:
    
// VARIABLEs
    enum NodeType {KEYWORD, PREDICATE, PARAM};    // Types of the node.
    static wstring KeyWord[];
    NodeType type;
    wstring content;    
// content of the node.
    int level;    // Record the level of the node,for example: 
                
// Owns(Nono,Sub(x))---"Owns" in level 0,"Nono""Sub" in level 1 and x in level 2.

    
// FUNCTIONs
    Node();
    Node(wstring con,NodeType type_
=KEYWORD,int lev=0);
    
~Node();
    
virtual Node& operator=(Node&); // Overrides of operator=

protected:

}
;

Node主要有三个部分:该节点内容、节点类型、节点的等级(用以对提取出的表达式进行进一步的分析)。

同时定义了一个链表:

typedef list<Node> NodeList; // Define List.

该链表用于存储整个逻辑表达式。

同时定义了一个类Parser,封装了NodeList用于对逻辑表达式进行操作。

class Parser
{
public:
    
// VARIABLEs
    NodeList list;
    Node
* node;
    
    
// FUNCTIONs
    Parser(){ node=NULL;};
    
~Parser();
    Node
* Parse(wstring str,int cur_pos=0); // function to parse a string.

private:

}
;

词法分析器的核心函数就是Node* Parser::Parse(wstring str,int cur_pos)该函数主要针对逻辑表达式中的'('' '','以及')'进行分析,流程图如下:

运行结果如下:

词法分析器运行结果

 
分析结果以树的形式表示:同一级节点表示具有相同的等级,参数比它的谓词的等级要高,比如Missile(x)中Missile等级为0级,x为1级。分
析之后各个节点存储在Parser.list中,可以根据该链表的节点的level属性将各节点插入树种的相应位置。
     分析以上逻辑表达式可知,各个节点的等级如下:
      Missile  x  AND  Owns  Nono  Sub  x  =>  Sells  West  x  Nono
         0         1   0         0           1         1    2  0      0          1      1      1
    
可见,利用堆栈来辅助将节点插入树中是最理想的方法。思路如下:将树的TVI_ROOT压栈;若当前节点的等级大于其前一个节点,将前一个节点压栈;若当
前节点等级小于前一个节点,出栈前一节点等级 和 
当前节点等级之差次;若当前节点等级等于前一节点等级,既不压栈也不出栈。每个当前节点的父节点为栈顶元素。


源代码如下:

//////////////////////////////////////////////////
//    
//    Function Name: Parse
//    Input:    a wstring(must), 
//            the start position of being parsed(choiced).
//    Output: a parsed list's head.
//
//////////////////////////////////////////////////
Node* Parser::Parse(wstring str,int cur_pos)
{
//    int start=cur_pos;
    Node* tmpNode=NULL;
    wchar_t pstr[
40]=L"";    // temp var to record words.
    int k=0// used together with pstr.
    int level=0;
    
int space_pos=0;
    
    
// Deal with the first keywords of a propositional fuction.
    
// Such as NOT, EXISTS(x), FORALL(y) and so on.
    
// EXAMPLE: EXISTS(x)(Missile(x) AND Owns(Nono,x)) => Sells(West,x,Nono)
    
// EXAMPLE: NOT(Missile(x)) AND Owns(Nono,Sub(x)) => Sells(West,x,Nono)
    
// EXAMPLE: Missile(x) AND Owns(Nono,Sub(x)) => Sells(West,x,Nono)
    while(cur_pos!=str.length())
    
{
        
if(str[cur_pos]==L'(')    // Words before '(' only can be KEYWORD or PREDICATE.
        {
            
bool isKeyWord=false;
            
for(int i=0;i<sizeof(Node::KEYWORD);++i)
            
{
                
if(!wcscmp(pstr,Node::KeyWord[i].c_str())) //pstr==Node::KeyWord[i]
                {
                    isKeyWord
=true;
                    tmpNode
=new Node(pstr,Node::KEYWORD,level);
                    list.push_back(
*tmpNode);    // Insert keyword.
                    break;
                }

            }

            
if(!isKeyWord && wcscmp(pstr,L"")) //pstr is not keyword or NULL
            {
                tmpNode
=new Node(pstr,Node::PREDICATE,level);
                list.push_back(
*tmpNode);    // Insert PREDICATE.
            }

            
++level;
            
++cur_pos;
            k
=0;
        }

        
else if(str[cur_pos]==L' ')
        
{
            
if(str[cur_pos-1]!=L')'// if a ' ' follows ')',then compare the following to or three with keyword.
            {
                
if(wcscmp(pstr,L"")) // pstr is not empty 
                {
                    wstring strAND(str,cur_pos
-3,3);
                    wstring strOR(str,cur_pos
-2,2);
                    
if(!strAND.compare(L"AND"|| !strOR.compare(L"OR"|| !strOR.compare(L"=>"))
                    
{
                        tmpNode
=new Node(pstr,Node::KEYWORD,level);
                        list.push_back(
*tmpNode);    // Insert keyword.
                        ++cur_pos;
                        k
=0;

                        memset(pstr,L
'',sizeof(pstr));
                        
continue;
                    }

                    
else 
                        exit(
0);    // Error!
                }

            }

                
            
++cur_pos;    // Ignore whitespace.
            continue;
        }

        
else if(str[cur_pos]==L','// pstr must be a param
        {
            
if(!wcscmp(pstr,L""&& str[cur_pos-1]==L')'// In a case like: Owns(Father(Nono),Sub(x))
            {
                
++cur_pos;
            }

            
else if(wcscmp(pstr,L"")) // pstr is not empty 
            {
                
if(str[cur_pos-1]==L')'// Something between a ')' and a ',', Error!
                    exit(1);
                
else
                
{
                    tmpNode
=new Node(pstr,Node::PARAM,level);
                    list.push_back(
*tmpNode);    // Insert PARAM.
                    ++cur_pos;
                }
    
            }
        

            k
=0;
        }

        
else if(str[cur_pos]==L')')    
        
{
            
if(!wcscmp(pstr,L""&& str[cur_pos-1]==L')'// In a case like: Owns(Father(Nono),Sub(x))
            {
                
++cur_pos;
            }

            
else if(wcscmp(pstr,L"")) //if pstr is not empty
            {
                
if(str[cur_pos-1]==L')')    // Error!
                    exit(1);
                
else
                
{
                    tmpNode
=new Node(pstr,Node::PARAM,level);
                    list.push_back(
*tmpNode);    // Insert PARAM.
                    ++cur_pos;
                }

            }


            
--level;
            k
=0;
        }

        
else
        
{
            pstr[k
++]=str[cur_pos++];
            
continue;
        }


        memset(pstr,L
'',sizeof(pstr));
    }

    
return &list.front();
}

 

 

线性坐标系到对数坐标系的变换——EMC测试曲线的绘制

       
    绘制测试曲线的核心函数为
CEMCView::DrawFrameCurve()函数。该函数可以根据测试的频段和该频段的测试数据在对数坐标系的对应位置绘制测试曲线。DrawFrameCurve()函数绘制曲线的流程图如图1所示:


图1 测试流程图


 

    图2 R3131A屏幕显示的线性坐标系


    每次测试,Advantest R3131A频谱仪都会对所测频段采样501个点,每个点对应的测试值不小于512,如图3-29所示。大于3392的数值不在频谱仪屏幕上显示,但会记录下这个值,因为这个值也是有效的。Advantest R3131A频谱仪默认纵轴每格代表10dB,因此频谱仪的测试值3392-512=2880对应着80dB。对于在计算机上绘制的对数坐标系而言,若纵轴表示0M dB,因此对数坐标系纵坐标最大值对应的频谱仪测试值为:


         Ytop为对数坐标系左上角对应的计算机屏幕上的纵坐标值,Ybot表示对数坐标系左下角对应的计算机屏幕上的纵坐标值,y表示对数坐标系中某个测试点对应的计算机屏幕上的纵坐标值,d表示该测试点对应的频谱仪测试值,对数坐标系纵坐标从0开始,则:


因此,


                                                  (3-1)

对于横坐标,如果已知测试的起始频率为fstart,起始频率对应的计算机横坐标为xstart,测试终止频率为fstop,测试终止频率对应的计算机横坐标为xstop,该频段的起始频率为ffrmstart,结合图3-16可得该频段起始频率对应的计算机坐标有:


因此

 

 

         如果每个测试频段有N个采样点,也即有N个测试数据,那么该频段中第i个数据对应的频率为fi,且

式中,     ffrmstop——测试频段的终止频率。

i个数据对应的计算机横坐标为:

                     (3-2)

         如果在某个测试频段内的第i个数据的测试值为d,则该点对应的计算机屏幕坐标为(xi,yi)xi、yi可分别根据式(3-1)和式(3-2)求出。

 

PS:

    CSDN不支持把Word中的公式自动保存为图片实在是太难用了,每次都要自己先把公式转化为图片然后再插入到文章里,麻烦!

案例检索——EMC-CBR故障诊断研究(三)


案例检索的核心任务就是计算新案例和案例库中的案例的相似度,而相似度要由案例的故障特征和系统结构确定。

1)案例属性之间的距离

由于系统结构直接影响着EMI的大小,即便两个设备具有相同的物理布局但采用不同的元件或材料,其EMC的效果也是不同的,因此两个案例之间的“系统结构”之间的距离不仅和谓词相关,而且要考虑到谓词函数的参数——谓词往往表示结构布局,而参数往往表示材料或元件。因此,在计算案例属性之间的距离时,对于案例属性中的谓词和参数要赋予不同的权值。

case-i的某个属性(故障特征或系统结构)m个谓词,case-j对应的该属性有n个谓词,且二者相同的谓词个数为k,其中min(m,n)k。若该属性中,谓词权重为,参数权重为,则定义两案例在该属性的距离为

其中, case-icase-j中第h个相同的谓词的参数之间的匹配程度,有

        

该定义只考虑了相同的谓词以及相同谓词对应的参数之间的关系,两案例相同的谓词越多,则这两个案例之间的距离越短。

         2)案例的相似度

         d1为两案例“故障特征”属性的距离,d2为两案例“系统结构”属性的距离,由于0<=d1,d2<=1,则可以定义两案例的相似度为:

其中,SIM1SIM2分别为两案例“故障特征”属性、“系统结构”属性对应的相似度,且

i=1,2

         案例库中和目标案例相似度最大的案例,就是最佳匹配案例。当然,有可能出现即便是最佳匹配案例和目标案例的相似度也比较小的情况。可以为了保证最终结果的正确性,设定一个相似度的阈值,低于该阈值的相似度的案例不能作为最终结果使用,必须利用专家系统对结果进行修正。

半旗.默哀.国歌

document.domain="qq.com";
//parent.qZEditor.callback();
function init(){
var key = location.hash.substr(1);
document.editorID = key;
parent.editorHash[key].callback();
}

    今天下午,2008年5月19日14:28分,我来到北京理工大学东操场,和其他近万名师生一起,集体为汶川大地震遇难者默哀。这次活动是学校倡议的,本没有安排我们即将毕业的硕士参加,但我们还是去了。下午2点操场上已经占满了人,BTV对这次活动现场直播。默哀前,低年级的小朋友们的表现令我很不满,他(她)们的态度很不严肃,部分女生的着装也不庄重,表现不合时宜。但是当开始默哀时,他/她们能够迅速进入状态,没有人交谈,没有手机响起,没有骚动,还是难能可贵的。

    默哀过程中,防空警报声、汽车鸣笛声此起彼伏,为逝者而悲号,为生者而祈祷。尽管我还年轻,尽管我远离灾区,但我脑海中再一次涌现出那句话——“人应该赶快生活”。

   
    默哀完毕,根据指挥老师的提议,我们和自己身边的同学手拉手,唱起了久违的国歌。国歌是那么熟悉有那么陌生——熟悉是因为从小就听着国歌长大,陌生是因为很少有机会自己亲口唱起它。今天,总算给了我们一个唱响国歌的机会。
 
    今天凌晨1:30从女朋友家出发走向她们县的火车站,3点多坐火车回北京。在由北京西站回学校的公交车上,看到了(确切地说是听到了,人多,只能听到电视的声音,却看不到图像)电视里天安门降半旗的情景。国旗护卫队迈着整齐的步伐走到旗杆前,奏国歌,升国旗,国旗升好后,只听一位国旗护卫队员高喊“降——半——旗——”,我身体一颤,莫名的辛酸油然而生,之后就是很长时间的寂静。平时公交车里即便寥寥数人也异常热闹,但今天早晨,却非常安静。尽管只有少数人能看到电视屏幕,但大多数人都在倾听,神情都很肃穆。
 
    路过几家宾馆和国营机构,鲜艳的五星红旗都在旗杆的半空中摇晃着,向路人诉说着这个国家正在经历的苦难……

硬盘安装Fedora 9成功

       昨天晚上半夜(5月13日晚23:56分)我登陆到fedora项目的主页一看,My God,Fedora 9已经可以下载了!我立马开始下载。由于速度只有几百K/S,只好先睡觉。
       今天早上6:30就起来了,第一件事就是准备将Fedora 9刻录到光盘,然后准备安装。几天前就已经将光盘买好了,Nero也装好了,就等着刻呢。非常恶心的是,我一连试了三张白盘,一次也没刻录成功!气得我七窍生烟!还不到两年,破本本的刻录光驱就不能刻录了!Shit!
       8点多感到实验室,半路上就决定了要从硬盘安装Fedora 9。上网查资料,N多,感觉还蛮简单的。照做。下载Grub for Linux,设置好,设置menu.lst。问题来了,将Fedora的iso映像放到哪里呢?还有就是我的Windows分区是NTFS格式的,留出来的空闲分区才15G,太小了,怎么改变分区大小呢?
         有人说DVD版的Fedora要解压缩,有人说不用,但都要放到Fat或fat32分区里。上网,下载了Partition Manager,结果安装时说不能用于Windows Server 2003下面。Shit@!只好重新搜到了一个可以用于Server 2003下调整分区的软件。调好之后,重启进入grub安装。结果进不去Fedora安装界面!
         找遍了所有原因,才发现自己在menu.lst中的initrd写成了intrid!唉!改正后终于进入了安装界面。这时却又找不到Fedora映像了。哦,原来我直接将iso给解压缩了。shit!不得不重新将Fedora的iso映像拷到fat32分区,重新装,一切OK!
       
       大二的时候就装过Red Hat Linux9,当时装了玩了几次,感觉很不好用,就给删了。大四毕业又玩了一段时间Fedora core3,感觉好多了。后来在实验室电脑上装了Fedora 7,感觉很好。前几天用Wubi在笔记本上装Ubuntu8.04,结果不成功,很是郁闷。在实验室台式机上却成功了。进到Ubuntu后完了几次,感觉很不爽——界面不怎么好看,桌面版自带的软件少得可怜,要通过网络安装,可我们平时很难上外网(拜教育网所赐)。总的说来,还是比较喜欢Red Hat 的产品,毕竟人家定位在企业级应用。而且听说Linus用的Linux版本就是Fedora哦。
     最近一年来逐渐对Linux情有独钟,也越来越不喜欢用Windows了。毕竟这是两种不同的模式,两种不同的文化。现在对知识产权的意识越来越强烈了,以前一直用盗版,现在不想用了,但又没钱买正版Windows下的软件,因此还是转到Linux的好。
      向开源进军!

PS:硬盘安装Linux的详细设置请参阅

以WinGrub 引导安装Fedora 4.0 为例,详述用WinGrub来引导Linux的安装

EMC测试曲线选择缩放功能的实现

EMC测试曲线选择缩放功能的实现

 

EMC测试完成后,一般以曲线的形式显示在对数坐标系中。由于测试数据非常多,而对数坐标常常使得大量的数据分布不均,经常在一些地方使得测试曲线叠加在一起,看不清楚具体的数值和趋势。一幅CE102测试曲线如图1所示:

1 CE102-全频段测试曲线图

由图可见,要想看清2MHz以后的数据只有两种方法:选择感兴趣的频段重新测试,或者将感兴趣的频段放大。重新测试需要耗费更多的时间,也是一种无谓的重复劳动,而且在某些情况下无法实现(没有频谱仪或接收机在身边的时候)。选择感兴趣的频段放大,既节省时间,又便于查看。

本程序中选择放大的使用方法极为简单,按下工具栏的放大按钮,在测试坐标系中按下并拖动鼠标左键选择频段,释放鼠标左键,这样就可以将选择的频段的测试曲线放大了。



2 选择放大的方法

在图2中绿色虚线就是按下并拖动鼠标左键进行选择时的效果。

放大后的曲线如图3所示:

3 选择放大后的测试曲线

放大后按下工具栏的缩小按钮就可以重新显示原始的测试数据。

 

下面介绍一下程序的编写。

选择频段的过程至少包含三个相关函数:void CEMCView::OnLButtonDown(UINT nFlags, CPoint point)void CEMCView::OnLButtonUp(UINT nFlags, CPoint point)void CEMCView::OnMouseMove(UINT nFlags, CPoint point)。三个函数的定义如下:

void CEMCView::OnLButtonDown(UINT nFlags, CPoint point)
{
    
// TODO: 在此添加消息处理程序代码和/或调用默认值
    m_lBtnDownPoint=point;    // 记录按下鼠标左键的点
    m_bIsLBtnDown=TRUE;

    CScrollView::OnLButtonDown(nFlags, point);
}

void CEMCView::OnMouseMove(UINT nFlags, CPoint point)
{
    
// TODO: 在此添加消息处理程序代码和/或调用默认值
    if(m_bIsWorking && m_bIsLBtnDown && !m_bOldVersion)
    
{
        
if(point.x>m_maxMouseX)
            m_maxMouseX
=point.x;
        
if(point.y>m_maxMouseY)
            m_maxMouseY
=point.y;

        CRect rect(m_lBtnDownPoint.x
-1,m_lBtnDownPoint.y-1,m_maxMouseX+1,m_maxMouseY+1);

        CClientDC dc(
this);
        
// Create a geometric pen.
        LOGBRUSH logBrush;
        logBrush.lbStyle 
= BS_SOLID;
        logBrush.lbColor 
= RGB(17,255,17);//RGB(0,51,51);
        CPen pen(PS_DOT|PS_GEOMETRIC|PS_ENDCAP_FLAT,2&logBrush);
        CPen
* pOldPen=dc.SelectObject(&pen);

        
this->InvalidateRect(&rect);
        
this->UpdateWindow();

        
// 绘制虚线矩形
        dc.MoveTo(m_lBtnDownPoint);
        dc.LineTo(m_lBtnDownPoint.x,point.y);
        dc.MoveTo(m_lBtnDownPoint.x,point.y);
        dc.LineTo(point);
        dc.MoveTo(point);
        dc.LineTo(point.x,m_lBtnDownPoint.y);
        dc.MoveTo(point.x,m_lBtnDownPoint.y);
        dc.LineTo(m_lBtnDownPoint);

        dc.SelectObject(pOldPen);
    }

    CScrollView::OnMouseMove(nFlags, point);
}

void CEMCView::OnLButtonUp(UINT nFlags, CPoint point)
{
    
// TODO: 在此添加消息处理程序代码和/或调用默认值
    m_bIsLBtnDown=FALSE;

    m_zoomStartX
=m_lBtnDownPoint.x;
    m_zoomStopX
=point.x;

    
// 更新视图
    if(!m_bOldVersion)
    
{
        
if(m_bIsZoomed)
        
{
            m_bDrawZoom
=TRUE;
        }

        
this->Invalidate();
        
this->UpdateWindow();
    }


    CScrollView::OnLButtonUp(nFlags, point);
}

由于测试是分成多段进行的,测试曲线的绘制也是分成多段来进行,因此选择放大时也要考虑到所选择区域是否包含关键点(频率段与频率段之间的边界点)。因此选择放大频段的显示也分为三种情况进行考虑:选择的起始点和终止点在同一分段内、在两相邻频段内、在不相邻的不同频段内。

由于选择放大显示的代码较多,只介绍编程思路吧。首先根据鼠标左键选择的起始点和终止点的X坐标确定起始频率和终止频率,然后确定起始点和终止点的相对位置(即上段所说的三种情况),接下来重绘坐标系,针对三种不同情况分段绘制曲线,最后重绘军标线。

【原创】案例推理(CBR)中案例的存储与检索——EMC-CBR故障诊断研究(二)

   最近一直在研究案例推理,看到好多论文都在大谈CBR理论,很是崇拜。不过一直有一个问题没有搞懂,就是案例(case)到底是怎么存储的呢?

       CBR的大师们如Schank、Koldner等人一般用动态存储模型

Dynamic Memory Model,如

Ray Bareiss者一般采用 类别&案例模型(The Category & Exemplar Model),中科院史忠植教授也提出了自己的一种由于以网络发展而来的方法。大师们的境界非我一AI菜鸟所能领悟,大师们的方法也非我能够掌握。幸好看到国内外有几篇论文比较浅显,说可以用关系型数据库来存储,一笔带过,很是潇洒,但我更加一头雾水了。

       迷糊了半个月,在高济教授等编著的《人工智能基础》(高等教育出版社,2002)第三章看到了语义网络表示方法,文中同时给出了如何将语义网络转换为一阶 谓词表示的方法,因此茅塞顿开,有了《EMC-CBR故障诊断研究(一)》一文中的成果。但一阶谓词逻辑又该如何存储到数据库呢?

        在《人工智能基础》一书的第122页作者给出了一个简单的语义网络和该语义网络的一阶谓词表示,书中阐述了一种将谓词作为数据表的列的一种存储方法。但是 思来想去该方法存在一个问题,一旦语义网络比较复杂(显示问题中随便一个问题的语义网络表示都很复杂),数据表中的列将迅速膨胀;更严重的问题是,对于不 同的EMC故障案例而言,用于描述该案例的谓词数目是不确定的,因此数据表的列数也无法确定,这在关系型数据库中是不可能实现的!我再次陷入迷茫。

       God bless us!今天终于想出一种存储方法。思路就是将一阶谓词作为一个对象来进行存储。一阶谓词的属性可以作为数据表中的列,而谓词函数以及谓词的参数作为行来存储。表的设计如下:

CBR

列号

列名

数据类型

能否为NULL

说明

1

predicate_no

smallint

Not Null

谓词编号,主键,标识,种子1,增量1

2

case_no

varchar(15)

Not Null

案例号,一般为case+数字

3

predicate

varchar(30)

Not Null

谓词

4

predicate_property

varchar(30)

Not Null

谓词属性,取值范围fault_character, phisical_structure, causation, settlement

5

param_nums

tinyint

Not Null

谓词参数的个数,取值范围12,默认为2

6

param1

varchar(50)

Null

谓词函数的第一个参数

7

is_param1_digit

bit

Null

param1是否为数字类型,默认0

8

param1_unit

varchar(8)

Null

param1的单位,如果param1为数字类型,则该项一般不为Null

9

param2

varchar(50)

Null

谓词函数的第二个参数

10

is_param2_digit

bit

Null

param2是否为数字类型,默认0

11

param2_unit

varchar(8)

Null

param2的单位,如果param2为数字类型,则该项一般不为Null

12

has_sub_predicate

bit

Null

谓词函数是否以别的谓词作为参数,默认为0

13

sub_predicate_no

smallint

Null

作为参数的谓词的编号

本案例库采用SQL Server2005 Express Edition来实现:

如果要查询案例6EUT的物理结构特征,可以用如下查询语句:

SELECT predicate, param1, param2

FROM Cases

WHERE (predicate_property = 'phisical_structure') AND (case_no = 'case6')

查询结果如下:

【注】:版权归作者所有,转载或引用请注明出处。