博文

[转]计算机科学家图灵(2006-04-07 10:15:00)

摘要:计算机科学家图灵

  阿兰·麦席森·图灵 1912年生于英国伦敦,1954年死于英国的曼彻斯特,他是计算机逻辑的奠基者,许多人工智能的重要方法也源自于这位伟大的科学家。他对计算机的重要贡献在于他提出的有限状态自动机也就是图灵机的概念,对于人工智能,它提出了重要的衡量标准“图灵测试”,如果有机器能够通过图灵测试,那他就是一个完全意义上的智能机,和人没有区别了。他杰出的贡献使他成为计算机界的第一人,现在人们为了纪念这位伟大的科学家将计算机界的最高奖定名为“图灵奖”。上中学时,他在科学方面的才能就已经显示出来,这种才能仅仅限于非文科的学科上,他的导师希望这位聪明的孩子也能够在历史和文学上有所成就,但是都没有太大的建树。少年图灵感兴趣的是数学等学科。在加拿大他开始了他的职业数学生涯,在大学期间这位学生似乎对前人现成的理论并不感兴趣,什么东西都要自己来一次。大学毕业后,他前往美国普林斯顿大学也正是在那里,他制造出了以后称之为图灵机的东西。图灵机被公认为现代计算机的原型,这台机器可以读入一系列的零和一,这些数字代表了解决某一问题所需要的步骤,按这个步骤走下去,就可以解决某一特定的问题。这种观念在当时是具有革命性意义的,因为即使在50年代的时候,大部分的计算机还只能解决某一特定问题,不是通用的,而图灵机从理论上却是通用机。在图灵看来,这台机器只用保留一些最简单的指令,一个复杂的工作只用把它分解为这几个最简单的操作就可以实现了,在当时他能够具有这样的思想确实是很了不起的。他相信有一个算法可以解决大部分问题,而困难的部分则是如何确定最简单的指令集,怎么样的指令集才是最少的,而且又能顶用,还有一个难点是如何将复杂问题分解为这些指令的问题。 

  图灵对于人工智能的发展有诸多贡献,例如图灵曾写过一篇名为《机器会思考吗?》(Can Machine Think?)的论文,其中提出了一种用于判定机器是否具有智能的试验方法,即图灵试验。至今,每年都有试验的比赛。 

  二战时,图灵在英国通信部工作,他运用他的专业技能破译德国密码,这在当时十分不容易,因为德国人开发出一种用于计算的机器称为Enigma,它能够定期将密码改变,让破译者根本摸不到头绪。......

阅读全文(5381) | 评论:4

传说中的CERNET(2006-04-06 18:34:00)

摘要:昨天了解到DNS的原理,原来CERNET(读成Sir'Net)就是China Education & Research Network,中国教育科研网,呵呵

老师说IPv6很有可能从这里开始;)一个国内走在网络技术前沿的网络~~......

阅读全文(4240) | 评论:3

[转]软件需求规格说明书样例(2006-04-06 12:34:00)

摘要:1. 引言 1.1 编写目的:编写此文档的目的是进一步定制软件开发的细节问题,便于用户与开发商协调工作.本文档面向的读者主要是项目委托单位的管理人员.希望能使本软件开发工作更具体. 1.2 项目背景 1.2.1项目委托单位:****公司 1.2.2开发单位:***公司 1.3 定义 1.4  参考资料 2. 任务概述 2.1 目标: <1> 决策支持:根据公司的要求及时提供所需报表及文件,并在适当时候对各部门领导给予销售及进货等方面的提示 <2>提高效率:利用软件进行管理,避免人工管理的失误以及 延迟性,从而实现高效率的管理. 2.2 运行环境: <1> 硬件方面:Pentium级处理芯片
  1兆显存的兼容显卡
  256色,800*600的兼容显示器
  标准兼容打印机 <2>软件方面: WIN95操作系统 2.3 条件与限制:   编程用计算机一台
  完成期限2000/7/1
  无资金供给 3. 数据概述 数据流程图如下: 3.1 静态数据:包括系统登录密码,各数据库所在位置,系统分析原始数据 3.2  动态数据:包括各数据库内各项显示数据,用户登录信息,系统时间 3.3 数据库描述:   人事管理数据库:公司内人员的个人详细信息,包括档案信息
  销售管理数据库:当日销售记录及以前的销售统计,用于销售分析
  财务管理数据库:公司内部账目及收支情况详表
  技术管理数据库:公司所需各技术档案的详细记录(包括文档) 3.4 数据字典: <1>数据流词条描述:   1.数据流名:登录信息
  来源:用户的输入
  去向:系统内部检验部分
  组成:用户名,密码
  流通量:每次登录输入一次   2.数据流名:登录结果
  来源:系统
  去向:用户
  组成:返回信息
  流通量:每次登录返回一次   3.数据流名:输入修改信息
  来源:用户
  去向:系统判断部分
  组成:根据各数据库内容而不同
  流通量:依用户输入而定   4.数据流名:反馈信息
  来源:系统判断部分
  去向:用户
  组成......

阅读全文(20421) | 评论:5

Windows程序设计[5]-认识一下GDI(2006-03-30 21:22:00)

摘要:其实我写的这几篇质量确实很低,我完全是按自己理解的写的,因为我也是初学,故显得有些乱。

以前看到论坛里讨论操作系统的贴子,主题是关于用哪个操作系统好,争得比较火爆。有人说WINDOWS是垃圾,有人说LINUX是王者,可能还有的人是DOS迷吧,意见不大统一。我觉得WINDOWS最好的东西也就是这个了GDI,图形设备接口,因为它是图形化直观的操作计算机,所以在PC机进入普通人生活的时候,这样简单直观的操作系统也就为很多人接受了。我觉得WINDOWS甚至可以成为操作系统的标准,或者说个人计算机操作系统的标准,就像网络一样ISO/OSI虽然是国际标准,但是事实上的标准却是TCP/IP,在这个时候,市场决定了标准。

不扯远了,说GDI。这个接口有什么用?它可以让我们轻易的使用图形设备。这里需要先确定一个设备环境(Device Context),简称DC(这个名字你很熟?),它就是一个区域,比如一个窗体,它会占有显示器中间的一个矩形框区域,常用的区域都矩形,因为当区域重叠的时候方便系统计算覆盖情况。

如下部分程序:
case WM_PAINT:
{
  char szText[]="Hello!Windows!";
  HDC hdc;
  PAINTSTRUCT ps;
  hdc=::BeginPaint(hwnd,&ps);
  //在这里画图
  ::TextOut(hdc,10,10,szText,strlen(szText));
  ::EndPaint(hwnd,&ps);
  return 0;
}
显然是在处理WM_PAINT消息,收到这个消息就说明,客户区需要重画,比如我们在调整窗体大小后。hdc是设备环境的句柄,ps是特定的PaintStruct,::BeginPaint()是获得特定窗口句柄的客户区DC句柄,当然hwnd就是该实例的主窗口句柄了。最后的::EndPaint()关闭hdc,在它......

阅读全文(5657) | 评论:1

Windows程序设计[4]-了解MFC(2006-03-30 20:13:00)

摘要:前面了解到了,用API直接搭建WINDOWS程序的过程。GUI程序的入口函数是WinMain(),在入口函数中用函数::CreateWindowEx()创建一个窗口,再注册并更新一个窗口,然后进入消息循环,当从用户或其它线程获得了一个消息,再调用指定的窗口函数,自定义的窗口函数在处理了特定的消息后,再将处理权交给系统默认的消息处理函数::DefWindowProc()。形式上是非常简单的,但事实上用起来并不是这么轻松的,当开发的系统变大时,用这样的方法搭程序,显然是很不够的,这个时候‘方法’会显得更加重要。我一直的观点是,搞理论的应该更注重‘结果’,而搞技术的应该更注重‘方法’。

MFC(Microsoft Fundation Classes)的设计就是出于这样的目的。它的本质就是对API的一个系统的封装,封装的过程是非常复杂的,但封闭的结果是非常实用的,用这样的方法搭建WINDOWS程序将会变得轻而易举。这就是‘方法’对技术的提高的一种表现吧。

总的看MFC,它由CObject从上往下展开(继承),主要的几个类有(这个时候我正拿着MFC体系图在看呢!),CCmdTarget支,它负责与消息处理有关的对象,包括CWinApp,用来搭建应用程序实例;CWnd,封闭了窗口的对象。这是最重要的两个类了,另外的还有CFile文件类,CDC设备环境类等。

使用的时候,用CWinApp派生CMyApp,重载virtual BOOL InitInstance();虚函数,意思是初始化实例。初始化的时候建立自己的窗口对象,从CWnd继承,如CMyWindow。在CMyApp::InitInstance()中定义一个CMyWindow对象作为成员,CMyWindow的生成函数中将设置窗口的特征,使用CreateEx()注册窗口,InitInstance()返回TRUE则表示进入消息循环。

这里还有个消息映射的问题,我们不愿意在一个消息处理函数中用switch(Message),例一长条的case nMsgID:,这样的程序不好看,也不容易阅读,更不好维护,所以我们希望用一个简单的映射。MFC做的相对简单,完全由宏定义做的,消息是系统固定的,消息宏名大致是WM_开头,意为Windo......

阅读全文(5763) | 评论:1

多线程可否应用在搜索算法上?(2006-03-29 23:10:00)

