All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.cilib.functions.discrete.RepairingKnightsTour Maven / Gradle / Ivy

/**           __  __
 *    _____ _/ /_/ /_    Computational Intelligence Library (CIlib)
 *   / ___/ / / / __ \   (c) CIRG @ UP
 *  / /__/ / / / /_/ /   http://cilib.net
 *  \___/_/_/_/_.___/
 */
package net.sourceforge.cilib.functions.discrete;

import net.sourceforge.cilib.functions.DiscreteFunction;
import net.sourceforge.cilib.type.types.container.Vector;

/**
 * An implementation of the Knight's Tour problem function. It is important to note
 * that this implementation implements a repair to the evaluation of the potential
 * solution. The reasoning behind this is that the knight all too often during the
 * testing phase would jump off the board and remain off the board.
 * 

* The repair is a simple in-order operation that determines the position where the * error occurred and tries to replace the error move with one of the possible 7 * moves remaining. Once the tour can continue, the move is replaced and evaluation * continues. */ public class RepairingKnightsTour extends DiscreteFunction { private static final long serialVersionUID = 6961834833997387285L; private int boardSize; private boolean cyclic; private String startingPos = null; private final int startX; private final int startY; private static final int[] MOVEMENT_X = {-2, -1, 1, 2, 2, 1, -1, -2}; private static final int[] MOVEMENT_Y = {-1, -2, -2, -1, 1, 2, -2, -1}; /** * */ public RepairingKnightsTour() { this.boardSize = 8; this.cyclic = false; this.startX = 0; this.startY = 0; // setDomain("B^"+boardSize*boardSize*3); } /** * */ @Override public Integer f(Vector input) { int fitness = 0; int row = startX; int col = startY; boolean[][] visited = new boolean[boardSize][boardSize]; for (int i = 0; i < boardSize; i++) { for (int j = 0; j < boardSize; j++) { visited[i][j] = false; } } int move = 0; while (true) { if (0 <= row && row < boardSize && 0 <= col && col < boardSize) { int moveNum = decode(input.booleanValueOf(move * 3), input.booleanValueOf(move * 3 + 1), input.booleanValueOf(move * 3 + 2)); if (!visited[row][col]) { fitness++; move++; // if (move == getMaximum() - 1) { // break; // } visited[row][col] = true; } row += MOVEMENT_X[moveNum]; col += MOVEMENT_Y[moveNum]; if (0 <= row && row < boardSize && 0 <= col && col < boardSize && !visited[row][col]) { // Nothing to do :) No need to repair } else { row -= MOVEMENT_X[moveNum]; col -= MOVEMENT_Y[moveNum]; int test = 0; for (int k = 0; k < 8; k++) { if (k == moveNum) { // Nothing to do :) } else { int newX = row + MOVEMENT_X[k]; int newY = col + MOVEMENT_Y[k]; if (0 <= newX && newX < boardSize && 0 <= newY && newY < boardSize && !visited[newX][newY]) { row = newX; col = newY; test++; modifyBits(input, move, k); break; } } } if (test == 0) { break; } } } else { break; } } return fitness; } /** * * @param b1 * @param b2 * @param b3 * @return the decoded value. */ private int decode(boolean b1, boolean b2, boolean b3) { int i0 = b1 ? 1 : 0; int i1 = b2 ? 1 : 0; int i2 = b3 ? 1 : 0; return 4*i0 + 2*i1 + i2; } /** * * @param x * @param move * @param k */ private void modifyBits(Vector x, int move, int k) { x.setInt(move * 3, (k >> 2) & 1); x.setInt(move * 3, (k >> 1) & 1); x.setInt(move * 3, k & 1); } /** * @return Returns the boardSize. */ public int getBoardSize() { return boardSize; } /** * @param boardSize The boardSize to set. */ public void setBoardSize(int boardSize) { this.boardSize = boardSize; // setDomain("B^"+boardSize*boardSize*3); } /** * @return Returns the cyclic. */ public boolean isCyclic() { return cyclic; } /** * @param cyclic The cyclic to set. */ public void setCyclic(boolean cyclic) { this.cyclic = cyclic; } /** * @return Returns the startingPos. */ public String getStartingPos() { return startingPos; } /** * Set the starting position on the board. Following the normal chess convention * the rows are described by letters (A-H) on the 8x8 board and columns (0-7). * These row and column values can obviously be adjusted to the currently set board * size. * * @param startingPos The startingPos to set. */ public void setStartingPos(String startingPos) { this.startingPos = startingPos; } // // @Override // public String getDomain() { // return "B^"+boardSize*boardSize*3; // } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy