您的位置:首页 > 理论基础

谁养鱼(三):如何让计算机认识线索

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是否满足这个线索。

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方法可以作为遗传算法适应度函数的主要组成部分,用来评价个体的生存能力。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: