另一个神经网络骑士之旅难题

发布于 2024-08-11 01:43:01 字数 7054 浏览 6 评论 0原文

我已经尽了最大努力为神经网络骑士的旅行查找器制作了一个简单的java实现,但我完全困惑于为什么它无法工作..

有6个类,其中3个用于GUI,我确信它工作得很好, 3 处理实际逻辑等。

如果您想知道,这是受到 Yacoby 的启发python提供他在实现上也有问题,尽管我不认为我犯了同样的错误..

我很欣赏它不是超级编码,但感激地收到任何建议

Neuron 类:

package model;

import java.util.Random;

public class Neuron {


boolean oldActive=true,active=true; //ie part of the solution
int state=0,previousState=0;

public Square s1,s2;

public Neuron(Square s1,Square s2){
    this.s1=s1;this.s2=s2;


    //status of the neuron is initialised randomly
    oldActive=active= (new Random()).nextInt(2)==1?true:false;

}

public int activeNeighbours(){

    //discount this neuron if it is active
    int s=0;if(isActive()){s=-2;}

    for(Object o:s1.neurons)
        if(((Neuron)o).isActive())s++;

    for(Object o:s2.neurons)
        if(((Neuron)o).isActive())s++;


    return s;

}

public boolean hasChanged(){
    return  oldActive != active||previousState != state;
}



public boolean isActive(){return active;}

public void updateState(){
    previousState=state;
    state+=2-activeNeighbours();
}

public void updateOutput(){
    oldActive=active;
    if (state>3) active=true;
    else if(state<0)active=false;

}


}

Square 类:

package model;

import java.util.Vector;

public class Square {

Vector neurons=new Vector();//neurons which connect to this square
public int col;
public int row;

public Square(int row, int col){

    this.col=col;
    this.row=row;


}


/**
 * creates a neuron which links this square with the square s,
 * then tells both squares about it,
 * also returns the neuron for inclusion in the global list.
 * 
 * @param s
 * @return neuron n, or null
 */
public Neuron link(Square s){

    for(Object o: neurons)
        //discounts the link if it has already been created
        if (((Neuron)o).s1==s ||((Neuron)o).s2==s)return null;

    Neuron n=new Neuron(this,s);
    neurons.add(n);
    s.neurons.add(n);
    return n;

}


}

Control 类:

package model;

import java.util.Vector;
import gui.Board;

public class Control {
Board b; //the graphic board

Vector neurons=new Vector();   //all 168 neurons

Square[][] squares=new Square[8][8];

int[][] moves={
        {-2,-2, 2, 2,-1,-1, 1, 1},
        { 1,-1, 1,-1, 2,-2, 2,-2}};

public Control(Board b){
    this.b=b;

    //create 64 squares
    for(int row=0;row<8;row++)
        for (int col=0;col<8;col++)
            squares[row][col]=new Square(row,col);

    //create neurons
    for(int row=0;row<8;row++)
        for(int col=0;col<8;col++)
            findMoves(squares[row][col]);

    dl();//draw the initial active neurons on the graphic

    //try this many enumerations of the board before giving up
    int counter=1000;

    //the main updating loop
    while(counter>0){
        for(Object o:neurons)((Neuron)o).updateState();//update all the states
        for(Object o:neurons)((Neuron)o).updateOutput();//then all the outputs

        counter--;

        if(isStable())break;
    }

    dl();   //draw the neurons when the solution is found/attempt abandoned
}

/**
 * draws the lines (active neurons) on the graphic display
 */
private void dl(){
    b.clear();
    for(Object o:neurons)
        b.drawLine((Neuron)o);
    b.repaint();


}


/**
 * Identify all of the squares legal to move to from this one - link with a neuron,
 * then add the neuron to the collection
 * 
 * @param s
 */
private void findMoves(Square s){

    for (int i=0;i<moves[0].length;i++){
        int newRow=s.row+moves[0][i];
        int newCol=s.col+moves[1][i];

        if(isInBounds(newRow,newCol)){

            Neuron n=s.link(squares[newRow][newCol]);
            if (n!=null)neurons.add(n);         
        }           
    }

}

/**
 * tests whether the identified square is contained within the (8*8) board
 * @param row
 * @param col
 * @return
 */
private boolean isInBounds(int row,int col){
    if (row>=0 && row<8 && col>=0 && col<8)return true;
    return false;
}


/**
 * returns true if no neuron changes its state/output
 * @return
 */
private boolean isStable(){

    for (Object o:neurons)
        if(((Neuron)o).hasChanged())
            return false;
    return true;

}



public static void main(String[]s){
    Board b=new Board(50,50,60);
    new Control(b);
}

}

GUI 类: -

Board 类:

package gui;
import java.util.Vector;
import javax.swing.JFrame;
import model.Neuron;
/**
* sets up the graphic representation of the chess board, and draws on the neurons as required
 * @param x
 * @param y
 * @param squareSize
 */
public class Board extends JFrame {
Vector lines=new Vector();
int squareSize;

public Board(int x, int y,int squareSize){

    //initialize dimensions etc
    super("there.");
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    setBounds(x,y,squareSize*8+8,squareSize*8+30);
    this.setLayout(null);
    this.setVisible(true);
    this.squareSize=squareSize;

    //draw the squares
    drawSquares();

    repaint();
}

private void drawSquares(){
    for(int i=0;i<8;i++)
        for (int j=0;j<8;j++){
            GuiSquare s=new GuiSquare(i,j,squareSize);
            this.add(s,0);
        }
}

/**
 * represent the neuron as a line on the board
 * @param n
 */
public void drawLine(Neuron n){
    Line l=new Line(n.s1.col+n.s1.row*8,n.s2.col+n.s2.row*8,squareSize);
    if(n.isActive()){
        lines.add(l);
        add (l,0);
    }
}

/**
 * removes all of the lines (neurons) from the board
 */
public void clear(){
    for(Object o:lines)
        remove((Line)o);

    lines.clear();
}

}

GuiSquare 类:

package gui;
import java.awt.*;

public class GuiSquare extends Component{

int row,col;
int x;
int y;
int size;

public GuiSquare(int row,int col,int size){

    this.row=row;this.col=col;this.size=size;
    y=row*size; x=col*size;
    setBounds(x,y,size,size);
    setBackground((row+col)%2==0?Color.white:Color.black);
}

public void paint(Graphics g){
    g.setColor(getBackground());        
    g.fillRect(0,0, size-1, size-1);
    g.setColor(Color.gray);
    g.drawString(""+((row*8)+col), size/2, size/2);
}
}

Line 类:

package gui;

import java.awt.*;

public class Line extends Component{

int x1,y1,x2,y2;
int x,y,w,h;

public Line(int a,int b, int squareSize){
    setBackground(Color.blue);
    x1=((a%8)*squareSize)+(squareSize/2);
    y1=((a/8)*squareSize)+(squareSize/2);
    x2=((b%8)*squareSize)+(squareSize/2);
    y2=((b/8)*squareSize)+(squareSize/2);

    if(x1<x2){
        x=x1;w=x2-x1;
    }else{
        x=x2;w=x1-x2;
    }

    if(y1<y2){
        y=y1;h=y2-y1;
    }else{
        y=y2;h=y1-y2;
    }
    setBounds(x,y,w,h);
}

public void paint(Graphics g){
    g.setColor(getBackground());
    g.drawLine(x1-x,y1-y,x2-x,y2-y);
}

}

I've done my best to make a simple java implementation of the neural network knight's tour finder but I'm completely stumped as to why it fails to work..

there are 6 classes, 3 for the GUI which im pretty sure works fine, and 3 to deal with the actual logic etc.

If you are wondering, this is inspired by Yacoby's python offering He had a problem with the implementation also, although I don't think I'm making the same mistake..

I appreciate its not super coding, but any suggestions gratefully received

Neuron class:

package model;

import java.util.Random;

public class Neuron {


boolean oldActive=true,active=true; //ie part of the solution
int state=0,previousState=0;

public Square s1,s2;

public Neuron(Square s1,Square s2){
    this.s1=s1;this.s2=s2;


    //status of the neuron is initialised randomly
    oldActive=active= (new Random()).nextInt(2)==1?true:false;

}

public int activeNeighbours(){

    //discount this neuron if it is active
    int s=0;if(isActive()){s=-2;}

    for(Object o:s1.neurons)
        if(((Neuron)o).isActive())s++;

    for(Object o:s2.neurons)
        if(((Neuron)o).isActive())s++;


    return s;

}

public boolean hasChanged(){
    return  oldActive != active||previousState != state;
}



public boolean isActive(){return active;}

public void updateState(){
    previousState=state;
    state+=2-activeNeighbours();
}

public void updateOutput(){
    oldActive=active;
    if (state>3) active=true;
    else if(state<0)active=false;

}


}

Square class:

package model;

import java.util.Vector;

public class Square {

Vector neurons=new Vector();//neurons which connect to this square
public int col;
public int row;

public Square(int row, int col){

    this.col=col;
    this.row=row;


}


/**
 * creates a neuron which links this square with the square s,
 * then tells both squares about it,
 * also returns the neuron for inclusion in the global list.
 * 
 * @param s
 * @return neuron n, or null
 */
public Neuron link(Square s){

    for(Object o: neurons)
        //discounts the link if it has already been created
        if (((Neuron)o).s1==s ||((Neuron)o).s2==s)return null;

    Neuron n=new Neuron(this,s);
    neurons.add(n);
    s.neurons.add(n);
    return n;

}


}

Control class:

package model;

import java.util.Vector;
import gui.Board;

public class Control {
Board b; //the graphic board

Vector neurons=new Vector();   //all 168 neurons

Square[][] squares=new Square[8][8];

int[][] moves={
        {-2,-2, 2, 2,-1,-1, 1, 1},
        { 1,-1, 1,-1, 2,-2, 2,-2}};

public Control(Board b){
    this.b=b;

    //create 64 squares
    for(int row=0;row<8;row++)
        for (int col=0;col<8;col++)
            squares[row][col]=new Square(row,col);

    //create neurons
    for(int row=0;row<8;row++)
        for(int col=0;col<8;col++)
            findMoves(squares[row][col]);

    dl();//draw the initial active neurons on the graphic

    //try this many enumerations of the board before giving up
    int counter=1000;

    //the main updating loop
    while(counter>0){
        for(Object o:neurons)((Neuron)o).updateState();//update all the states
        for(Object o:neurons)((Neuron)o).updateOutput();//then all the outputs

        counter--;

        if(isStable())break;
    }

    dl();   //draw the neurons when the solution is found/attempt abandoned
}

/**
 * draws the lines (active neurons) on the graphic display
 */
private void dl(){
    b.clear();
    for(Object o:neurons)
        b.drawLine((Neuron)o);
    b.repaint();


}


/**
 * Identify all of the squares legal to move to from this one - link with a neuron,
 * then add the neuron to the collection
 * 
 * @param s
 */
private void findMoves(Square s){

    for (int i=0;i<moves[0].length;i++){
        int newRow=s.row+moves[0][i];
        int newCol=s.col+moves[1][i];

        if(isInBounds(newRow,newCol)){

            Neuron n=s.link(squares[newRow][newCol]);
            if (n!=null)neurons.add(n);         
        }           
    }

}

/**
 * tests whether the identified square is contained within the (8*8) board
 * @param row
 * @param col
 * @return
 */
private boolean isInBounds(int row,int col){
    if (row>=0 && row<8 && col>=0 && col<8)return true;
    return false;
}


/**
 * returns true if no neuron changes its state/output
 * @return
 */
private boolean isStable(){

    for (Object o:neurons)
        if(((Neuron)o).hasChanged())
            return false;
    return true;

}



public static void main(String[]s){
    Board b=new Board(50,50,60);
    new Control(b);
}

}

the GUI classes: -

Board class:

package gui;
import java.util.Vector;
import javax.swing.JFrame;
import model.Neuron;
/**
* sets up the graphic representation of the chess board, and draws on the neurons as required
 * @param x
 * @param y
 * @param squareSize
 */
public class Board extends JFrame {
Vector lines=new Vector();
int squareSize;

public Board(int x, int y,int squareSize){

    //initialize dimensions etc
    super("there.");
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    setBounds(x,y,squareSize*8+8,squareSize*8+30);
    this.setLayout(null);
    this.setVisible(true);
    this.squareSize=squareSize;

    //draw the squares
    drawSquares();

    repaint();
}

private void drawSquares(){
    for(int i=0;i<8;i++)
        for (int j=0;j<8;j++){
            GuiSquare s=new GuiSquare(i,j,squareSize);
            this.add(s,0);
        }
}

/**
 * represent the neuron as a line on the board
 * @param n
 */
public void drawLine(Neuron n){
    Line l=new Line(n.s1.col+n.s1.row*8,n.s2.col+n.s2.row*8,squareSize);
    if(n.isActive()){
        lines.add(l);
        add (l,0);
    }
}

/**
 * removes all of the lines (neurons) from the board
 */
public void clear(){
    for(Object o:lines)
        remove((Line)o);

    lines.clear();
}

}

GuiSquare class:

package gui;
import java.awt.*;

public class GuiSquare extends Component{

int row,col;
int x;
int y;
int size;

public GuiSquare(int row,int col,int size){

    this.row=row;this.col=col;this.size=size;
    y=row*size; x=col*size;
    setBounds(x,y,size,size);
    setBackground((row+col)%2==0?Color.white:Color.black);
}

public void paint(Graphics g){
    g.setColor(getBackground());        
    g.fillRect(0,0, size-1, size-1);
    g.setColor(Color.gray);
    g.drawString(""+((row*8)+col), size/2, size/2);
}
}

Line class:

package gui;

import java.awt.*;

public class Line extends Component{

int x1,y1,x2,y2;
int x,y,w,h;

public Line(int a,int b, int squareSize){
    setBackground(Color.blue);
    x1=((a%8)*squareSize)+(squareSize/2);
    y1=((a/8)*squareSize)+(squareSize/2);
    x2=((b%8)*squareSize)+(squareSize/2);
    y2=((b/8)*squareSize)+(squareSize/2);

    if(x1<x2){
        x=x1;w=x2-x1;
    }else{
        x=x2;w=x1-x2;
    }

    if(y1<y2){
        y=y1;h=y2-y1;
    }else{
        y=y2;h=y1-y2;
    }
    setBounds(x,y,w,h);
}

public void paint(Graphics g){
    g.setColor(getBackground());
    g.drawLine(x1-x,y1-y,x2-x,y2-y);
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉南桥 2024-08-18 01:43:01

我认为我的代码存在问题,因为它工作正常,但它似乎使用了与维基百科上提出的方程略有不同的方程,因为它考虑了当前神经元的活动状态。它正在等待我返回并编写它,因此它使用建议的公式

尝试:

public int activeNeighbours(){
    int s=0; //changed
    for(Object o:s1.neurons)
            if(((Neuron)o).isActive())s++;
    for(Object o:s2.neurons)
            if(((Neuron)o).isActive())s++;
    return s;
}

public boolean hasChanged(){
    return  oldActive != active||previousState != state;
}



public boolean isActive(){return active;}

public void updateState(){
    previousState=state;
    state+=4-activeNeighbours(); //changed
}

I think there is a problem with my code, in that it works fine, but it seems to use a slightly different equation than the one proposed on Wikipedia due to it taking into account the active status of the current neurons. It is waiting for me to go back to it and write it so it uses the proposed formula

Try:

public int activeNeighbours(){
    int s=0; //changed
    for(Object o:s1.neurons)
            if(((Neuron)o).isActive())s++;
    for(Object o:s2.neurons)
            if(((Neuron)o).isActive())s++;
    return s;
}

public boolean hasChanged(){
    return  oldActive != active||previousState != state;
}



public boolean isActive(){return active;}

public void updateState(){
    previousState=state;
    state+=4-activeNeighbours(); //changed
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文