随笔-30  评论-67  文章-0  trackbacks-0
 
网上互动式多功能服务站 http://wims.math.ecnu.edu.cn/wims.cgi?lang=cn&+session=FV1FF9B54A.1

对谈式练习集--中文部分  http://www.gzjzes.net/forum/Display.asp?id=610&Board_ID=26
posted @ 2006-07-23 23:54 含笑半步癫 阅读(315) | 评论 (0)编辑 收藏
为了计算robocode里头的炮弹的发射角度,不得不去解方程,可是多项式越展越长,无法忍受。于是上网看看有没有好工具,于是发现了Mathematica。Mathematica可以用于解决各种领域的涉及复杂的符号计算和数值计算的问题。它能进行多项式的计算、因式分解、展开等。进行各种有理式计算,求多项式、有理式方程和超越方程的精确解和近似解。这个展开功能正是我需要的。


Mathematica教程 http://www.math.sjtu.edu.cn/Mathematica%E6%95%99%E7%A8%8B/index.htm
posted @ 2006-07-23 23:51 含笑半步癫 阅读(938) | 评论 (1)编辑 收藏
相信大部分人小时候都对机器人比较感兴趣。
Robocode 是 IBM 开发的 Java 战斗机器人平台,游戏者可以在平台上设计一个 Java 坦克。每个坦克有个从战场上收集信息的感应器,并且它们还有一个执行动作的传动器。其规则和原理类似于现实中的坦克战斗。其融合了机器学习、物理、数学等知识,是研究人工智能的很好工具。
Robocode,需要Java 虚拟机。您创建一个机器人,把它放到战场上,然后让它同其他开发者们创建的机器人对手拼死战斗到底。Robocode 里有一些预先做好的机器人对手让你入门,但一旦您不再需要它们,就可以把您自己创建的机器人加入到正在世界范围内形成的某个联盟里去和世界最强手对阵。不喜欢java的也有选择,国内http://www.ai-code.org 网站上有类似的ai-tank和ai-足球,支持c/c++,java, .net,呵呵很强大吧,不过他论坛的人气就比较抱歉了。
虽说介绍robocode的文章经常都要鼓吹一下java,其实这个和java没多大关系,主要看算法。而且java初学着用robocode学习java实在不是一件值得推荐的事情,用来提高倒是还行。

玩了一两天robocode,就发现的最新版本1.1.1有些bug,国内的ai-code似乎做的更好些。这个游戏要玩的好,也不是太简单的事情。玩了这个游戏,才发现自己以前学的高数,曲线拟合,坐标,角坐标等等,忘了差不多了。
在全世界 Robocode 中有很多种用到了遗传算法方法来实现进化机器人。而且全世界的 Robocode 流派中也发展几种比较成熟的方法,比如预设策略遗传、自开发解释语言遗传、遗传移动。是不是觉得很夸张:)。不过人工智能刚好是我感兴趣的方向:)可以借这个游戏好好学习学习。有兴趣的朋友可以留个联系方式,或者有QQ群或者论坛给引见一下。有空的时候大家可以一起玩,看看谁的机器人更强:)

以下是一些相关资源:

robocode的主页 http://robocode.sourceforge.net/?Open&ca=daw-prod-robocode 
robocode的中文文章 http://www-128.ibm.com/developerworks/cn/java/robocode/index.html 
ai-code 的网址 http://www.ai-code.org 

posted @ 2006-07-23 13:42 含笑半步癫 阅读(5950) | 评论 (5)编辑 收藏
java1.5出来很久了,最近才去试了试。发现1.5虽然说支持模板了,但是像int 这样的基础类型还是不能支持,只能支持类对象。而且不支持运算符重载,极大限制了模板的使用。比起c++的模板,意义不是很大,最大的好处是从容器里头取对象不用手工进行类型转换。看来先天不足,后天还是不好补。无论sun如何努力,始终无法掩盖设计上的失败。
1.5在线程方面多了线程池,和一些其他功能,还是不错的。因为我刚好用的到:)。这让我想到c++,比起sun及其第三方的java库的疯狂扩张,c++的标准库让人感觉过于保守。java对一些实际上已经成为标准的东西的支持,以及c++对这些东西自生自灭的态度(虽然有boost库,但毕竟不是正式标准)以及对标准库的实现放任自由的态度(没有一个标准的实现),难免让c++的支持者感到一些失望。
posted @ 2006-07-19 10:19 含笑半步癫 阅读(508) | 评论 (4)编辑 收藏
半年前,玩qq游戏。不爽。于是写了个外挂,顺便练练win-api。对搜索做了初步优化,每次会找到比较优的位置进行交换(只查找一步,以后有空会考虑3步的情况)。但是得不到对对碰得计算分数得公式。只能大概计算一下。全部用c和api写得,代码比较乱(函数的功能还是稍微有注释),功能比较简陋,但是有兴趣的可以看看。以后有时间大概会用c++来改写一下。

使用方法:保证游戏画面在最前面。外挂窗口有简单提示,输入命令得时候,焦点需要在外挂上。

写完后发现c代码有个毛病就是传得参数太多(由于工作原因本人用的是java),看来以c++声称的大概5%得性能损失换来可读性大大得提搞,在大部分情况下还是很值的。

代码下载http://www.cppblog.com/Files/wmuu/ddpwg.rar
posted @ 2006-07-10 23:06 含笑半步癫 阅读(754) | 评论 (1)编辑 收藏

1) 启动inetd
编辑 /etc/rc.conf
inetd_enable="YES"


2) 开启telnet
编辑 /etc/inetd.conf

#telnet  stream  tcp     nowait  root    /usr/libexec/telnetd    telnetd
#telnet stream  tcp6    nowait  root    /usr/libexec/telnetd    telnetd (这个是tcp6协议的)
前面的#去掉
kill -HUP `cat /var/run/inetd.pid`
把inetd重启一下,就可以了。(只要输入inetd)

3)让root可以登陆telnet
编辑 /etc/pam.d/login 
account                requisite       pam_securetty.so
把这行注释掉

4)开启ftp
编辑 /etc/inetd.conf
#ftp     stream  tcp     nowait  root    /usr/libexec/ftpd       ftpd -l
#ftp    stream  tcp6    nowait  root    /usr/libexec/ftpd       ftpd -l
去掉前面的注释

5)让root登陆ftp
编辑 /etc/ftpusers
注释掉root


6)dmesg
dispaly the system message buffer

posted @ 2006-06-23 00:15 含笑半步癫 阅读(237) | 评论 (0)编辑 收藏
很早就找过这首歌,没找到,可能是当时知道的人少。最近突然想起来,上网找了找,居然找到了。我觉得这首歌的词和曲都不错,唱的也不错。

《西游记后传》相思 毛阿敏

相思作曲:三宝作词:赵小源演唱:毛阿敏

红豆生南国

是很遥远的事情

相思算什么

早无谁在意

醉卧红尘

处处霓虹

酒杯中好一片朗朗风情

 

最肯忘却故人诗

最不屑一顾是相思

守着爱怕人笑

还怕人看清

春又来

看红豆开

却不见有情人去采

拈花拥着风流

真情不再

网络上歌词不少,但是感觉有的字是错的,于是找了一个自己认为最正确的。

posted @ 2006-06-19 22:05 含笑半步癫 阅读(1111) | 评论 (5)编辑 收藏
最近开始看portal,在http://www.blogjava.net/eamoi/找到了中文文档,省了很多麻烦。

网站一般是这么介绍portal的:

随着信息化建设的深入,Portal 门户已经成为新型办公环境的一个重要组成部分。 Portal所提供的单点登录、权限控制、个性化定制、内容集成、文件管理等独特的功能, 已经大大占据公众的眼球,并在信息集成和消除信息孤岛方面发挥了重要的左右。
随着Portal技术的成熟,以MyNestcape、MyYahoo、MSN-Space等为代表大型网站也较多的采用Portal架构来实现个性化的内容聚合和定制,以实现灵活的扩展的服务策略。

粗粗一看,portal确实很强大,可以像应用程序一样自由控制要展现的东西。但是,细细想一下,网页既然做到了这份上,那和客户端有什么区别?为什么一定要在先天不足的web协议上实现这么复杂的东西。就拿MSN-Space来说,是我见过的最慢的blog。如果portal加上ajax,不时在后台刷新些什么东西,那才叫锦上添花。
posted @ 2006-06-14 21:36 含笑半步癫 阅读(650) | 评论 (1)编辑 收藏
java里头反射很强,但是要把一个函数传递出去确很麻烦。sun把原先的枚举类变成了迭代器类,1.5里头不甘愿的把泛形加了进来。以后呢?我想函数也会像c一样可以传递,说不定说有的东西都是对象,函数也是一种对象,可以自由传递。
接着加了泛形的util包会不会越来越像stl呢?
posted @ 2006-05-31 22:13 含笑半步癫 阅读(445) | 评论 (0)编辑 收藏

最近看了Java 编程的动态性,第 7 部分: 用 BCEL 设计字节码,网址是http://www-128.ibm.com/developerworks/cn/java/j-dyn0414/

其中的示范代码解释的不是很详细,这方面的中文资料又少,只好自己花时间看下去。bcel的类库却是不够友好,api文档也是走马观花的点一下,很多函数没有说明。理解基本靠猜,还好有个示范代码。下面对自己理解的东西做个记录,详细的代码可以到上面的链接下载。


import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.bcel.Constants;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;

public class BCELTiming {
    /**
     * Add timing wrapper to method of class. The method can accept any
     * arguments and return any type (including void), but must be a normal
     * (non-static, non-initializer) method to be used with this code as
     * currently implemented. Handling the other types of methods would not
     * involve any fundamental changes to the code.
     *
     * @param cgen
     *            generator for class being modified
     * @param method
     *            current method to be enhanced with timing wrapper
     */

    private static void addWrapper(ClassGen cgen, Method method) {

        // set up the construction tools
        InstructionFactory ifact = new InstructionFactory(cgen);
        InstructionList ilist = new InstructionList();
        ConstantPoolGen pgen = cgen.getConstantPool();
        String cname = cgen.getClassName();
        MethodGen wrapgen = new MethodGen(method, cname, pgen);
        wrapgen.setInstructionList(ilist);

        // rename a copy of the original method
        MethodGen methgen = new MethodGen(method, cname, pgen);
        cgen.removeMethod(method);
        String iname = methgen.getName() + "$impl";
        methgen.setName(iname);
        cgen.addMethod(methgen.getMethod());
        //以上是一下初始化的工作
       

        // compute the size of the calling parameters
        // operand stack操作数堆栈
        Type[] types = methgen.getArgumentTypes(); // 取出参数类型数组

        // solt代表本地变量的堆栈偏移量,里头储存了调用methen代表的函数的参数
        int slot = methgen.isStatic() ? 0 : 1; // 这种方式与Java如何处理方法调用有关。对于非静态的方法,每次调用的第一个(隐藏的)参数是目标对象的this引用(就是位置0储存的内容)。
        for (int i = 0; i < types.length; i++) {
            slot += types[i].getSize();// 累计个个参数类型的长度,
        }
        // 现在solt指向最后一个参数的下一个位置

        // save time prior to invocation
        // 调用静态的long java.lang.System.currentTimeMillis()方法,调用结束后函数的返回的long类型的值会压入operand stack操作数堆栈
        ilist.append(ifact.createInvoke("java.lang.System",
                "currentTimeMillis", Type.LONG, Type.NO_ARGS,
                Constants.INVOKESTATIC));
        ilist.append(InstructionFactory.createStore(Type.LONG, slot));// 将operand stack的top保存到本地变量堆栈的slot位置,operand stack弹出long值

        // call the wrapped method
        int offset = 0; // 偏移量
        short invoke = Constants.INVOKESTATIC; // 预先设置为调用静态函数
        if (!methgen.isStatic()) { // 如果不是调用静态函数,将调用的第一个(隐藏的)参数(目标对象的this引用)压入operand stack
            ilist.append(InstructionFactory.createLoad(Type.OBJECT, 0));
            offset = 1;// 偏移量加1
            invoke = Constants.INVOKEVIRTUAL;// 设置为调用非静态函数
        }
        for (int i = 0; i < types.length; i++) { // 遍历所有参数
            Type type = types[i];
            ilist.append(InstructionFactory.createLoad(type, offset)); // 按参数类型把参数一个个从本地变量堆栈取出,压入operand stack
            offset += type.getSize();
        }
        Type result = methgen.getReturnType();// 取得要调用函数的返回值类型
        ilist.append(ifact.createInvoke(cname, iname, result, types, invoke));// 调用方法名为iname的函数

        // store result for return later
        if (result != Type.VOID) {
            ilist.append(InstructionFactory.createStore(result, slot + 2)); // 将名为iname的函数返回值复制到本地变量堆栈的slot+2的位置上
        }

        // print time required for method call
        // 获取静态对象java.lang.System.out的引用,返回值压入operand stack
        ilist.append(ifact.createFieldAccess("java.lang.System", "out",
                new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
        ilist.append(InstructionConstants.DUP);// 取operand stack的top,压入operand stack。完成后load_stack的头两个元素是静态对象java.lang.System.out的引用
        ilist.append(InstructionConstants.DUP);// 取operand stack的top,压入operand stack。现在有3个java.lang.System.out的引用。供下面3次调用out.print()函数使用
        String text = "Call to method " + methgen.getName() + " took ";
        ilist.append(new PUSH(pgen, text));// 将text放入pgen(代表常量池),并把其在pgen的引用压入operand stack(供out.print(Sting)调用的参数)
        ilist.append(ifact.createInvoke("java.io.PrintStream", "print",
                        Type.VOID, new Type[] { Type.STRING },
                        Constants.INVOKEVIRTUAL));// 调用结束,operand stack弹出一个String的引用和一个out的引用(还剩2个out),函数没有返回值

        ilist.append(ifact.createInvoke("java.lang.System",
                "currentTimeMillis", Type.LONG, Type.NO_ARGS,
                Constants.INVOKESTATIC));// 调用java.lang.System.currentTimeMillis()方法,调用结束后函数的返回的long类型的值会压入堆栈operand stack
        ilist.append(InstructionFactory.createLoad(Type.LONG, slot));// 从本地变量堆栈的slot位置载入先前储存的long值,压入operand stack
        ilist.append(InstructionConstants.LSUB);// 调用long的减法指令,弹出2个long值,并把结果压入operand stack,现在operand stack的top第一个是long,第二个是out的引用
        ilist.append(ifact.createInvoke("java.io.PrintStream", "print",
                Type.VOID, new Type[] { Type.LONG }, Constants.INVOKEVIRTUAL));// 调用out.print(long)方法
        ilist.append(new PUSH(pgen, " ms."));// 将String对象" ms."放入pgen,并把其在pgen的引用压入operand stack(供out.print(Sting)调用的参数)
        ilist
                .append(ifact.createInvoke("java.io.PrintStream", "println",
                        Type.VOID, new Type[] { Type.STRING },
                        Constants.INVOKEVIRTUAL));

        // return result from wrapped method call
        if (result != Type.VOID) {
            ilist.append(InstructionFactory.createLoad(result, slot + 2));// 处理返回值,如果不为空,从本地对象堆栈的slot+2位置读取指定类型的返回值压入operand stack
        }
        ilist.append(InstructionFactory.createReturn(result)); //调用处理返回值的指令,result为返回值的类型

        //下面是一下扫尾工作
        // finalize the constructed method
        wrapgen.stripAttributes(true);
        wrapgen.setMaxStack();
        wrapgen.setMaxLocals();
        cgen.addMethod(wrapgen.getMethod());
        ilist.dispose();
    }

    public static void main(String[] argv) {
        if (argv.length == 2 && argv[0].endsWith(".class")) {
            try {

                JavaClass jclas = new ClassParser(argv[0]).parse();
                ClassGen cgen = new ClassGen(jclas);
                Method[] methods = jclas.getMethods();
                int index;
                for (index = 0; index < methods.length; index++) {
                    if (methods[index].getName().equals(argv[1])) {
                        break;
                    }
                }
                if (index < methods.length) {
                    addWrapper(cgen, methods[index]);
                    FileOutputStream fos = new FileOutputStream(argv[0]);
                    cgen.getJavaClass().dump(fos);
                    fos.close();
                } else {
                    System.err.println("Method " + argv[1] + " not found in "
                            + argv[0]);
                }
            } catch (IOException ex) {
                ex.printStackTrace(System.err);
            }

        } else {
            System.out.println("Usage: BCELTiming class-file method-name");
        }
    }
}


相对javassist,bcel确实比较复杂。但是bcel给我的感觉比较自由,有种一切尽在掌握的感觉,这一点比较我喜欢。
虽然自由,但是用bcel写一个类的实现绝对不会是一件让人开心的事情,如果碰巧你的实现又稍微复杂了点(比如实现了xx接口,又增加了一些函数和成员变量)。而且你的实现未必会比javac编译出来的代码效率高(不考虑jvm的动态优化)。
不过,先把你要实现的类的代码写出来,按照代码来写bcel的实现,会降低些实现难度。

posted @ 2006-05-31 16:44 含笑半步癫 阅读(2422) | 评论 (4)编辑 收藏
仅列出标题
共3页: 1 2 3