搜档网
当前位置:搜档网 › quagga代码分析

quagga代码分析

quagga代码分析
quagga代码分析

quagga代码解读

编辑:王斌2009-6-8

修改:

1vtysh命令添加

vtysh是quagga与用户交互的接口软件,用户通过vtysh输入命令,vtysh可以将命令解析并通过socket发送给相应的后台进程进行对应处理,处理结果由后台进程通过socket发送回vtysh并显示在屏幕上。

Quagge的程序结构如下:

其中rip, ospf, interface…都是quagga后台的进程负责实现对应的功能。其他还有zebra, bgp…

Vtysh接收到输入的命令后会通过命令对应的deamon字段(可以理解为一个进程的标志,标志该命令输入哪个进程)传送给对应进程处理,进程处理完后会自动返回一个结果给vtysh.

Vtysh运行后进入vtysh_main.c的主函数main中,经过一系列初始化后进入循环等待命令输入:

输入的命令会传入line_read的地址中,通过vtysh_execute()进行后续的解析和执行。在vtysh_rl_gets()可以看到这样一段代码

会把输入的命令存入history中。

添加一个命令需要几部分的工作:

1 找到该命令所在视图,若视图不存在则需要定义该视图

2 定义声明该命令的宏,并将命令注册到对应视图下

3 定义命令动作

下面我们慢慢介绍上面的过程。

1.1定义并引入node

代码中的node指vtysh的视图模式,所谓视图最直观的表现就是命令行前端显示出来的提示信息,如图:

vtysh开始的视图为dptech-desktop#, 当输入configure t/n后视图变成了dptech-desktop(config)#,输入router ospf后视图变成了dptech-desktop(config-router)#.命令都是在视图下注册的,视图的作用是区分在本视图下哪些命令有效,哪些无效。

在vtysh.c中定义了node:

Cmd_node的结构体定义如下:

首先是node_type,是枚举类型,因此定义一个视图首先要在枚举中添加该视图。Prompt字段即是进入该视图后命令行前端显示的提示字符。

一个node在定义后还需要引入到vtysh中

通过在vtysh.c中的vtysh_init_vty (void)函数(该函数在vthsh启动时由main()函数调用)中调用install_node()可以将node引入到vtysh。其本质就是将node加入到一个包含所有node的数组中。Node也同时需要在后台的其他对应进程中定义并引入,目的是为了视图同步。因为后台运行的其他进程(如rip、ospf)都可以通过其他telnet 客户端访问调用。因此如果不同步则在同时两个客户端接入后台进程时会产生一些问题。

在vtysh_init_vty (void)函数中Node引入后还需要定义进入和退出node以及帮助的命令,并引入

View_node中添加了help命令config_help_cmd。

1.2添加command

需要用到Command.h中的三个宏定义:

从定义中我们能够看到区别,DEFUN和DEFUNSH两个宏中的FUN代表包含函数,它们除了由DEFUN_CMD_ELEMENT定义了一个结构体外都声明并引入了一个函数。函数由宏DEFUN_CMD_FUNC_DECL声明(DECL表示declear),由DEFUN_CMD_FUNC_TEXT定义函数头。通过宏所引入的函数可以完成命令对应操作。

DEFSH中只定义了一个结构体

还有以SH结尾的两个结构体DEFUNSH和DEFSH中都定义了一个daemon字段,该字段用于记录进程号,如

上图中的结构体表示对应在vtysh中输入exit这条命令会将该命令传送给VTYSH_INTERFACE这个进程处理,‖Exit current mode and down to previous mode\n‖表示该宏的作用,vtysh_exit_interface为该宏所定义函数的函数名,vtysh_exit_interface_cmd为该命令的id(在引入到node中时使用该字段)。Exit表示对应在vtysh中输入的command。

通过定义这三个个结构体中的一个便可以引入我们需要添加的命令行命令。但是注意加入一条命令时需要分别在vtysh和其对应执行进程中使用对应宏定义该命令,因为进程在接收到由vtysh发送来的输入命令后也需要查找这些宏来进行相应处理。通常后台进程中只定义DEFUN宏即可,因为一般不需要再通过daemon字段传送给其他进程处理。而在vtysh中一般使用DEFUNSH和DEFSH,除非像help或者List这样不需要后台进程处理的命令使用DEFUN定义。

Command需要通过install_element()函数引入到对应的node下,如

引入时使用了前面所介绍宏定义中的vtysh_exit_interface_cmd字段(ospf_router_id_cmd便是对应宏中该字段的值)。

这样在之前提到的node数组中,每个节点的node都会对应一组命令,所有的命令和视图就是被放在一个“大表”中。

再次提示要同时在vtysh和对应进程中添加命令。

至此命令添加完毕。

1.3编译

为什么会单独提到编译这点,因为它比较重要而且很容易被忽略。命令添加完毕后,在linux 下进行编译安装时要注意在./configure后添加命令—enable-vtysh,否则安装后新添加的命令便无法体现在vtysh中。详细的linux下安装方法请参考

―/VSS/学习资料/quagga资料/quagga在Linux下的安装方法.doc‖

1.4添加“ip ospf enable”命令行

该命令添加比较简单,因为作用是接口ospf使能,因此只需要在interface node中添加该命令并添加对应函数。首先简单的不和ospf进行交互,使用DEFUN便可实现。

在ospf_vty.c中添加如下图代码。vtyshell在输入‖ip ?‖后会显示可在ip后添加的命令及命令的说明,“enable ip ospf router in this Interface\n‖便是命令的说明,在命令“ip ospf enable”后的第一对双引号中是对应ospf的说明,第二对双引号中是对应enable的说明,如果命令由更多words组成,则以此类推。本例中只给出一个说明,因此输入命令“ip ospf ?”后可以看到enable后没有命令说明。

注意在vtysh外其他进程中打调试命令可以使用vty_out()函数,fprintf()试了一下,好像打不出来。

添加该宏后在ospf_vty_if_init (void)函数中注册该命令:

然后在linux下编译安装,注意需要./configure –-enable-vtysh.还有就是因为修改ospf_vty.c中的文件,因此安装时候如果原来系统里已经安装过quagga请将libospfd.so.0重新由/usr/local/lib目录下拷入/usr/lib目录,否则命令无法运行。说明libospfd.so.0可能由ospf_vty.c编译生成或者相关。

安装完毕后先运行zebra(因为interface node 属于zebra进程),再运行vtysh.运行结果:

2Network使能过程

从ospf_vty.c中可以看到network使能命令的定义:

通过

VTY_GET_IPV4_PREFIX()

VTY_GET_OSPF_AREA_ID()

得到网络前缀(network prefix)和区域ID(area ID)。然后通过函数ospf_network_set()使能网段。

ospf_network_set() 中首先调用了route_node_get()用来得到ospf结构中network表(用于记录network使能的地址段)中与输入地址段匹配的结点(node)。如果该结点的info字段有值,说明该地址段已经被network使能过了,于是

/* There is already same network statement. */

route_unlock_node (rn);

return 0;

返回。否则在这个结点的info字段中添加该area,然后运行ospf_network_run()

ospf_network_run()中,首先判断router id是否存在,若不存在则通过

ospf_router_id_update()函数获得。获得路由器ID的规则是:

1. Statically assigned router ID is always the first choice.

2. If there is no statically assigned router ID, then try to stick

with the most recent value, since changing router ID's is very disruptive.

3. Last choice: just go with whatever the zebra daemon recommends.

1 如果有静态路由则优先使用静态路由作为路由器ID

2 如果没有分配静态路由ID则使用最近使用的路由器ID

3 如果以上都无法得到路由器ID,使用zebra中router_id_zebra指定的ID,router_id_zebra.该值在ospf进程启动时,在ospf_zebra_init()中得到一个初值。看样子好像是zebra进程传过来的值,没有再继续跟。

可以看到宏ALL_LIST_ELEMENTS_RO(list,node,data)的定义:

#define ALL_LIST_ELEMENTS_RO(list,node,data) \

(node) = listhead(list); \

(node) != NULL && ((data) = listgetdata(node), 1); \

(node) = listnextnode(node)

For循环的过程是从每个om->iflist上的node中取出om->iflist->node->data存入ifp(用于储存接口相关信息),由函数

ospf_network_run_interface (p, area, ifp);

调用。该循环作用是遍历所有接口,使能与p匹配的地址段。

ospf_network_run_interface (p, area, ifp)函数主要部分为:

/* if interface prefix is match specified prefix,

then create socket and join multicast group. */

for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) //遍历该接口上所有连接的地址段

{

struct prefix *addr;

if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))

continue;

addr = CONNECTED_ID(co);

/*如果符合输入地址段的接口地址并没有被network使能过,

*则创建一个ospf_interface结构体,付值后将该*/

if (p->family == co->address->family //为同种ip地址(ipv4或ipv6) && ! ospf_if_is_configured (area->ospf, &(addr->u.prefix4)) //该地址段并没有被使能

&& ospf_network_match_iface(co,p)) //ip地址段匹配

{

struct ospf_interface *oi;

oi = ospf_if_new (area->ospf, ifp, co->address); //在已经使能ospf(目前只能通过

network使能)的interface中寻找地

址段匹配的结点,找不到则新建结点 oi->connected = co;

oi->area = area;

oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4); //从接口的匹配地址段

结点上获得参数

oi->output_cost = ospf_if_get_output_cost (oi);

/* Add pseudo neighbor. */

ospf_nbr_add_self (oi); //将自己作为邻居信息的一部分添加到oi->nbrs->node->info

中,查找oi->nbrs->node的依据是接口地址段,找不到对应的

地址段则添加一个新的。

/* Relate ospf interface to ospf instance. */

oi->ospf = area->ospf;

/* update network type as interface flag */

/* If network type is specified previously,

skip network type setting. */

oi->type = IF_DEF_PARAMS (ifp)->type; //从结点默认参数中获得类型

ospf_area_add_if (oi->area, oi); //将结点链在area->oiflist链表里

/* if router_id is not configured, dont bring up

* interfaces.

* ospf_router_id_update() will call ospf_if_update

* whenever r-id is configured instead.

*/

if ((area->ospf->router_id.s_addr != 0)

&& if_is_operative (ifp))

ospf_if_up (oi);

}

}

3No network去使能

我们再看一下no network去使能的过程,主要由以下函数完成:

ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p, struct in_addr area_id)

该函数的函数体:

{

struct route_node *rn;

struct ospf_network *network;

struct external_info *ei;

struct listnode *node, *nnode;

struct ospf_interface *oi;

rn = route_node_lookup (ospf->networks, (struct prefix *)p); //在ospf->network中寻找于输入地

址段匹配的结点 if (rn == NULL)

return 0;

network = rn->info;

if (!IPV4_ADDR_SAME (&area_id, &network->area_id)) //若区域不匹配

return 0;

ospf_network_free (ospf, rn->info); //若匹配,从相关表中去掉结点,后面会再介绍 rn->info = NULL;

route_unlock_node (rn); //在route_node_lookup()中lock,因此在此unlock

/* Find interfaces that not configured already. */

for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) //遍历所有ospf过的接口(ospf->oiflist

上的结点)

{

int found = 0;

struct connected *co = oi->connected; //获得该接口上地址

if (oi->type == OSPF_IFTYPE_VIRTUALLINK)

continue;

for (rn = route_top (ospf->networks); rn; rn = route_next(rn)) //遍历所有network上的结点 {

if (rn->info == NULL)

continue;

if (ospf_network_match_iface(co,&rn->p)) //判断该接口上地址与network结点地址段

是否匹配,若有匹配则found置1,说明该

结点上还有被network使能的地址段 {

found = 1;

route_unlock_node (rn); //route_top(),route_next()中会lock(rn) break;

}

}

if (found == 0)

ospf_if_free (oi); //found==0说明该接口上没有network使能过

的地址段,将该结点从相关链表中去掉 }

/* Update connected redistribute. */

if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))

if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))

for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));

rn; rn = route_next (rn))

if ((ei = rn->info) != NULL)

if (!ospf_external_info_find_lsa (ospf, &ei->p))

if (ospf_distribute_check_connected (ospf, ei))

ospf_external_lsa_originate (ospf, ei);

return 1;

}

前面调用的函数ospf_network_free():

void

ospf_network_free (struct ospf *ospf, struct ospf_network *network)

{

ospf_area_check_free (ospf, network->area_id); //察看输入的area下还有没有活动的接口,如果没

有将该area从ospf->area中去掉。这里有个问题,

运行到这里时候符合ip地址段和area_id的

ospf_interface结构体到这里并没有从area的链上

面去掉,而是在后面的循环中由ospf_if_free()函

数去掉。因此本次空链的area在下次运行no

network时才会被free。如果只一次network和一次

no network时候可能会有未释放的指针。

ospf_schedule_abr_task (ospf);

XFREE (MTYPE_OSPF_NETWORK, network); //free开始XMALLOC()分配的指针

}

4Ip ospf cost命令实现过程

Ospf_init()中会创建一个interface 的list, 在每个接口的结构体中都有个info 的字段,其定义如下:

struct ospf_if_info

{

struct ospf_if_params *def_params;

struct route_table *params;

struct route_table *oifs;

unsigned int membership_counts[MEMBER_MAX]; /* multicast group refcnts */

};

然后通过ospf_if_new_hook()初始化对应的指针:

IF_OIFS (ifp) = route_table_init (); //ifp->info->oifs oifs链表保存已经ospf使能的interface IF_OIFS_PARAMS (ifp) = route_table_init (); //ifp->info->params 参数链表,是一个route table二叉

树papams->info也是个ospf_if_params结构。之所以设置

该字段的原因是因为每个接口除了有个默认的参数结构以

外还需要对于每个接口上配置的各个主次ip地址段分别对

应一个params,这些params以ip段为关键字存在这个route

table二叉树里面。

IF_DEF_PARAMS (ifp) = ospf_new_if_params (); //ifp->info->def_params 是一个ospf_if_params结构,保

存已经定义的一些参数及其默认值

再通过ospf_if_delete_hook()清空参数。

Ip ospf cost <0-65535>a,b,c,d的命令执行时,初始化params指针指向默认参数表。

params = IF_DEF_PARAMS (ifp);

如果输入了a,b,c,d:

params = ospf_get_if_params (ifp, addr); //按照地址a,b,c,d获得params表里面

ifp->info->params->node*->info(这个就是结点的

params),找到了就unlock node找不到就添加一个

node. Node如果unlock到0便从表中删除该node

ospf_if_update_params (ifp, addr); //按照地址获得oifs表里面的

