📄 stringgene.java
字号:
/*
* This file is part of JGAP.
*
* JGAP offers a dual license model containing the LGPL as well as the MPL.
*
* For licencing information please see the file license.txt included with JGAP
* or have a look at the top of class org.jgap.Chromosome which representatively
* includes the JGAP license policy applicable for any file delivered with JGAP.
*/
package org.jgap.impl;
import java.io.*;
import java.net.*;
import java.util.*;
import org.jgap.*;
/**
* A Gene implementation that supports a string for its allele. The valid
* alphabet as well as the minimum and maximum length of the string can be
* specified.<p>
* An alphabet == null indicates that all characters are seen as valid.<br>
* An alphabet == "" indicates that no character is seen to be valid.<p>
* Partly copied from IntegerGene.
*
* @author Klaus Meffert
* @author Audrius Meskauskas
* @since 1.1
*/
public class StringGene
extends BaseGene
implements Gene {
//Constants for ready-to-use alphabets or serving as part of concetenation
public static final String ALPHABET_CHARACTERS_UPPER =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String ALPHABET_CHARACTERS_LOWER =
"abcdefghijklmnopqrstuvwxyz";
public static final String ALPHABET_CHARACTERS_DIGITS = "0123456789";
public static final String ALPHABET_CHARACTERS_SPECIAL = "+.*/\\,;@";
/** String containing the CVS revision. Read out via reflection!*/
private final static String CVS_REVISION = "$Revision: 1.26 $";
private int m_minLength;
private int m_maxLength;
private String m_alphabet;
/**
* Optional helper class for checking if a given allele value to be set
* is valid. If not the allele value may not be set for the gene!
*/
private IGeneConstraintChecker m_geneAlleleChecker;
/**
* References the internal String value (allele) of this Gene.
*/
private String m_value;
/**
* @author Klaus Meffert
* @since 1.1
*/
public StringGene() {
this(0,0);
}
/**
*
* @param a_minLength minimum valid length of allele
* @param a_maxLength maximum valid length of allele
*
* @author Klaus Meffert
* @since 1.1
*/
public StringGene(int a_minLength, int a_maxLength) {
this(a_minLength, a_maxLength, null);
}
/**
*
* @param a_minLength minimum valid length of allele
* @param a_maxLength maximum valid length of allele
* @param a_alphabet valid aplhabet for allele
*
* @author Klaus Meffert
* @since 2.0
*/
public StringGene(int a_minLength, int a_maxLength, String a_alphabet) {
if (a_minLength < 0) {
throw new IllegalArgumentException(
"minimum length must be greater than"
+ " zero!");
}
if (a_maxLength < a_minLength) {
throw new IllegalArgumentException(
"minimum length must be smaller than"
+ " or equal to maximum length!");
}
m_minLength = a_minLength;
m_maxLength = a_maxLength;
setAlphabet(a_alphabet);
}
/**
* Sets the value (allele) of this Gene to a random String according to the
* valid alphabet and boundaries of length
*
* @param a_numberGenerator The random number generator that should be
* used to create any random values. It's important
* to use this generator to maintain the user's
* flexibility to configure the genetic engine
* to use the random number generator of their
* choice.
*
* @author Klaus Meffert
* @since 1.1
*/
public void setToRandomValue(RandomGenerator a_numberGenerator) {
if (m_alphabet == null || m_alphabet.length() < 1) {
throw new IllegalStateException("The valid alphabet is empty!");
}
if (m_maxLength < m_minLength || m_maxLength < 1) {
throw new IllegalStateException(
"Illegal valid maximum and/or minimum "
+ "length of alphabet!");
}
//randomize length of string
//--------------------------
int length;
char value;
int index;
length = m_maxLength - m_minLength + 1;
int i = a_numberGenerator.nextInt() % length;
if (i < 0) {
i = -i;
}
length = m_minLength + i;
//for each character: randomize character value (which can be represented
//by an integer value)
//-----------------------------------------------------------------------
m_value = "";
final int alphabetLength = m_alphabet.length();
for (int j = 0; j < length; j++) {
index = a_numberGenerator.nextInt(alphabetLength);
value = m_alphabet.charAt(index);
m_value += value;
}
}
/**
* Sets the value and internal state of this Gene from the string
* representation returned by a previous invocation of the
* getPersistentRepresentation() method. This is an optional method but,
* if not implemented, XML persistence and possibly other features will not
* be available. An UnsupportedOperationException should be thrown if no
* implementation is provided.
*
* @param a_representation the string representation retrieved from a
* prior call to the getPersistentRepresentation()
* method.
*
* @throws UnsupportedOperationException to indicate that no implementation
* is provided for this method.
* @throws UnsupportedRepresentationException if this Gene implementation
* does not support the given string representation.
*
* @author Klaus Meffert
* @since 1.1
*/
public void setValueFromPersistentRepresentation(String a_representation)
throws UnsupportedRepresentationException {
if (a_representation != null) {
StringTokenizer tokenizer =
new StringTokenizer(a_representation,
PERSISTENT_FIELD_DELIMITER);
// Make sure the representation contains the correct number of
// fields. If not, throw an exception.
// -----------------------------------------------------------
if (tokenizer.countTokens() != 4) {
throw new UnsupportedRepresentationException(
"The format of the given persistent representation '" +
a_representation+"'"+
"is not recognized: it does not contain four tokens.");
}
String valueRepresentation;
String alphabetRepresentation;
String minLengthRepresentation;
String maxLengthRepresentation;
try {
valueRepresentation =
URLDecoder.decode (tokenizer.nextToken (), "UTF-8");
minLengthRepresentation = tokenizer.nextToken();
maxLengthRepresentation = tokenizer.nextToken();
alphabetRepresentation =
URLDecoder.decode (tokenizer.nextToken (), "UTF-8");
}
catch (UnsupportedEncodingException ex) {
throw new Error ("UTF-8 encoding should be always supported");
}
// Now parse and set the minimum length.
// -------------------------------------
try {
m_minLength = Integer.parseInt(minLengthRepresentation);
}
catch (NumberFormatException e) {
throw new UnsupportedRepresentationException(
"The format of the given persistent representation " +
"is not recognized: field 2 does not appear to be " +
"an integer value.");
}
// Now parse and set the maximum length.
// -------------------------------------
try {
m_maxLength = Integer.parseInt(maxLengthRepresentation);
}
catch (NumberFormatException e) {
throw new UnsupportedRepresentationException(
"The format of the given persistent representation " +
"is not recognized: field 3 does not appear to be " +
"an integer value.");
}
String tempValue;
// Parse and set the representation of the value.
// ----------------------------------------------
if (valueRepresentation.equals("null")) {
tempValue = null;
}
else {
if (valueRepresentation.equals( ("\"\""))) {
tempValue = "";
}
else {
tempValue = valueRepresentation;
}
}
//check if minLength and maxLength are violated
//---------------------------------------------
if (tempValue != null) {
if (m_minLength > tempValue.length()) {
throw new UnsupportedRepresentationException(
"The value given"
+ " is shorter than the allowed maximum length.");
}
if (m_maxLength < tempValue.length()) {
throw new UnsupportedRepresentationException(
"The value given"
+ " is longer than the allowed maximum length.");
}
}
//check if all characters are within the alphabet
//-----------------------------------------------
if (!isValidAlphabet(tempValue, alphabetRepresentation)) {
throw new UnsupportedRepresentationException("The value given"
+ " contains invalid characters.");
}
m_value = tempValue;
// Now set the alphabet that should be valid
// -----------------------------------------
m_alphabet = alphabetRepresentation;
}
}
/**
* Retrieves a string representation of this Gene that includes any
* information required to reconstruct it at a later time, such as its
* value and internal state. This string will be used to represent this
* Gene in XML persistence. This is an optional method but, if not
* implemented, XML persistence and possibly other features will not be
* available. An UnsupportedOperationException should be thrown if no
* implementation is provided.
*
* @return A string representation of this Gene's current state.
* @throws UnsupportedOperationException to indicate that no implementation
* is provided for this method.
*
* @author Klaus Meffert
* @since 1.1
*/
public String getPersistentRepresentation()
throws UnsupportedOperationException {
try {
String s = toString();
// The persistent representation includes the value, minimum length,
// maximum length and valid alphabet. Each is separated by a colon.
// ----------------------------------------------------------------
return URLEncoder.encode("" + toString(), "UTF-8") +
PERSISTENT_FIELD_DELIMITER + m_minLength +
PERSISTENT_FIELD_DELIMITER + m_maxLength +
PERSISTENT_FIELD_DELIMITER +
URLEncoder.encode("" + m_alphabet, "UTF-8");
}
catch (UnsupportedEncodingException ex) {
throw new Error ("UTF-8 encoding should be supported");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -