谁养鱼(三):如何让计算机认识线索
2011-11-25 21:52
330 查看
在谁养鱼问题中给出了15条线索,如何让计算机识别这些线索,并作出正确的判断呢?
因为房子的顺序是固定,给它们编号1、2、3、4、5。每个房子都有五种类型的属性,分别是颜色、国籍、饮料、宠物、香烟,并且不同的房子之间相同类型的属性是不同的。
通过观察可以发现,线索可以分为三类:固定线索,绑定线索和相邻线索。固定线索指的将某个属性固定在某个序号的房子,比如线索8和线索9,分别将牛奶固定在中间房子,将挪威人固定在第一个房子;绑定线索指的是,如果房子A具有属性B,那么也有属性C,比如线索2,瑞典人和狗这两个属性是绑定的;相邻线索指的是两个属性位于相邻的房子里,这种相邻可以是左相邻、右相邻或者左右相邻(简称为相邻),比如线索4,绿色相对于白色是左相邻关系,而线索10是左右相邻。
Solution类是用来表示一个可能解的,包含了五个房子的全部属性的一种排列。为了表示这三种不同的线索,分别设计了FixedClue、BindClue和AdjacentClue类,它们都是Clue的子类,并都有一个重写的方法match,用来检查一个Solution是否满足这个线索。
因为房子的顺序是固定,给它们编号1、2、3、4、5。每个房子都有五种类型的属性,分别是颜色、国籍、饮料、宠物、香烟,并且不同的房子之间相同类型的属性是不同的。
通过观察可以发现,线索可以分为三类:固定线索,绑定线索和相邻线索。固定线索指的将某个属性固定在某个序号的房子,比如线索8和线索9,分别将牛奶固定在中间房子,将挪威人固定在第一个房子;绑定线索指的是,如果房子A具有属性B,那么也有属性C,比如线索2,瑞典人和狗这两个属性是绑定的;相邻线索指的是两个属性位于相邻的房子里,这种相邻可以是左相邻、右相邻或者左右相邻(简称为相邻),比如线索4,绿色相对于白色是左相邻关系,而线索10是左右相邻。
Solution类是用来表示一个可能解的,包含了五个房子的全部属性的一种排列。为了表示这三种不同的线索,分别设计了FixedClue、BindClue和AdjacentClue类,它们都是Clue的子类,并都有一个重写的方法match,用来检查一个Solution是否满足这个线索。
public abstract class Clue { public abstract boolean match(Solution solution); }
public class FixedClue extends Clue{ /*固定的房间编号*/ int seat; Attribute attr; @Override public boolean match(Solution solution) { /*获取此Solution第seat个房子*/ House house = solution.get(seat-1); /*获取该房子和attr同类型的属性,并比较*/ if(attr==(house.get(attr.getType().getId()-1))){ return true; } return false; } public FixedClue(int seat, Attribute attr){ this.seat = seat; this.attr = attr; } }
public class AdjacentClue extends Clue{ Attribute attr1; Attribute attr2; int dir;//attr2相对attr1的位置,负数为左相邻,正数为右相邻,0为相邻 @Override public boolean match(Solution solution) { int seat1=0, seat2=0; /*获取该Solution具有属性attr1和attr2的房子的位置*/ for(int i=0; i<solution.size(); ++i){ /*获取此Solution第seat个房子*/ House house = solution.get(i); if(house.get(attr1.getType().getId()-1)==attr1) seat1=i+1; if(house.get(attr2.getType().getId()-1)==attr2) seat2=i+1; if(seat1!=0&&seat2!=0) break; } /*比较两个位置的关系*/ if(dir==0){ if(seat1-seat2==1 ||seat1-seat2==-1){ return true; } }else if(dir==seat2-seat1){ return true; } return false; } public AdjacentClue(Attribute attr1, Attribute attr2, int dir){ this.attr1 = attr1; this.attr2 = attr2; this.dir = dir; } }
public class BindClue extends Clue{ Attribute attr1; Attribute attr2; @Override public boolean match(Solution solution) { Iterator<House> iter = solution.iterator(); /*遍历五个房子,看是否存在房子同时具有属性attr1和attr2*/ while(iter.hasNext()){ House house = iter.next(); if(attr1==(house.get(attr1.getType().getId()-1)) && attr2==(house.get(attr2.getType().getId()-1))){ return true; } } return false; } public BindClue(Attribute attr1, Attribute attr2){ this.attr1 = attr1; this.attr2 = attr2; } }在Solution类初始化的时候,添加所有的线索到一个ArrayList对象中,每个Solution对象提供一个getMatches接口返回匹配了多少个线索。
import java.util.ArrayList; import java.util.Iterator; public class Solution extends ArrayList<House>{ public static ArrayList<Clue> clues=new ArrayList<Clue>(); int matches=0; static{ clues.add(new BindClue(Attribute.Red, Attribute.Britain)); clues.add(new BindClue(Attribute.Sweden, Attribute.Dog)); clues.add(new BindClue(Attribute.Denmark, Attribute.Tea)); clues.add(new BindClue(Attribute.Green, Attribute.Coffee)); clues.add(new BindClue(Attribute.Bird, Attribute.PallMall)); clues.add(new BindClue(Attribute.Yellow, Attribute.Dunhill)); clues.add(new BindClue(Attribute.Beer, Attribute.BlueMaster)); clues.add(new BindClue(Attribute.Germany, Attribute.Prince)); clues.add(new FixedClue(3, Attribute.Milk)); clues.add(new FixedClue(1, Attribute.Norway)); clues.add(new AdjacentClue(Attribute.White, Attribute.Green, -1)); clues.add(new AdjacentClue(Attribute.Cat, Attribute.Blends, 0)); clues.add(new AdjacentClue(Attribute.Horse, Attribute.Dunhill, 0)); clues.add(new AdjacentClue(Attribute.Blue, Attribute.Norway, 0)); clues.add(new AdjacentClue(Attribute.Water, Attribute.Blends, 0)); } public int getMatches(){ matches=0; Iterator<Clue> iter = clues.iterator(); while(iter.hasNext()){ Clue clue = iter.next(); if(clue.match(this)) matches++; } /**/ if(God.better==null||matches>God.better.matches){ God.better = (Solution)this.clone(); } return matches; } }getMatches方法可以作为遗传算法适应度函数的主要组成部分,用来评价个体的生存能力。
相关文章推荐
- 如何教计算机认识手写数字(上)
- 如何教计算机认识手写数字(中)
- 如何教计算机认识手写数字(下)
- 如何用vbscript实现计算机的关闭或重启
- 2.5D与3D编辑模式该如何进行认识
- 计算机是如何启动的
- 计算机是如何启动的?
- 如何阅读深入理解计算机系统
- 三论计算机专业本科该如何学习——三要,三不要
- 如何取消IE“已限制此网页运行可以访问计算机的脚本或ActiveX控件”
- 认识队列技术中的硬件队列和软件队列及如何改变硬件队列长度 推荐
- 如何让IE9以下版本认识html5元素
- 如何从零基础学习计算机编程
- 如何查找陈旧的用户名和计算机
- 【计算机管理】——如何更好进行
- 初步认识jetty,以及在项目中,如何结合jetty进行调试
- 如何使用自己不了解的计算机语言去实现自己想要的功能呢?
- 我对当前国内计算机教育的一点认识
- 谁养鱼(二):如何将排列映射到整数域
- 如何开始学习计算机编程