集体智慧编程第十一章---用java编写(小部分)

<<集体智慧编程>>的第十一章是有关遗传编程的话题,书中提到本章将考查一种截然不同的问题解决方法。与先前遇到一个问题就选择一种算法的思路不同,我们将编写一个程序,尝试自动构造出解决某一问题的最佳程序。因而从本质上,我们将要构造的是一个能够构造算法的算法。

本章最后实现了一个能人机对战的AI,虽然比较粗糙,但还是觉得挺有趣,于是想自己实现一次里面的代码。书中代码是用python编写的,但是想试下用不同的语言实现同一个机器学习算法,举一反三,之前接触的机器学习算法都是用python,没试过java,于是打算用java编写一次。

此算法需要先构造一棵程序解析树。


相当于

def func(x,y)

if x > 3:

return y + 5

else:

return y - 2


书中的Python2代码:

from random import random,randint,choice
from copy import deepcopy
from math import log

class fwrapper:
  def __init__(self,function,childcount,name):
    self.function=function
    self.childcount=childcount
    self.name=name

class node:
  def __init__(self,fw,children):
    self.function=fw.function
    self.name=fw.name
    self.children=children

  def evaluate(self,inp):    
    results=[n.evaluate(inp) for n in self.children]
    return self.function(results)
  def display(self,indent=0):
    print ((' '*indent)+self.name)
    for c in self.children:
      c.display(indent+1)
    

class paramnode:
  def __init__(self,idx):
    self.idx=idx

  def evaluate(self,inp):
    return inp[self.idx]
  def display(self,indent=0):
    print ('%sp%d' % (' '*indent,self.idx))
    
    
class constnode:
  def __init__(self,v):
    self.v=v
  def evaluate(self,inp):
    return self.v
  def display(self,indent=0):
    print ('%s%d' % (' '*indent,self.v))
    

addw=fwrapper(lambda l:l[0]+l[1],2,'add')
subw=fwrapper(lambda l:l[0]-l[1],2,'subtract') 
mulw=fwrapper(lambda l:l[0]*l[1],2,'multiply')

def iffunc(l):
  if l[0]>0: return l[1]
  else: return l[2]
ifw=fwrapper(iffunc,3,'if')

def isgreater(l):
  if l[0]>l[1]: return 1
  else: return 0
gtw=fwrapper(isgreater,2,'isgreater')

flist=[addw,mulw,ifw,gtw,subw]

def exampletree():
  return node(ifw,[
                  node(gtw,[paramnode(0),constnode(3)]),
                  node(addw,[paramnode(1),constnode(5)]),
                  node(subw,[paramnode(1),constnode(2)]),
                  ]
              )


个别类的说明

fwrapper

一个封装类,对应于“函数型”节点上的函数。其成员变量包括了函数名称、函数本身,以及该函数接受的参数个数

node

对应于函数型节点(即带子节点的节点)。我们以一个fwrapper类对其进行初始化。当evaluate被调用时,我们会对各个子节点进行求值运算,然后再将函数本身应用于求得的结果

paramnode

这个类对应的节点只返回传递给程序的某个参数。其evaluate方法返回的是由idx指定的函数

constnode

返回常量值的节点。其evaluate方法返回该类初始化时所传入的值


程序运行代码结果:

>>>import gp

>>>exampletree = gp.exampletree()

>>>exampletree.evaluate([2,3])

1

>>>exampletree.evaluate([5,3])

8

>>>exampletree.display()

if

  isgreater

    p0

    3

  add

    p1

    5

  subtract

    p1

    2


java代码:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;


public class Chapter11Test {
    private FWrapper addw ,subw ,mulw ,ifw , gtw ;
    private List<FWrapper> flist ;
    private static Chapter11Test obj = new Chapter11Test();

    int addfunc(List<Integer> l){
        return l.get(0)+l.get(1);
    }

    int subfunc(List<Integer> l){
        return l.get(0)-l.get(1);
    }

    int mulfunc(List<Integer> l){
        return l.get(0)*l.get(1);
    }

    int iffunc(List<Integer> l){
        if(l.get(0) > 0) return l.get(1);
        else return l.get(2);
    }

    int isgreater(List<Integer> l){
        if(l.get(0) > l.get(1)) return 1;
        else return 0;
    }

    private Node exampletree(){
        return new Node(ifw,new Object[]{
                new Node(gtw,new Object[]{new ParamNode(0),new ConstNode(3)}),
                new Node(addw,new Object[]{new ParamNode(1),new ConstNode(5)}),
                new Node(subw,new Object[]{new ParamNode(1),new ConstNode(2)})
        });
    }

    private void beginTest() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException {
        addw = new FWrapper(obj.getClass().getDeclaredMethod("addfunc",List.class), 2 ,"add");
        subw = new FWrapper(obj.getClass().getDeclaredMethod("subfunc",List.class), 2 ,"subtract");
        mulw = new FWrapper(obj.getClass().getDeclaredMethod("mulfunc",List.class), 2 ,"multiply");
        ifw = new FWrapper(obj.getClass().getDeclaredMethod("iffunc",List.class), 3 ,"if");
        gtw = new FWrapper(obj.getClass().getDeclaredMethod("isgreater",List.class), 2 ,"isgreater");
        flist = new ArrayList<>(Arrays.asList(addw,subw,mulw,ifw,gtw));
        Scanner reader = new Scanner(System.in);
        System.out.println("请输入参数X,Y :");
        int X = reader.nextInt();
        int Y = reader.nextInt();
        System.out.println("exampletree.evaluate(["+X+","+Y+"])");
        System.out.println(exampletree().evaluate(new int[]{X,Y}));
        System.out.println("exampletree.display()");
        exampletree().display(0);

    }


    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException {
        obj.beginTest();
    }


    class FWrapper{
        Method function;
        int childcount;
        String name;
        FWrapper(Method function,int childcount,String name){
            this.function = function;
            this.childcount = childcount;
            this.name = name;
        }
    }

    class Node{
        //private Method function;
        private FWrapper fw;
        private Object[] children;
        private String name;
        Node(FWrapper fw,Object[] children){
            this.fw = fw;
            this.name = fw.name;
            this.children = children;

        }

        public int evaluate(int[] inp) throws NoSuchMethodException, IllegalAccessException, ClassNotFoundException, InvocationTargetException {

            List<Integer> results = new ArrayList<>();
            for (int i = 0; i < children.length; i++) {
                int result = (Integer)children[i].getClass().getDeclaredMethod("evaluate",Class.forName("[I")).invoke(children[i],inp);
                results.add(result);
            }
            return (Integer)fw.function.invoke(obj,results);

        }

        public void display(int indent) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
            String indents="";
            for (int i = 0; i < indent; i++)
                indents+=" ";
            System.out.println(indents + name);
            for(Object c: children)
                c.getClass().getDeclaredMethod("display",int.class).invoke(c,indent+1);
        }
    }

    class ParamNode{
        private int idx;
        ParamNode(int idx){
            this.idx = idx;
        }

        public int evaluate(int[] inp){
            return inp[idx];
        }

        public void display(int indent){
            String indents="";
            for (int i = 0; i < indent; i++)
                indents+=" ";
            System.out.println(indents+"p"+idx);
        }
    }

    class ConstNode{
        private int v ;
        ConstNode(int v){
            this.v = v;
        }

        public int evaluate(int[] inp){
            return v;
        }

        public void display(int indent){
            String indents="";
            for (int i = 0; i < indent; i++)
                indents+=" ";
            System.out.println(indents+v);
        }
    }
}

java代码里的class和方法基本和python里的class和函数对应,这样写其实意义不大...代码比较烂,但是也从中学到一点java反射的知识,尤其是Method类的invoke。


运行结果也一样
请输入参数X,Y :
5
3
exampletree.evaluate([5,3])
8
exampletree.display()
if
 isgreater
  p0
  3
 add
  p1
  5
 subtract
  p1
  2


这次没有完整实现整章的算法,但以上的内容是本章后面的算法的基础。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值