1 10 package org.jgap.impl; 11 12 import java.io.*; 13 import java.net.*; 14 import java.util.*; 15 import org.jgap.*; 16 17 29 public class StringGene 30 extends BaseGene implements IPersistentRepresentation { 31 public static final String ALPHABET_CHARACTERS_UPPER = 33 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 34 35 public static final String ALPHABET_CHARACTERS_LOWER = 36 "abcdefghijklmnopqrstuvwxyz"; 37 38 public static final String ALPHABET_CHARACTERS_DIGITS = "0123456789"; 39 40 public static final String ALPHABET_CHARACTERS_SPECIAL = "+.*/\\,;@"; 41 42 43 private final static String CVS_REVISION = "$Revision: 1.55 $"; 44 45 private int m_minLength; 46 47 private int m_maxLength; 48 49 private String m_alphabet; 50 51 54 private String m_value; 55 56 68 public StringGene() 69 throws InvalidConfigurationException { 70 this(Genotype.getStaticConfiguration()); 71 } 72 73 84 public StringGene(final Configuration a_config) 85 throws InvalidConfigurationException { 86 this(a_config, 0, 0); 87 } 88 89 102 public StringGene(final Configuration a_config, final int a_minLength, 103 final int a_maxLength) 104 throws InvalidConfigurationException { 105 this(a_config, a_minLength, a_maxLength, null); 106 } 107 108 122 public StringGene(final Configuration a_config, final int a_minLength, 123 final int a_maxLength, final String a_alphabet) 124 throws InvalidConfigurationException { 125 super(a_config); 126 if (a_minLength < 0) { 127 throw new IllegalArgumentException ( 128 "minimum length must be greater than" 129 + " zero!"); 130 } 131 if (a_maxLength < a_minLength) { 132 throw new IllegalArgumentException ( 133 "minimum length must be smaller than" 134 + " or equal to maximum length!"); 135 } 136 m_minLength = a_minLength; 137 m_maxLength = a_maxLength; 138 setAlphabet(a_alphabet); 139 } 140 141 153 public void setToRandomValue(final RandomGenerator a_numberGenerator) { 154 if (m_alphabet == null || m_alphabet.length() < 1) { 155 throw new IllegalStateException ("The valid alphabet is empty!"); 156 } 157 if (m_maxLength < m_minLength || m_maxLength < 1) { 158 throw new IllegalStateException ( 159 "Illegal valid maximum and/or minimum " 160 + "length of alphabet!"); 161 } 162 int length; 165 char value; 166 int index; 167 length = m_maxLength - m_minLength + 1; 168 int i = a_numberGenerator.nextInt() % length; 169 if (i < 0) { 170 i = -i; 171 } 172 length = m_minLength + i; 173 String newAllele = ""; 177 final int alphabetLength = m_alphabet.length(); 178 for (int j = 0; j < length; j++) { 179 index = a_numberGenerator.nextInt(alphabetLength); 180 value = m_alphabet.charAt(index); 181 newAllele += value; 182 } 183 setAllele(newAllele); 186 } 187 188 205 public void setValueFromPersistentRepresentation(final String 206 a_representation) 207 throws UnsupportedRepresentationException { 208 if (a_representation != null) { 209 StringTokenizer tokenizer = 210 new StringTokenizer(a_representation, 211 PERSISTENT_FIELD_DELIMITER); 212 if (tokenizer.countTokens() != 4) { 216 throw new UnsupportedRepresentationException( 217 "The format of the given persistent representation '" + 218 a_representation + "'" + 219 "is not recognized: it does not contain four tokens."); 220 } 221 String valueRepresentation; 222 String alphabetRepresentation; 223 String minLengthRepresentation; 224 String maxLengthRepresentation; 225 try { 226 valueRepresentation = 227 URLDecoder.decode(tokenizer.nextToken(), "UTF-8"); 228 minLengthRepresentation = tokenizer.nextToken(); 229 maxLengthRepresentation = tokenizer.nextToken(); 230 alphabetRepresentation = 231 URLDecoder.decode(tokenizer.nextToken(), "UTF-8"); 232 } 233 catch (UnsupportedEncodingException ex) { 234 throw new Error ("UTF-8 encoding should be always supported"); 235 } 236 try { 239 m_minLength = Integer.parseInt(minLengthRepresentation); 240 } 241 catch (NumberFormatException e) { 242 throw new UnsupportedRepresentationException( 243 "The format of the given persistent representation " + 244 "is not recognized: field 2 does not appear to be " + 245 "an integer value."); 246 } 247 try { 250 m_maxLength = Integer.parseInt(maxLengthRepresentation); 251 } 252 catch (NumberFormatException e) { 253 throw new UnsupportedRepresentationException( 254 "The format of the given persistent representation " + 255 "is not recognized: field 3 does not appear to be " + 256 "an integer value."); 257 } 258 String tempValue; 259 if (valueRepresentation.equals("null")) { 262 tempValue = null; 263 } 264 else { 265 if (valueRepresentation.equals( ("\"\""))) { 266 tempValue = ""; 267 } 268 else { 269 tempValue = valueRepresentation; 270 } 271 } 272 if (tempValue != null) { 275 if (m_minLength > tempValue.length()) { 276 throw new UnsupportedRepresentationException( 277 "The value given" 278 + " is shorter than the allowed maximum length."); 279 } 280 if (m_maxLength < tempValue.length()) { 281 throw new UnsupportedRepresentationException( 282 "The value given" 283 + " is longer than the allowed maximum length."); 284 } 285 } 286 if (!isValidAlphabet(tempValue, alphabetRepresentation)) { 289 throw new UnsupportedRepresentationException("The value given" 290 + " contains invalid characters."); 291 } 292 m_value = tempValue; 293 m_alphabet = alphabetRepresentation; 296 } 297 } 298 299 315 public String getPersistentRepresentation() 316 throws UnsupportedOperationException { 317 try { 318 String s; 322 if (m_value == null) { 323 s = "null"; 324 } 325 else { 326 if (m_value.equals("")) { 327 s = "\"\""; 328 } 329 else { 330 s = m_value; 331 } 332 } 333 return URLEncoder.encode("" + s, "UTF-8") + 334 PERSISTENT_FIELD_DELIMITER + m_minLength + 335 PERSISTENT_FIELD_DELIMITER + m_maxLength + 336 PERSISTENT_FIELD_DELIMITER + 337 URLEncoder.encode("" + m_alphabet, "UTF-8"); 338 } 339 catch (UnsupportedEncodingException ex) { 340 throw new Error ("UTF-8 encoding should be supported"); 341 } 342 } 343 344 355 public void setAllele(final Object a_newValue) { 356 if (a_newValue != null) { 357 String temp = (String ) a_newValue; 358 if (temp.length() < m_minLength || 359 temp.length() > m_maxLength) { 360 throw new IllegalArgumentException ( 361 "The given value is too short or too long!"); 362 } 363 if (!isValidAlphabet(temp, m_alphabet)) { 366 throw new IllegalArgumentException ("The given value contains" 367 + " at least one invalid character."); 368 } 369 if (getConstraintChecker() != null) { 370 if (!getConstraintChecker().verify(this, a_newValue, null, -1)) { 371 return; 372 } 373 } 374 m_value = temp; 375 } 376 else { 377 m_value = null; 378 } 379 } 380 381 391 protected Gene newGeneInternal() { 392 try { 393 StringGene result = new StringGene(getConfiguration(), m_minLength, 394 m_maxLength, m_alphabet); 395 result.setConstraintChecker(getConstraintChecker()); 396 return result; 397 } 398 catch (InvalidConfigurationException iex) { 399 throw new IllegalStateException (iex.getMessage()); 400 } 401 } 402 403 418 public int compareTo(Object a_other) { 419 StringGene otherStringGene = (StringGene) a_other; 420 if (otherStringGene == null) { 425 return 1; 426 } 427 else if (otherStringGene.m_value == null) { 428 if (m_value == null) { 432 if (isCompareApplicationData()) { 433 return compareApplicationData(getApplicationData(), 434 otherStringGene.getApplicationData()); 435 } 436 else { 437 return 0; 438 } 439 } 440 else { 441 return 1; 442 } 443 } 444 else { 445 int res = m_value.compareTo(otherStringGene.m_value); 446 if (res == 0) { 447 if (isCompareApplicationData()) { 448 return compareApplicationData(getApplicationData(), 449 otherStringGene.getApplicationData()); 450 } 451 else { 452 return 0; 453 } 454 } 455 else { 456 return res; 457 } 458 } 459 } 460 461 public int size() { 462 return m_value.length(); 463 } 464 465 public int getMaxLength() { 466 return m_maxLength; 467 } 468 469 public int getMinLength() { 470 return m_minLength; 471 } 472 473 public void setMinLength(int m_minLength) { 474 this.m_minLength = m_minLength; 475 } 476 477 public void setMaxLength(int m_maxLength) { 478 this.m_maxLength = m_maxLength; 479 } 480 481 public String getAlphabet() { 482 return m_alphabet; 483 } 484 485 494 public void setAlphabet(String a_alphabet) { 495 m_alphabet = a_alphabet; 496 } 497 498 507 public String toString() { 508 String s = "StringGene="; 509 if (m_value == null) { 510 s += "null"; 511 } 512 else { 513 if (m_value.equals("")) { 514 s += "\"\""; 515 } 516 else { 517 s += m_value; 518 } 519 } 520 return s; 521 } 522 523 531 public String stringValue() { 532 return m_value; 533 } 534 535 544 private boolean isValidAlphabet(String a_value, String a_alphabet) { 545 if (a_value == null || a_value.length() < 1) { 546 return true; 547 } 548 if (a_alphabet == null) { 549 return true; 550 } 551 if (a_alphabet.length() < 1) { 552 return false; 553 } 554 int length = a_value.length(); 557 char c; 558 for (int i = 0; i < length; i++) { 559 c = a_value.charAt(i); 560 if (a_alphabet.indexOf(c) < 0) { 561 return false; 562 } 563 } 564 return true; 565 } 566 567 577 public void applyMutation(int index, double a_percentage) { 578 String s = stringValue(); 579 int index2 = -1; 580 boolean randomize; 581 int len = 0; 582 if (m_alphabet != null) { 583 len = m_alphabet.length(); 584 if (len < 1) { 585 randomize = true; 588 } 589 else { 590 randomize = false; 591 } 592 } 593 else { 594 randomize = true; 595 } 596 char newValue; 597 RandomGenerator rn = getConfiguration().getRandomGenerator(); 598 if (!randomize) { 599 int indexC = m_alphabet.indexOf(s.charAt(index)); 600 index2 = indexC + (int) Math.round(len * a_percentage); 601 if (index2 < 0 || index2 >= len) { 606 index2 = rn.nextInt(len); 607 } 608 newValue = m_alphabet.charAt(index2); 609 } 610 else { 611 index2 = rn.nextInt(256); 612 newValue = (char) index2; 613 } 614 if (s == null) { 617 s = "" + newValue; 618 } 619 else { 620 s = s.substring(0, index) + newValue + s.substring(index + 1); 621 } 622 setAllele(s); 623 } 624 625 protected Object getInternalValue() { 626 return m_value; 627 } 628 } 629 | Popular Tags |