ifp->info->oifs->node*->info->params, 把params

表里面对应这个地址的参数写入oifs里的这个params

字段中,红色部分是一个ospf_interface的指针*注:node代表链表中的某个结点,是通过top结点查下去找到的

这两个函数中分别调用了

route_node_get(struct route_table *table, struct prefix *p)

route_node_lookup(struct route_table *table, struct prefix *p)

都是用于遍历通过参数传进去的table找到地址字段为p的结点并返回,区别是get函数找不到遍会创建结点,lookup函数只寻找。

ospf_if_recalculate_output_cost()函数遍历ospf过的interface, 修改他们的output_cost字段:

newcost = ospf_if_get_output_cost (oi); //计算得到新的cost

if (oi->output_cost != newcost) //如果新的cost变化了

{

oi->output_cost = newcost; //更新output_cost字段

ospf_router_lsa_timer_add (oi->area); //重新设置router_lsa的timer

}

5添加接口使能命令功能ip ospf enable area a.b.c.d|<0-65535>

本节使用1.4节中添加的命令完成对应功能。

5.1常用结构体

struct interface

{

……

struct list *connected; //该字段用于储存配置在该接口下的ip地址,该字段为list类型,与ospf_interface结构体

中connected字段类型不同,该listnode上的data字段指向一个connected结构体。结构

体中记录着接口上配置的主ip和次ip,这样的作用是可以在同一个接口上配置多个网

段。

void *info; //这个字段在第4节中已经介绍过了,包括params, def_params, oifs三个树结构,主要

用于保存参数设置,详细参考page12

……

}

struct ospf

{

……

struct route_table *networks; //每个list的info(route_node中的字段)指向一个ospf_network结构体,保存network使

能过的网段

struct list *areas; //每个list的data(listnode中的字段)指向一个ospf_area结构体,保存ospf使能过得area struct list *oiflist; //ospf使能的Interface链表

……

}

struct ospf_interface

{

struct ospf *ospf; //属于哪个ospf

struct ospf_area *area; //设置的那个area

struct interface *ifp; //属于哪个接口

……

struct prefix *address; /* 接口地址段*/

struct connected *connected; /* 连接的地址*/

struct ospf_if_params *params; /*用于保存ospf 使能过得interface上设置的参数,如果没在这个oi上设置

则使用ifp接口上的default设置*/

……

}

struct ospf_area //该结构体为ospf使能后才会赋值并链接在对应链表中的结构

{

struct ospf *ospf; //属于哪个ospf

struct list *oiflist; //该area中ospf使能的接口列表(链表)

struct in_addr area_id; //对应的area ID

……

}

struct ospf_network

{

struct in_addr area_id;

int format;

}

struct connected

{

struct interface *ifp; //属于哪个接口

……

struct prefix *address; //连接网段地址

struct prefix *destination; //可能是网络地址或者peer地址,如果设置了ZEBRA_IFA_PEER标志则使用该地

址,否则使用address

……

}

struct prefix

{

u_char family; //协议类型IPV4 IPV6

u_char prefixlen; //掩码长度

union //地址,通过联合体可以储存IPV4或IPV6的地址

{

u_char prefix;

struct in_addr prefix4;

#ifdef HAVE_IPV6

struct in6_addr prefix6;

#endif /* HAVE_IPV6 */

struct

{

struct in_addr id;

struct in_addr adv_router;

} lp;

u_char val[8];

} u __attribute__ ((aligned (8)));

};

各个结构体间都有一定的关系,主要通过interface, ospf, area这三个结构体联系起来。

5.2功能实现

首先根据功能修改命令定义:

DEFUN (interface_ospf_enable,

ip_ospf_enable_cmd,

"ip ospf enable area (A.B.C.D|<0-4294967295>)",

"OSPF interface commands\n" //introduce to ospf cmd

"enable ip ospf router\n" // introduce to enable cmd

"set the area\n" //introduce to area cmd

"area ID\n") //introduce to the number after area cmd {

……

}

函数体:

{

int format;

struct in_addr area_id;

struct interface *ifp = vty->index;

struct ospf_area *area;

struct listnode *cnode;

struct connected *co;

int ret = OSPF_AREA_ID_FORMAT_ADDRESS;

struct ospf *ospf = ospf_get (); //首先得到当前的ospf指针,没有的话便新创建一个VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); //从命令中得到area

area = ospf_area_get (ospf, area_id, ret); //从ospf的area字段中找到对应的area,没有的

话便新创建一个

for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) //遍历该接口下所有连接

的地址段

{

struct prefix *addr;

if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))

continue;

addr = CONNECTED_ID(co);

if (! ospf_if_is_configured (area->ospf, &(addr->u.prefix4))) //在area->ospf->oiflist中寻

找该地址段,若存在说明该

地址段已经被ospf使能过

了,不存在说明还没有ospf

{

struct ospf_interface *oi; //若在area->ospf->oiflist中没

oi = ospf_if_new (area->ospf, ifp, co->address); //首先在ifp->info->oifs里创建

该结点,并将结点链在

ospf->oiflist上

oi->connected = co;

oi->area = area;

/*从ifp->info->params中获得参数*/

oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);

oi->output_cost = ospf_if_get_output_cost (oi);

ospf_nbr_add_self (oi);

oi->ospf = area->ospf;

oi->type = IF_DEF_PARAMS (ifp)->type;

ospf_area_add_if (oi->area, oi); //将该接口链在area的链表中

/* if router_id is not configured, dont bring up

* interfaces.

* ospf_router_id_update() will call ospf_if_update

* whenever r-id is configured instead.

*/

if ((area->ospf->router_id.s_addr != 0)

&& if_is_operative (ifp))

ospf_if_up (oi); //添加ISM_InterfaceUp event开始ospf服务}

}

Android源代码结构分析

目录 一、源代码结构 (2) 第一层次目录 (2) bionic目录 (3) bootloader目录 (5) build目录 (7) dalvik目录 (9) development目录 (9) external目录 (13) frameworks目录 (19) Hardware (20) Out (22) Kernel (22) packages目录 (22) prebuilt目录 (27) SDK (28) system目录 (28) Vendor (32)

一、源代码结构 第一层次目录 Google提供的Android包含了原始Android的目标机代码,主机编译工具、仿真环境,代码包经过解压缩后,第一级别的目录和文件如下所示: . |-- Makefile (全局的Makefile) |-- bionic (Bionic含义为仿生,这里面是一些基础的库的源代码) |-- bootloader (引导加载器),我们的是bootable, |-- build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具) |-- dalvik (JAVA虚拟机) |-- development (程序开发所需要的模板和工具) |-- external (目标机器使用的一些库) |-- frameworks (应用程序的框架层) |-- hardware (与硬件相关的库) |-- kernel (Linux2.6的源代码) |-- packages (Android的各种应用程序) |-- prebuilt (Android在各种平台下编译的预置脚本) |-- recovery (与目标的恢复功能相关) `-- system (Android的底层的一些库)

层次分析法实现代码(MATLAB)

%% AHP weight calculation %%data input clc clear all A =[1 3 5 7 9 5;1/3 1 3 9 3 3;1/5 1/3 1 3 3 1/3;1/7 1/9 1/3 1 5 1/3;1/9 1/3 1/3 1/5 1 1/3;1/5 1/3 1 3 3 1]; %%Consistency calculation and weight vector calculation [n,n] = size(A); [v,d] = eig(A); r = d(1,1); CI = (r-n)/(n-1); RI = [0 0 0.58 0.90 1.12 1.24 1.32 1.41 1.45 1.49 1.52 1.54 1.56 1.58 1.59]; CR = CI/RI(n); if CR<0.10 CR_Result = 'pass'; else CR_Result = 'no pass'; end % % Weight vector calculation w = v(:,1)/sum(v(:,1));

w = w'; % % output disp('The judgment matrix weight vector calculation report:'); disp('coincidence indicator:');disp(num2str(CI)); disp('Consistency ratio:');disp(num2str(CR)); disp(' Consistency test results:');disp(CR_Result); disp('eigenvalue:');disp(num2str(r)); disp('weight vector:');disp(num2str(w));

层次分析法矩阵权重和,根,特征值法,c语言计算

// ???óè¨??2010.cpp : ?¨ò?????ì¨ó|ó?3ìDòμ?è??úμ??£ #include "stdafx.h" //vs2010ò?é?°?±?óD′??? #include"stdio.h" #include"math.h" void sum(int N,double a[13][13]) { double sum[13]={0},pro[13]={0}; int i,j,k; for(i=0;i

} for(k=0;k

yaffs2文件系统制作

交叉编译器ARM-Linux-gcc4.1.2 开发板TX2440A Busybox-1.15.1.tar.bz2(在Linux中被称为瑞士军刀) mkyaffs2image工具 首先创建一个名字为root_2.6.31的文件夹,在其中创建如下文件夹 etc bin var dev home lib mnt proc root sbin sys tmp usr opt共14个文件夹 解压Busybox tar xjvf busybox 进入源目录,修改Makefile 第164行,CROSS_COMPILE=arm-linux- 第190行,ARCH=arm 执行#make men onfig进行配置 配置选项大部分都是保持默认的,只需要注意选择以下这几个选项,其他的选项都不用动:Busybox Setting---> Build Options---> [*]Build Busybox as a static binary(no shared libs) [*]Build with Large File Support(for accessing files>2GB) Installation Options--->

(./_install)Busybox installation prefix 进入这个选项,输入busybox的安装路径,如:../rootfs Busybox Library Tuning---> [*]vi-style line editing commands [*]Fancy shell prompts 要选择这个选项:“Fancy shell prompts”,否则挂载文件系统后,无法正常显示命令提示符:“[\u@\h\W]#” 配置完成以后 执行#make #make install 然后就会在上一级目录下生成rootfs文件夹,里面包含几个文件夹/bin/sbin/usr linuxrc 把这些文件全部复制到刚建好的root_2.6.31目录下, #cp–rf*../root_2.6.31 在dev目录下,创建两个设备节点: #mknod console c51 #mknod null c13 然后进入自己建立的etc目录 拷贝Busybox-1.15.2/examples/bootfloopy/etc/*到当前目录下。 #cp-r../../busybox-1.15.2/examples/bootfloopy/etc/*./ 包括文件:fstab init.d inittab profile

层次分析法

层次分析法简介 层次分析法的特点是在对复杂的决策问题的本质、影响因素及其内在关系等进行深入分析的基础上,利用较少的定量信息使决策的思维过程数学化,从而为多目标、多准则或无结构特性的复杂决策问题提供简便的决策方法。尤其适合于对决策结果难于直接准确计量的场合。 在现实世界中,往往会遇到决策的问题,比如如何选择旅游景点的问题,选择升学志愿的问题等等。在决策者作出最后的决定以前,他必须考虑很多方面的因素或者判断准则,最终通过这些准则作出选择。比如选择一个旅游景点时,你可以从宁波、普陀山、浙西大峡谷、雁荡山和楠溪江中选择一个作为自己的旅游目的地,在进行选择时,你所考虑的因素有旅游的费用、旅游地的景色、景点的居住条件和饮食状况以及交通状况等等。这些因素是相互制约、相互影响的。我们将这样的复杂系统称为一个决策系统。这些决策系统中很多因素之间的比较往往无法用定量的方式描述,此时需要将半定性、半定量的问题转化为定量计算问题。层次分析法是解决这类问题的行之有效的方法。层次分析法将复杂的决策系统层次化,通过逐层比较各种关联因素的重要性来为分析、决策提供定量的依据。 层次分析法定义 所谓层次分析法,是指将一个复杂的多目标决策问题作为一个系统,将目标分解为多个目标或准则,进而分解为多指标(或准则、约束)的若干层次,通过定性指标模糊量化方法算出层次单排序(权数)和总排序,以作为目标(多指标)、多方案优化决策的系统方法,称为层次分析法。 层次分析法是将决策问题按总目标、各层子目标、评价准则直至具体的备投方案的顺序分解为不同的层次结构,然后得用求解判断矩阵特征向量的办法,求得每一层次的各元素对上一层次某元素的优先权重,最后再加权和的方法递阶归并各备择方案对总目标的最终权重,此最终权重最大者即为最优方案。这里所谓“优先权重”是一种相对的量度,它表明各备择方案在某一特点的评价准则或子目标,标下优越程度的相对量度,以及各子目标对上一层目标而言重要程度的相对量度。层次分析法比较适合于具有分层交错评价指标的目标系统,而且目标值又难于定量描述的决策问题。其用法是构造判断矩阵,求出其最大特征值。及其所对应的特征向量W,归一化后,即为某一层次指标对于上一层次某相关指标的相对重要性权值。层次分析法的优点 运用层次分析法有很多优点,其中最重要的一点就是简单明了。层次分析法不仅适用于存在不确定性和主观信息的情况,还允许以合乎逻辑的方式运用经验、洞察力和直觉。也许层次分析法最大的优点是提出了层次本身,它使得买方能够认真地考虑和衡量指标的相对重要性。 层次分析法的基本步骤 建立层次结构模型 在深入分析实际问题的基础上,将有关的各个因素按照不同属性自上而下地分解成若干层次,同一层的诸因素从属于上一层的因素或对上层因素有影响,同时又支配下一层的因素或受到下层因素的作用。最上层为目标层,通常只有1个因素,最下层通常为方案或对象层,中间可以有一个或几个层次,通常为准则或指标层。当准则过多时(譬如多于9个)应进一步分解出子准则层。

linux-2.6.18移植

Linux-2.6.18移植 有了我们的交叉编译环境和我们先前学的内核基础知识,下面我们就开始我们的内核移植了,我们所用的是博创的 S3C2410 。 关于 linux-2.6.18.tar.bz2 的下载网站先前我们说过,我们要先到该官方网站上去下载一个全新的内核。 [root@Binnary ~ ]# tar –jxvf linux-2.6.18.tar.bz2 [root@Binnary ~ ]# make mrproper 如果你是新下载的内核,那这一步就不用了。但如果你用的是别人移植好的内核,那最好在编译内核之前先清除一下中间文件,因为你们用来编译内核的交叉编译工具可能不同。 第一步:修改Makefile文件 将 改为 第二步:修改分区设置信息 我们要先在BootLoader中查看相应的分区信息 vivi>help 然后修改内核源码中的分区信息。分区信息文件在 a rch/arm/mach-s3c2410/common-smdk.c 将其中的

改为如下内容:

第三步:内核通过 BootLoader把数据写入NAND Flash,而vivi的ECC效验算法和内核的不同,内核的效验码是由NAND Flash控制器产生的,所以在此必须禁用NAND Flash ECC。所以我们就要修改 drivers/mtd/nand/s3c2410.c 这个文件。将 中的 chip->ecc.mode = NAND_ECC_SOFT ,改为如下 chip->ecc.mode = NAND_ECC_NONE。

只此一处。 第四步:下面是devfs的问题,因为2.6.12内核以后取消了devfs的配置选项,缺少了它内核会找不到mtdblock设备。所以我们需要修改 fs/Kconfig 文件,或者是从2.6.12的fs/Kconfig中拷贝下面几项到2.6.18的fs/Kconfig中去,我们采用修改的方法来完成。 修改 fs/Kconfig支持devfs 。 在Pseudo filesystems 主菜单的最后添加我们所要的内容。 第五步:文件系统的支持 Yaffs 文件系统 YAFFS文件系统简介 YAFFS,Yet Another Flash File System,是一种类似于JFFS/JFFS2的专门为Flash设计 的嵌入式文件系统。与JFFS相比,它减少了一些功能,因此速度更快、占用内存更少。 YAFFS和JFFS都提供了写均衡,垃圾收集等底层操作。它们的不同之处在于: (1)、JFFS是一种日志文件系统,通过日志机制保证文件系统的稳定性。YAFFS仅仅 借鉴了日志系统的思想,不提供日志机能,所以稳定性不如JAFFS,但是资源占用少。 (2)、JFFS中使用多级链表管理需要回收的脏块,并且使用系统生成伪随机变量决定 要回收的块,通过这种方法能提供较好的写均衡,在YAFFS中是从头到尾对块搜索, 所以在垃圾收集上JFFS的速度慢,但是能延长NAND的寿命。 (3)、JFFS支持文件压缩,适合存储容量较小的系统;YAFFS不支持压缩,更适合存 储容量大的系统。 YAFFS还带有NAND芯片驱动,并为嵌入式系统提供了直接访问文件系统的API,用 户可以不使用Linux中的MTD和VFS,直接对文件进行操作。NAND Flash大多采用 MTD+YAFFS的模式。MTD( Memory Technology Devices,内存技术设备)是对Flash 操作的接口,提供了一系列的标准函数,将硬件驱动设计和系统程序设计分开。 Yaffs 文件系统内核没有集成,可以对其主页下载: https://www.sodocs.net/doc/ff17850605.html,/cgi-bin/viewcvs.cgi/#dirlist

基于Matlab的层次分析法及其运用浅析

基于Matlab的层次分析法及其运用浅析 本文通过使用Matlab软件进行编程,在满足同一层次中各指标对所有的下级指标均产生影响的假定条件下,实现了层次分析法的分析运算。本程序允许用户自由设定指标层次结构内的层次数以及各层次内的指标数,通过程序的循环,用户只需输入判断矩阵的部分数据,程序可依据层次分析法的计算流程进行计算并作出判断。本程序可以方便地处理层次分析法下较大的运算量,解决层次分析法的效率问题,提高计算机辅助决策的时效性。 标签:Matlab层次分析法判断矩阵决策 在当前信息化、全球化的大背景下,传统的手工计算已不能满足人们高效率、高准确度的决策需求。因此计算机辅助决策当仁不让地成为了管理决策的新工具、新方法。基于此,本文在充分发挥计算机强大运算功能的基础上,选用美国MathWorks公司的集成数学建模環境Matlab R2009a作为开发平台,使用M语言进行编程,对计算机辅助决策在层次分析法中的运用进行讨论。试图通过程序实现层次分析法在计算机系统上的运用,为管理决策探索出新的道路。 1 层次分析法的计算流程 根据层次分析法的相关理论,层次分析法的基本思想是将复杂的决策问题进行分解,得到若干个下层指标,再对下层指标进行分解,得到若干个再下层指标,如此建立层次结构模型,然后根据结构模型构造判断矩阵,进行单排序,最后,求出各指标对应的权重系数,进行层次总排序。 1.1 构造层次结构模型在进行层次分析法的分析时,最主要的步骤是建立指标的层次结构模型,根据结构模型构造判断矩阵,只有判断矩阵通过了一致性检验后,方可进行分析和计算。其中,结构模型可以设计成三个层次,最高层为目标层,是决策的目的和要解决的问题,中间层为决策需考虑的因素,是决策的准则,最低层则是决策时的备选方案。一般来讲,准则层中各个指标的下级指标数没有限制,但在本文中设计的程序尚且只能在各指标具有相同数量的下级指标的假定下,完成层次分析法的分析,故本文后文选取的案例也满足这一假定。 1.2 建立判断矩阵判断矩阵是表示本层所有因素针对上一层某一个因素的相对重要性的比较给判断矩阵的要素赋值时,常采用九级标度法(即用数字1到9及其倒数表示指标间的相对重要程度),具体标度方法如表1所示。 1.3 检验判断矩阵的一致性由于多阶判断的复杂性,往往使得判断矩阵中某些数值具有前后矛盾的可能性,即各判断矩阵并不能保证完全协调一致。当判断矩阵不能保证具有完全一致性时,相应判断矩阵的特征根也将发生变化,于是就可以用判断矩阵特征根的变化来检验判断的一致性程度。在层次分析法中,令判断矩阵最大的特征值为λmax,阶数为n,则判断矩阵的一致性检验的指标记为:

层次分析法确定绩效考核指标权重

表4-2 某厂运行部年度部门级绩效考核指标 (1)由1-9比例标度法分别对每一层次的评价指标的相对重要性进行定性描述,确定两两比较判断矩阵。 一级考核指标相对于总的考核指标所得两两比较判断矩阵如下: ????? ???? ???=13/17/1315/1751321321V V V V V V V A 二级考核指标相对于其所属一级考核指标所得的两两判断矩阵分别如下所示: ????? ???? ???=13/15/1313/153113121113121111v v v v v v V B

?? ? ?? ?? ?????????=12/14/15/1213/14/14313/15431242322212423222122v v v v v v v v V B 33132331321 31/31V v v B v v ????=?????? (2)运用和积法(方根法)求解各判断矩阵,得出单一准则下各级考核指标的相对权重。 1)一级指标两两判断矩阵A 的求解 一级指标的权重向量: w =(1w ,2w ,3w )T =(0.637,0.258,0.103)T 最大特征根:3 max 1()3i i i Aw w λ==∑ =3.037 一致性检验: 3.0373 0.018531 CI -= =-,0.58RI = 则0.0320.1CR =<,说明判断矩阵A 具有满意的一致性。 2)二级评价指标的两两判断矩阵的求解: ①判断矩阵1B 求解结果如下: 1B 下二级指标的权重向量: 1w =(11w ,21w ,31w )T =(0.6548,0.2499,0.0953)T 最大特征根:3 1max 1()3i i i B w w λ==∑ =3.0182 一致性检验: 3.01823 0.009131 CI -= =-,0.58RI = 则0.0160.1CR =<,这表明判断矩阵具有非常令人满意的一致性。 ②判断矩阵B 2求解结果如下: 权重向量: 2w =(21w ,22w ,32w ,24w )T =(0.5318,0.2701,0.1221,0.0760)T 最大特征根:4 2max 1()4i i i B w w λ==∑ =4.0753 一致性检验: 4.07534 0.025141 CI -= =-,0.9RI = 则0.0280.1C R =< ,这说明判断矩阵B 2具有令人满意的一致性。 ③判断矩阵B 3求解结果如下: 权重向量:

Yaffs2文件系统中对NAND Flash磨损均衡的改进

Yaffs2文件系统中对NAND Flash磨损均衡的改进 摘要:针对以NAND Flash为存储介质时Yaffs2文件系统存在磨损均衡的缺陷,通过改进回收块选择机制,并在数据更新中引入冷热数据分离策略,从而改善NAND Flash的磨损均衡性能。实验借助Qemu软件建立Linux嵌入式仿真平台,从总擦除次数、最大最小擦除次数差值和块擦除次数标准差等方面进行对比。实验结果表明,在改进后的Yaffs2文件系统下NAND Flash的磨损均衡效果有明显提升,这有益于延长NAND Flash的使用寿命。 关键词: Yaffs2文件系统;NAND Flash;垃圾回收;冷热数据 0 引言 NAND Flash存储设备与传统机械磁盘相比,具有体积小、存储密度高、随机存储和读写能力强、抗震抗摔、功耗低等特点[1]。它被广泛用于智能手机、车载智能中心、平板电脑等智能终端中。近年来,以NAND Flash为存储介质的固态硬盘也得到越来越多的应用。目前Yaffs2文件系统(Yet Another Flash File System Two,Yaffs2)[1]是使用最多、可移植性最好的专用文件系统,在安卓、阿里云OS、Linux等嵌入式系统中都有使用。在Yaffs2文件系统下以NAND Flash为存储介质时存在磨损均衡的缺陷,可通过对回收块选择机制作改进和引入冷热数据分离策略来提高磨损均衡的效果。 1 Yaffs2和Nand Flash关系 这里以使用最多的Linux操作系统为实践,将Yaffs2文件系统移植到Linux操作系统中。Linux系统通常可以分为3层:应用层、内核层和设备层,其中支持NAND Flash设备的Yaffs2文件系统属于内核层,。 最上层用户应用程序通过VFS(Virtual File System)提供的统一接口,将数据更新等文件操作传递给Yaffs2。VFS代表虚拟文件系统,它为上层应用提供统一的接口。有了这些接口,应用程序只用遵循抽象后的访问规则,而不必理会底层文件系统和物理构成上的差异。然后Yaffs2通过MTD(Memory Technology Device)提供的统一访问接口对NAND Flash进行读、写和擦除操作,从而完成数据的更新或者存储操作。MTD代表内存技术设备,它为存储设备提供统一访问的接口。最终,在NAND Flash上以怎样的格式组织和存储数据由Yaffs2文件系统决定。 NAND Flash由若干块(block)组成,每个块又是由若干页(page)组成,页中含有数据区和附加区。NAND Flash的页根据状态不同,可以分为有效页、脏页、空闲页。有效页中存放有效数据,脏页中存放无效数据,空闲页是经过擦除后可以直接用于写入数据的页。NAND Flash在写入数据前需要执行擦除操作,因此数据不能直接在相同的位置更新。当一个页中数据需要更新时,必须将该页中有效数据拷贝到其他空闲页上再更新,并将原来页上的数据置为无效。随着时间的推移,许多无效页累积在存储器中使得空闲页逐渐减少。当存储器中的空闲空间不足时,启动垃圾回收操作,利用回收块选择机制从待回收块中选取满足要求的块来擦除,从而得到足够的空闲空间。NAND Flash中块的擦除次数有限,通常为10 000次~100 000次[2]。当某个块的擦除次数超过使用寿命时,该块将无法正常用于数据存储。因此,垃圾回收应利用合理的回收块选择机制,从待回收块中找到回收后能产生良好磨损均衡效果且付出较少额外代价的块来回收,从而获得足够的空闲空间用于数据更新操作。 2 Yaffs2在磨损均衡方面的缺陷 Yaffs2中回收块的选择机制[3]是从待回收块中找到有效数据最少的块来回收。回收过程中,Yaffs2能够减少有效数据的额外读和写操作。当数据更新处于均匀分布的情况下,Yaffs2表现出较好的磨损均衡效果。 但是,通常情况下数据的更新频率不同,有些数据经常更新,而有些数据很少更新。经

Matlab求解层次分析法程序代码【求解步骤+代码】

层次分析法 1)建立层次结构模型: (2)构造判断矩阵 判断矩阵() ij A a =应为正互反矩阵,而且ij a 的判断如下(1~9尺度法): (3)单层排序及一致性检验 1、单层排序 求解判断矩阵A 的最大特征值max λ,再由最大特征值求出对应的特征向量

ω()max A ωλω=,并将ω标准化,即为同一层相对于上一层某一因素的权重,根据此 权重的大小,便可确定该层因素的排序。

2、一致性检验 取一致性指标max 1 n CI n λ-= -,(n 为A 的阶数) 令CR RI = ,若0.1CR <,则认为A 具有一致性。 否则,需要对A 进行调整,直到具有满意的一致性为止。 (4)层次总排序及一致性检验 假定准则层12,,,n C C C 排序完成,其权重分别为12,, ,n a a a ,方案层P 包含m 个方 案:12,, ,m P P P 。其相对于上一层的()1,2, ,j C j n =对方案层P 中的m 个方案进行单层排序,其排序权重记为12,,,j j mj b b b ()1,2, ,j n =,则方案层P 中第i 个方案Pi 的总 排序权重为 1 n j ij j a b =∑,见下表: 从而确定层的排序。 例: 纯文本文件txt3.txt 中的数据格式如下: 1 1 1 4 1 1/ 2 1 1 2 4 1 1/2 1 1/2 1 5 3 1/2 1/ 4 1/4 1/ 5 1 1/3 1/3 1 1 1/3 3 1 1 2 2 2 3 3 1 1 1/4 1/2

4 1 3 2 1/ 3 1 1 1/4 1/5 4 1 1/2 5 2 1 1 3 1/3 1/3 1 1/7 3 7 1 1 1/3 5 3 1 7 1/5 1/7 1 1 1 7 1 1 7 1/7 1/7 1 1 7 9 1/7 1 1 1/9 1 1 matlab程序: >> fid=fopen('txt3.txt','r'); n1=6;n2=3; a=[]; for i=1:n1 tmp=str2num(fgetl(fid)); a=[a;tmp]; %读准则层判断矩阵 end for i=1:n1 str1=char(['b',int2str(i),'=[];']); str2=char(['b',int2str(i),'=[b',int2str(i),';tmp];']); eval(str1); for j=1:n2 tmp=str2num(fgetl(fid)); eval(str2); %读方案层的判断矩阵 end end ri=[0,0,0.58,0.90,1.12,1.24,1.32,1.41,1.45]; %一致性指标[x,y]=eig(a); lamda=max(diag(y)); num=find(diag(y)==lamda); w0=x(:,num)/sum(x(:,num)); cr0=(lamda-n1)/(n1-1)/ri(n1) for i=1:n1 [x,y]=eig(eval(char(['b',int2str(i)]))); lamda=max(diag(y)); num=find(diag(y)==lamda);

2-Linux

Linux-2.6.32.2内核在mini2440上的移植(二)---yaffs2文件系统移植 移植环境(红色粗字体字为修改后内容,蓝色粗体字为特别注意内容) 2.1, yaffs2文件系统移植 【1】获取yaffs2 源代码 现在大部分开发板都可以支持yaffs2 文件系统,它是专门针对嵌入式设备,特别是使用nand flash 作为存储器的嵌入式设备而创建的一种文件系统,早先的yaffs 仅支持小页(512byte/page)的nand flash,现在的开发板大都配备了更大容量的nand flash,它们一般是大页模式的(2K/page),使用yaffs2 就可以支持大页的nand flash,下面是yaffs2 的移植详细步骤。 在https://www.sodocs.net/doc/ff17850605.html,/node/346可以下载到最新的yaffs2 源代码,需要使用git工具( 安装方法见Git版本控制软件安装与使用),在命令行输入: [root@localhost ~]# cd ./linux-test [root@localhost linux-test]# git clone git://https://www.sodocs.net/doc/ff17850605.html,/ya ffs2 Cloning into yaffs2... remote: Counting objects: 6592, done. remote: Compressing objects: 100% (3881/3881), done. remote: Total 6592 (delta 5237), reused 3396 (delta 2642) Receiving objects: 100% (6592/6592), 3.34 MiB | 166 KiB/s, d one. Resolving deltas: 100% (5237/5237), done.

AHP层次分析法详细讲解

AHP层次分析法详细讲解 。它是一种定性和定量相结合的、系统化、层次化的分析方法。由于它在处理复杂的决策问题上的实用性和有效性很快在世界范围得到重视。它的应用已遍及经济计划和管理、能源政策和分配、行为科学、军事指挥、运输、农业、教育、人才、医疗和环境等领域。 层次分析法的基本思路与人对一个复杂的决策问题的思维、判断过程大体上是一样的。不妨用假期旅游为例假如有3个旅游胜地A、B、C供你选择你会根据诸如景色、费用和居住、饮食、旅途等一些准则去反复比较这3个候选地点首先你会确定这些准则在你的心目中各占多大比重如果你经济宽绰、醉心旅游自然分别看重景色而平素俭朴或手头拮据的人则会优先考虑费用中老年旅游者还会对居住、饮食等寄以较大关注。其次你会就每一个准则将3个地点进行对比譬如A 景色最好B次之B费用最低C次之C居住等较好等等。最后你要将这两个层次的比较判断进行综合在A、B、C中确定哪个作为最佳地点。 层次分析法的基本步骤 1、建立层次结构模型。在深入分析实际问题的基础上将有关的各个因素按照不同属性自上而下 2 / 8 AHP指南-层次分析法详解地分解成若干层次同一层的诸因素从属于上一层的因素或对上层因素有影响同时又支配下一层的因素或受到下层因素的作用。最上层为目标层通常只有1个因素最下层通常为方案或对象层中间可以有一个或几个层次通常为准则或指标层。当准则过多时譬如多于9个应进一步分解出子准则层。 2、构造成对比较阵。从层次结构模型的第2层开始对于从属于或影响上一层每个因素的同一层诸因素用成对比较法和1—9比较尺度构追成对比较阵直到最下层。 3、计算权向量并做一致性检验。对于每一个成对比较阵计算最大特征根及对应特征向量利用一致性指标、随机一致性指标和一致性比率做一致性检验。若检验通过特征向量归一化后即为权向量若不通过需重新构追成对比较阵。 4、计算组合权向量并做组合一致性检验。计算最下层对目标的组合权向量并根据公式做组合一致性检验若检验通过则可按照组合权向量表示的结果进行决策否则需要重新考虑模型或重新构造那些一致性比率较大的成对比较阵。 层次分析法的优点运用层次分析法有很多优点其中最重要的一点就是简单明了。层次分析法不仅适用于存在不确定性和主观信息的情况还允许以合乎逻辑的方式运用经验、洞察力和直觉。也许层次分析法最大的优点是提出了层次本身它使得买方能够认真地考虑和衡量指标的相对重要性。 建立层次结构模型将问题包含的因素分层最高层解决问题的目的中间层实现总目标而采取的各种措施、必须考虑的准则等。也可称策略层、约束层、准则层等最低层用于解决问题的各种措施、方案等。把各种所要考虑的因素放在适当的层次内。用层次结构图清晰地表达这些因素的关系。 〔例1〕购物模型某一个顾客选购电视机时对市场正在出售的四种电视机考虑了八项准则作为评估依据建立层次分析模型如下 3 / 8 AHP指南-层次分析法详解〔例2〕选拔干部模型对三个干部候选人y1、y2 、y3按选拔干部的五个标准品德、才能、资历、年龄和群众关系构成如下层次分析模型假设有三个干部候选人y1、y2 、y3按选拔干部的五个标准品德才能资历年龄和群众关系构成如下层次分析模型构造成对比较矩阵比较第 i 个元素与第 j 个元素相对上一层某个因素的重要性时使用数量化的相对权重aij来描述。设共有 n 个元素参与比较则称为成对比较矩阵。

层次分析法可行性研究

层次分析法可行性研究 层次分析法逻辑严密,可以很好地克服在决策过程中主观因素的影响,应用层次分析法,可以计算各个因素对决策结果的权重,反映各个因素的重要程度,优化方案的选择。分析方法自下到上逐步分析,从单排序到总权重,是具有较高精度的判断方法。但是层次分析法只能是在已有的方案中择优选择,不能提出新的策略,这是在应用中的局限性。 可以看出,层次分析法具有很多优点,如:通过分析复杂问题中的不同单之间相互关系,使之层次化、条理化;将专家对每层因素相对重要程度的主观评价通过两两比较定量化,然后利用数学方法权值来反映全部因素的相对重要程度;通过所有层次之间的总排序,确定所有方案的排序;利用组合权向量分配目标可靠性。但是它的缺点也是非常明显的,由于过于依赖专家构造两两比较矩阵,同时矩阵运算非常复杂,导致此方法效率较低,同时由于完全依赖主观评价,没有利用现有的客观数据,使得分配结果主观性过强。 1.系统性的分析方法 层次分析法把研究对象作为一个系统,按照分解、比较判断、综合的思维方式进行决策,成为继机理分析、统计分析之后发展起来的系统分析的重要工具。系统的思想在于不割断各个因素对结果的影响,而层次分析法中每一层的权重设置最后都会直接或间接影响到结果,而且在每个层次中的每个因素对结果的影响程度都是量化的,非常清晰、明确。这种方法尤其可用于对无结构特性的系统评价以及多目标、多准则、多时期等的系统评价。 2.简洁实用的决策方法 这种方法既不单纯追求高深数学,又不片面地注重行为、逻辑、推理,而是把定性方法与定量方法有机地结合起来,使复杂的系统分解,能将人们的思维过程数学化、系统化,便于人们接受,且能把多目标、多准则又难以全部量化处理的决策问题化为多层次单目标问题,通过两两比较确定同一层次元素相对上一层次元素的数量关系后,最后进行简单的数学运算。即使是具有中等文化程度的人也可了解层次分析的基本原理和掌握它的基本步骤,计算也经常简便,并且所得结果简单明确,容易为决策者了解和掌握。

层次分析法计算权重在matlab中的实现

信息系统分析与设计作业 层次分析法确定绩效评价权重在matlab中的实现 小组成员:孙高茹、王靖、李春梅、郭荣1 程序简要概述 编写程序一步实现评价指标特征值lam、特征向量w以及一致性比率CR的求解。 具体的操作步骤是:首先构造评价指标,用专家评定法对指标两两打分,构建比较矩阵,继而运用编写程序实现层次分析法在MATLAB中的应用。 通过编写MATLAB程序一步实现问题求解,可以简化权重计算方法与步骤,减少工作量,从而提高人力资源管理中绩效考核的科学化电算化。 2 程序在matlab中实现的具体步骤 function [w,lam,CR] = ccfx(A) %A为成对比较矩阵,返回值w为近似特征向量 % lam为近似最大特征值λmax,CR为一致性比率 n=length(A(:,1)); a=sum(A); B=A %用B代替A做计算 for j=1:n %将A的列向量归一化 B(:,j)=B(:,j)./a(j); end s=B(:,1); for j=2:n s=s+B(:,j); end c=sum(s);%计算近似最大特征值λmax w=s./c; d=A*w lam=1/n*sum((d./w)); CI=(lam-n)/(n-1);%一致性指标 RI=[0,0,0.58,0.90,1.12,1.24,1.32,1.41,1.45,1.49,1.51];%RI为随机一致

性指标 CR=CI/RI(n);%求一致性比率 if CR>0.1 disp('没有通过一致性检验'); else disp('通过一致性检验'); end end 3 案例应用 我们拟构建公司员工绩效评价分析权重,完整操作步骤如下: 3.1构建的评价指标体系 我们将影响员工绩效评定的指标因素分为:打卡、业绩、创新、态度与品德。 3.2专家打分,构建两两比较矩阵 A = 1.0000 0.5000 3.0000 4.0000 2.0000 1.0000 5.0000 3.0000 0.3333 0.2000 1.0000 2.0000 0.2500 0.3333 0.5000 1.0000 3.3在MATLAB中运用编写好的程序实现 直接在MATLAB命令窗口中输入 [w,lam,CR]=ccfx(A) 继而直接得出 d = 1.3035 2.0000 0.5145 0.3926 w = 0.3102 0.4691 0.1242 0.0966 lam =4.1687

使用yaffs2img工具制作Android刷机包教程

制作刷机包 打开‘yaffs2img浏览器’,点击左上角的‘选取yaffs2文件’选择你刚刚复制出来的 files文件夹里的system.img 先来认识一下这个软件 1.定制软件的提取(此部和制作刷机包没关系,可以不做,想用官方软件的同学可以 看看) 选择app,右键你想要提取软件,提取就可以了,我是把整个app文件夹提取出来了,不用 的软件直接删掉好了 2.定制软件的精简 在你不想要用的软件上直接右键,删除,就好了,你也可以右键添加你想要用的软件,得把

软件改成比较简短的英文名,否则有可能不能用 秀一下我精简后的列表,大家可以参照着精简 https://www.sodocs.net/doc/ff17850605.html,uncher文件的替换 下载好你想要用的桌面软件,改名为‘Launcher’,删掉app中的‘Launcher2’,添加进去你改好名字的‘Launcher’就好了,我比较喜欢ADW,所以我把ADW的文件名改为 Launcher,替换掉原来的Launcher2就好了 4.破音问题的解决 在左边导航点选‘etc’,右键添加文件,把附件中的声音配置文件解压出来 ‘AudioFilter.csv’添加进去就好了 AudioFilter.rar (355 Bytes)

5.字体的更改 下载字体文件,中文字体库一律把名字改名为‘DroidSans Fallback.ttf’,英文字体改为‘DroidSans.ttf ’,加粗的英文字体改为‘DroidSans-Bold.ttf ’然后再左边导航栏点选‘fonts’,把之前自带的字体删除,然后把你改好名字的字体添加进去就好了把国产机皇的字体也分享给大家,中文+英文+英文加粗 6.开机音乐和照相机音乐的删除 在导航栏点选‘media’,在audio/ui文件夹下,删除‘Bootsound.mp3’(开机音乐)和

层次分析法matlab程序举例

层次分析法程序举例: A=[1 1/7 1/5 2 4 1/3;7 1 3 5 5 3;5 1/3 1 5 5 3;1/2 1/3 1/5 1 2 1/3;1/4 1/5 1/5 1/2 1 1/5;3 1/3 1/3 3 5 1]; [v,d]=eig(A); eigenvalue=diag(d); lamda=max(eigenvalue); cil=(lamda-6)/5; crl=cil/1.26; w1=v(:,1)/sum(v(:,1)) 挑选合适的工作。经双方恳谈,已有三个单位表示愿意录用某毕业生。该生根据已有信息建立了一个层次结构模型,如下图所示。 程序: A=[1 1/7 1/5 2 4 1/3;7 1 3 5 5 3;5 1/3 1 5 5 3;1/2 1/3 1/5 1 2 1/3;1/4 1/5 1/5 1/2 1 1/5;3 1/3 1/3 3 5 1]; [v,d]=eig(A); eigenvalue=diag(d); lamda=max(eigenvalue); ci=(lamda-6)/5

cr=ci/1.26 w1=v(:,1)/sum(v(:,1)) B1=[1 1/4 1/2;4 1 3;2 1/3 1]; [v,d]=eig(B1); eigenvalue=diag(d); lamda=max(eigenvalue); cil1=(lamda-3)/2 cr1=cil1/0.52 b1w=v(:,1)/sum(v(:,1)) B2=[1 1/4 1/5;4 1 1/2;5 2 1]; [v,d]=eig(B2); eigenvalue=diag(d); lamda=max(eigenvalue); cil2=(lamda-3)/2 cr2=cil2/0.52 b2w=v(:,1)/sum(v(:,1)) B3=[1 1/2 2; 2 1 3;1/2 1/3 1]; [v,d]=eig(B3); eigenvalue=diag(d);

第2天 linux系统的编译及镜像文件的制作

第2天linux系统的编译及镜像文件的制作 一般来说,linux系统分为几个映像。 一:bootload :一般常用的是 U-boot 二:内核映像:主要是linux内核编译成的映像比如TQ210开发板使用的zImage.bin 三:文件系统:有很多格式,比如 下面根据TQ210说明书进行讲解,大部分参考官方手册。以后自己修改源码可以在此基础上进行修改,修改完以后按照此步骤进行编译,编译完成后进行下载到开发板进行运行 1编译bootloader 1.1光盘中的 u-boot 源码的解压 先将光盘中的 u-boot 源码 ( 在光盘的“ TQ210_CD\bootloader\ ” 目录下 , 名为 uboot_TQ210_1.3.4_V1.1.tar.bz2)拷贝到 PC 的linux系统的根目录(这里说的根目录是本手册编写者的操 作和截图所拷贝的地方, 实际操作可以拷贝到任意目录下) 下, 然后使用命令#tar xvfjuboot_TQ210_1.3.4_V1.1.tar.bz2 -C /,解压源码,如下图所示 源码解压后,会在“/opt/EmbedSky/TQ210/uboot_TQ210_1.3.4/”目录下得到刚刚解压的源码。 1.2 光盘中的u-boot源码的编译 解压完成后,使用命令#make TQ210_config,配置u-boot,如下图所示:

使用命令#make,编译u-boot。编译结束后,在/opt/EmbedSky/TQ210/uboot_TQ210_1.3.4/目录下会得 到一个名字u-boot.bin的镜像,将其拷贝到Windows 或者拷贝到TFTP 服务器发送文件指定的目录中,就 可以烧写到开发板上面进行测试了(或者制作成SD 启动卡也可以测试)。如下两图所示:

相关主题