摘要:书上看到一个多线程文件搜索器的例程,如果说这是算法的法,那在WINDOWS里早就用过了,想想用WINDOWS在硬盘上搜索文件,是不是很快?

简单的说,搜索算法有两种,深度优先和广度优先。优先就是说搜索的时候是单线程的,于是就有线程到达结点的先后,根据算法固有的侧重方向不同而分为深度优先和广度优先。深度优先就是递归式,在子结点延伸的结点中搜索的时候,前一搜索器在那里等待它的回溯,回溯后再进行下一枝的搜索,这里的等待是不是在浪费时间?广度优先就是层次式,把同一层次(相同父结点的子结点)的结点一齐压入队列,从外面看就像是一层一层按广度从上往下‘铺’开来搜索的,但事实上处于同一层的结点往下‘铺’的时候,并不是同时的,虽然处于同一层,但入队的时机不同,因此也可以看成是有时间停滞。

如果在这里应用多线程的思想,那情况会不会更好呢?在每一个非叶子结点上都启动一个线程,该线程负责往下搜索,原线程处于等待状态,当下一级的搜索线程完成后,回调搜索的结果。整体思路是这样的,感觉有点像深搜也有点像广搜,如果不考虑创建线程的时间,认为线程是同步启动的话,那整个程序将会在最快的时间内到达全部结点。

呵呵~只是一种想法,不知道这样做会不会时间重叠,这样的东西我也不好说时间复杂度了,如果有重叠那会是有所提高的,如果没有,算法就没有提高,同样是O(n)。只是笔者的设想而已。......

阅读全文(6818) | 评论:6

Windows程序设计[3]-消息与消息循环(2006-03-25 14:48:00)

摘要:今天有朋友提的意见让我感触很深,说写BLOG要多一些‘有趣’多一些funny,回头看看我写的东西,大部分都给人严肃、枯燥的感觉,我在这里免费拿了一个BLOG,而这个BLOG却不完全属于我,他属于千千万万在使用网络的学者!所以,我有责任,而这个责任就是不浪费读者的时间。

不说废话了,同样今天继续写的将是Win32程序设计中的Windows消息机制。

消息就是一个用户对电脑的‘请求’。我想放点音乐,我就对电脑大声喊:“Hey!伙计,放点音乐吧!”,结果显然是我将被冷落。我不能这样发‘请求’,我应该用电脑懂的语言,再用‘友好’的方式请求。我只能选择按鼠标或者敲键盘,于是消息便从这里产生了。

消息的原来形式是你手指的‘动能’,结果导致了某些特定电信号,电信号再到达计算机电路系统,系统再将信号反应到操作系统,操作系统再将信号变成消息形式发到线程,到线程的消息再进入消息队列排队,最终到达消息处理函数,此时电脑就明白你的请求是什么意思了,再通过消息处理函数工作。

与其说消息是发到电脑,还不如说是发到了线程,如果没有线程在那里‘听’,你发再多的消息,也不会有反应。

线程要怎么‘听’,还得从GUI入口函数说起。

一个GUI用户程序的入口函数将不是main(),而是WinMain(),原形是:
int APIENTRY WinMain(
   HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPSTR lpCmdLine,
   int nCmdShow)
{
}
APIENTRY是__stdcall的宏,意思是用Windows标准调用方式,hInstance是本身的实例句柄,lpCmdLine是命令行参数。

光一个WinMain()是不会等待消息的(‘听’),我可以加入一个::MessageBox();简单的弹一个窗口出来,然后默默的结束。

问题是我们需要先建一个窗体出来,建主窗体的过程比较复杂......

阅读全文(6298) | 评论:5

对无穷大的思考(2006-03-23 17:34:00)

摘要:无穷饭店
在宇宙中有一个饭店叫无穷饭店,无穷饭店已经住满了人。一天,来了一个乘客要住店,怎么住?无穷饭店的老板非常聪明,他想到一个办法,设无穷饭店的房间号是0,1,2,...,那让所有住在i号房间的顾客改为住i+1号房间,那0号房间就空出来了。第二天,又来了n个乘客(n为某正整数),同样的办法,所有顾客只要往后移n个房间,这n个人就可以住进来。第三天,这回来了无穷多个乘客,这下怎么办?老板一拍脑袋,这样吧,让所有现在住i号房间的顾客都住到2*i号房间,这样就可以空出所有的奇数号房间,而且也可以住进无穷多个人。

这个例子是以前数学分析的老师举的,其实这里的无穷只能限定为‘可数的’无穷,还有很多类无穷是不可数的。

对于集合,可以简单的分成‘有限集’和‘无限集’,有限集很容易,有限个是很容易理解的,我们可以记集合的基为有限集的元素个数,它给人的感觉就是集合的大小。但对于无限集是否还有基的概念呢?

首先是阿列夫0,这是一种基,是多少不知道,只是一个记号,基是阿列夫0的集合叫‘可数集’,定义为元素可以和自然数建立一一对应关系的集数。比如{正偶数},{负奇数},{整数}等。

它有几个性质:
1、可数集并有限集仍然是可数集
2、有限个可数集的并集是可数集
3、可数个可数集的并集是可数集
第三个的意思是,虽然你给了我无穷多个可数集,但我可以把这些可数集按某种顺序排列起来,于是就可以建立与自然数的对应,结论就可以是无穷并集仍是可数集。

利用3可以证明{有理数}是可数集。书上有证明,略。

其次是阿列夫1,这也是一种基,是多少也不知道,同样是一个记号,也叫连续基数,它定义为实数集合R0={x|x属于(0,1)之间,x属于实数}的基。
首先R0不可数,证明非常经典。
首先把所有的(0,1)间的数全写成无穷小数,对于有限小数这样处理,比如0.23=0.229999...
这样处理后所有的数都可表示成
0.x1x2x3x4...
的形式
假设它是可数的,则可以排列成
a1=a11a12a13a14...
a2=a21a22a23a24...
...
an=an1an2an3an4...
...
并且这无穷多个数......

阅读全文(6175) | 评论:2

为什么要写BLOG(2006-03-23 16:47:00)

摘要:什么是BLOG?
打开IE或者Opera,在地址栏上敲google.com,回车,输入‘什么是BLOG’,出来结果。

http://blog.park4u.com/blogger/1/archives/2004/63.html

我觉得写BLOG主要还是写自己的东西,web log嘛,写你的成长心情,写你的生活情感,写你的技术感想,写你的工作经验,写你的学习体验,总之这是一个个人的空间,而且应该是原创的空间。

我一直想说点什么。写BLOG难道真是为了点击率?网上随便就能google出来的东西在自己的BLOG里copy一大堆,如果真想链接一下,可以只copy个URL来,没必要再浪费网络资源。(其实我原来也转贴过,今天有人问我转贴的文章的问题,因为不是我写的,我也回答不出来,所以才觉得不应该这样。。。)

我经常会想如何利用网络这个问题,网络这个东西发展太快了,有时候一个新的东西出来,等到有很多人都在用了还不知道是什么东西,我有朋友前些天还问我哪有个人论坛,我说你搞个人论坛干嘛?如果想在网上安静的写点东西,选择BLOG吧。

有朋友说我的BLOG原创性强,其实本应该这样,不然我来这里干嘛。我以后写BLOG会尽量写自己的东西,克服转贴这个坏毛病。

以上纯属个人观点。......

阅读全文(4910) | 评论:9

Windows程序设计[2]-线程与线程通信(2006-03-20 09:40:00)

摘要:首先要说明一点,我在这里写的关于Win32编程的Windows程序设计系列文章并不是我深思熟虑的小论文,实际上我在写的时候还不了解Win32编程,这是我自己在学习。如果您是初学者禁止观看,如果您是高手欢迎指导!除此之外的其它版的有些文章我是非常认真写的。

Windows程序启动的过程
在Win32环境下有两种模式,GUI和CUI,前者是图形用户接口,后者是控制台用户接口(类似DOS),GUI后面会要深入讨论,如果Windows没这个东西,估计就没人用它了。学过C语言的都知道任何一个程序都要有一个main(){}入口函数,但OS(操作系统)并不是直接调用main();,而是先调用C/C++运行期启动函数,此函数会初始化C/C++运行期库。我先不去理解这里的两个概念,我觉得这里的C/C++运行期使用的目的是为了实现C++的一种机制,比如malloc()管理自己的存储空间,分配对象,回收对象等。OK先不管它如何做的,总之它做好了运行一个Win32程序的一切准备工作,然后再建立一个进程,该进程有一个主线程,主线程的入口函数为main();,主线程的处于激活状态,主线程参与了CPU的竞争,程序正常运行了。

进程的建立
函数CreateProcess,原型见P15页。调用的时候需给系统指定一个STARTUPINFO变量,该变量保存一些进程初运行的信息,包括图形窗口的信息等。同时返回一个进程标志信息(PROCESS_INFORMATION),如ID、句柄信息等。
例:
STARTUPINFO si={sizeof(si)};
PROCESS_INFORMATION pi;
char* szCommandLine="notepad";
::CreateProcess(NULL,szCommandLine,NULL,NULL,FALSE,NULL,NULL,NULL,&si,&pi);
将打开记事本程序进程,si为运行初信息,pi为返回进程信息。

多线程
以前编程的思想都是单一的,一个程序总是从开始一行跑到最后一行,不管是分支还是循环,总之是从头运行到脚,跟汇编的思想一样,有一个PC指明指令的顺序,这个是容易理解的,因为我们......

阅读全文(6930) | 评论:5