001/* 002 * Java Genetic Algorithm Library (jenetics-5.1.0). 003 * Copyright (c) 2007-2019 Franz Wilhelmstötter 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 * Author: 018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) 019 */ 020package io.jenetics.xml; 021 022import static java.util.Objects.requireNonNull; 023import static io.jenetics.xml.stream.Writer.attr; 024import static io.jenetics.xml.stream.Writer.elem; 025import static io.jenetics.xml.stream.Writer.elems; 026import static io.jenetics.xml.stream.Writer.text; 027 028import java.io.OutputStream; 029import java.util.Collection; 030import java.util.stream.Collectors; 031 032import javax.xml.stream.XMLStreamException; 033 034import io.jenetics.BoundedGene; 035import io.jenetics.Chromosome; 036import io.jenetics.DoubleGene; 037import io.jenetics.Gene; 038import io.jenetics.IntegerGene; 039import io.jenetics.LongGene; 040 041import io.jenetics.xml.stream.AutoCloseableXMLStreamWriter; 042import io.jenetics.xml.stream.Writer; 043import io.jenetics.xml.stream.XML; 044 045/** 046 * This class contains static fields and methods, for creating chromosome- and 047 * genotype writers for different gene types. 048 * 049 * <pre>{@code 050 * final Writer<Genotype<BitGene> bgw = 051 * Writers.Genotype.writer(Writers.BitChromosome.writer())); 052 * 053 * final Writer<Genotype<IntegerGene>> igw = 054 * Writers.Genotype.writer(Writers.IntegerChromosome.writer())); 055 * 056 * final Writer<Genotype<DoubleGene>> dgw = 057 * Writers.Genotype.writer(Writers.DoubleChromosome.writer())); 058 * }</pre> 059 * 060 * This class also contains some helper methods, which makes it easier to write 061 * Jenetics domain objects to a given output stream. 062 * <pre>{@code 063 * final List<Genotype<BitGene>> genotypes = ...; 064 * try (OutputStream out = Files.newOutputStream(Paths.get("path"))) { 065 * Writers.write(out, genotypes, Writers.BitChromosome.writer()); 066 * } 067 * }</pre> 068 * 069 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 070 * @version 3.9 071 * @since 3.9 072 */ 073public final class Writers { 074 private Writers() {} 075 076 /** 077 * This class contains static writer methods for 078 * {@link io.jenetics.BitChromosome} objects. 079 * <p> 080 * <b>Writer code</b> 081 * <pre>{@code 082 * final BitChromosome value = BitChromosome.of(20, 0.5); 083 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 084 * Writers.BitChromosome.writer().write(value, xml); 085 * } 086 * }</pre> 087 * 088 * <b>XML output</b> 089 * <pre> {@code 090 * <bit-chromosome length="20" ones-probability="0.5">11100011101011001010</bit-chromosome> 091 * }</pre> 092 * 093 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 094 * @version 3.9 095 * @since 3.9 096 */ 097 public static final class BitChromosome { 098 private BitChromosome() {} 099 100 static final String ROOT_NAME = "bit-chromosome"; 101 static final String LENGTH_NAME = "length"; 102 static final String ONES_PROBABILITY_NAME = "ones-probability"; 103 104 /** 105 * Return a {@link Writer} for {@link io.jenetics.BitChromosome} 106 * objects. 107 * 108 * @return a chromosome writer 109 */ 110 public static Writer<io.jenetics.BitChromosome> writer() { 111 return elem(ROOT_NAME, 112 attr(LENGTH_NAME).map(io.jenetics.BitChromosome::length), 113 attr(ONES_PROBABILITY_NAME).map(ch -> ch.getOneProbability()), 114 text().map(io.jenetics.BitChromosome::toCanonicalString) 115 ); 116 } 117 118 /** 119 * Write the given {@link io.jenetics.BitChromosome} to the given 120 * output stream. 121 * 122 * @param out the target output stream 123 * @param data the bit-chromosome to write 124 * @throws XMLStreamException if an error occurs while writing the 125 * chromosome 126 * @throws NullPointerException if one of the given arguments is 127 * {@code null} 128 */ 129 public static void write( 130 final OutputStream out, 131 final io.jenetics.BitChromosome data 132 ) 133 throws XMLStreamException 134 { 135 requireNonNull(data); 136 requireNonNull(out); 137 138 try (AutoCloseableXMLStreamWriter xml = XML.writer(out)) { 139 writer().write(xml, data); 140 } 141 } 142 } 143 144 145 /** 146 * This class contains static writer methods for 147 * {@link io.jenetics.CharacterChromosome} objects. 148 * <p> 149 * <b>Writer code</b> 150 * <pre>{@code 151 * final CharacterChromosome value = CharacterChromosome.of("ASDF", CharSeq.of("A-Z")); 152 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 153 * Writers.CharacterChromosome.writer().write(value, xml); 154 * } 155 * }</pre> 156 * 157 * <b>XML output</b> 158 * <pre> {@code 159 * <character-chromosome length="4"> 160 * <valid-alleles>ABCDEFGHIJKLMNOPQRSTUVWXYZ<valid-alleles> 161 * <alleles>ASDF</alleles> 162 * </character-chromosome> 163 * }</pre> 164 */ 165 public static final class CharacterChromosome { 166 private CharacterChromosome() {} 167 168 static final String ROOT_NAME = "character-chromosome"; 169 static final String LENGTH_NAME = "length"; 170 static final String VALID_ALLELES_NAME = "valid-alleles"; 171 static final String ALLELES_NAME = "alleles"; 172 173 /** 174 * Return a {@link Writer} for {@link io.jenetics.CharacterChromosome} 175 * objects. 176 * 177 * @return a chromosome writer 178 */ 179 public static Writer<io.jenetics.CharacterChromosome> writer() { 180 return elem(ROOT_NAME, 181 attr(LENGTH_NAME).map(io.jenetics.CharacterChromosome::length), 182 elem(VALID_ALLELES_NAME, 183 text().map(ch -> ch.getGene().getValidCharacters())), 184 elem(ALLELES_NAME, 185 text().map(io.jenetics.CharacterChromosome::toString)) 186 ); 187 } 188 189 /** 190 * Write the given {@link io.jenetics.CharacterChromosome} to the given 191 * output stream. 192 * 193 * @param out the target output stream 194 * @param data the chromosome to write 195 * @param indent the XML level indentation 196 * @throws XMLStreamException if an error occurs while writing the 197 * chromosome 198 * @throws NullPointerException if the {@code chromosome} or output 199 * stream is {@code null} 200 */ 201 public static void write( 202 final OutputStream out, 203 final io.jenetics.CharacterChromosome data, 204 final String indent 205 ) 206 throws XMLStreamException 207 { 208 requireNonNull(data); 209 requireNonNull(out); 210 211 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 212 writer().write(xml, data); 213 } 214 } 215 216 /** 217 * Write the given {@link io.jenetics.CharacterChromosome} to the given 218 * output stream. 219 * 220 * @param out the target output stream 221 * @param data the chromosome to write 222 * @throws XMLStreamException if an error occurs while writing the 223 * chromosome 224 * @throws NullPointerException if the {@code chromosome} or output 225 * stream is {@code null} 226 */ 227 public static void write( 228 final OutputStream out, 229 final io.jenetics.CharacterChromosome data 230 ) 231 throws XMLStreamException 232 { 233 write(out, data, null); 234 } 235 236 } 237 238 /** 239 * This class contains static writer methods for 240 * {@link io.jenetics.BoundedChromosome} objects. 241 * 242 * <p> 243 * <b>XML template</b> 244 * <pre> {@code 245 * <root-name length="3"> 246 * <min>aaa</min> 247 * <max>zzz</max> 248 * <alleles> 249 * <allele>iii</allele> 250 * <allele>fff</allele> 251 * <allele>ggg</allele> 252 * </alleles> 253 * </root-name> 254 * }</pre> 255 */ 256 public static final class BoundedChromosome { 257 private BoundedChromosome() {} 258 259 static final String LENGTH_NAME = "length"; 260 static final String MIN_NAME = "min"; 261 static final String MAX_NAME = "max"; 262 static final String ALLELE_NAME = "allele"; 263 static final String ALLELES_NAME = "alleles"; 264 265 /** 266 * Create a bounded chromosome writer with the given configuration. 267 * 268 * @param rootName the name of the root element. E.g. {@code int-chromosome} 269 * @param alleleWriter the XML writer used for the alleles 270 * @param <A> the allele type 271 * @param <G> the bounded gene type 272 * @param <C> the bounded chromosome type 273 * @return a bounded chromosome XML writer 274 * @throws NullPointerException if one of the arguments is {@code null} 275 */ 276 public static < 277 A extends Comparable<? super A>, 278 G extends BoundedGene<A, G>, 279 C extends io.jenetics.BoundedChromosome<A, G> 280 > 281 Writer<C> writer( 282 final String rootName, 283 final Writer<? super A> alleleWriter 284 ) { 285 requireNonNull(rootName); 286 requireNonNull(alleleWriter); 287 288 return elem(rootName, 289 attr(LENGTH_NAME).map(ch -> ch.length()), 290 elem(MIN_NAME, alleleWriter.map(ch -> ch.getMin())), 291 elem(MAX_NAME, alleleWriter.map(ch -> ch.getMax())), 292 elem(ALLELES_NAME, 293 elems(ALLELE_NAME, alleleWriter) 294 .map(ch -> ch.toSeq().map(G::getAllele)) 295 ) 296 ); 297 } 298 } 299 300 /** 301 * This class contains static writer methods for 302 * {@link io.jenetics.IntegerChromosome} objects. 303 * <p> 304 * <b>Writer code</b> 305 * <pre>{@code 306 * final IntegerChromosome value = IntegerChromosome 307 * .of(Integer.MIN_VALUE, Integer.MAX_VALUE, 3); 308 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 309 * Writers.IntegerChromosome.writer().write(value, xml); 310 * } 311 * }</pre> 312 * 313 * <b>XML output</b> 314 * <pre> {@code 315 * <int-chromosome length="3"> 316 * <min>-2147483648</min> 317 * <max>2147483647</max> 318 * <alleles> 319 * <allele>-1878762439</allele> 320 * <allele>-957346595</allele> 321 * <allele>-88668137</allele> 322 * </alleles> 323 * </int-chromosome> 324 * }</pre> 325 */ 326 public static final class IntegerChromosome { 327 private IntegerChromosome() {} 328 329 static final String ROOT_NAME = "int-chromosome"; 330 331 /** 332 * Return the default integer allele writer for the 333 * {@code IntegerChromosome}. 334 * 335 * @return the default integer allele writer 336 */ 337 public static Writer<Integer> alleleWriter() { 338 return text(); 339 } 340 341 /** 342 * Return a {@link Writer} for {@link io.jenetics.IntegerChromosome} 343 * objects. 344 * 345 * @param alleleWriter the allele writer used for writing the integer 346 * allele. Might be useful for using different integer 347 * <i>encodings</i>. 348 * @return a chromosome writer 349 * @throws NullPointerException if the given {@code alleleWriter} is 350 * {@code null} 351 */ 352 public static Writer<io.jenetics.IntegerChromosome> 353 writer(final Writer<? super Integer> alleleWriter) { 354 requireNonNull(alleleWriter); 355 356 return BoundedChromosome.< 357 Integer, 358 IntegerGene, 359 io.jenetics.IntegerChromosome 360 >writer(ROOT_NAME, alleleWriter); 361 } 362 363 /** 364 * Return a {@link Writer} for {@link io.jenetics.IntegerChromosome} 365 * objects. 366 * 367 * @return a chromosome writer 368 */ 369 public static Writer<io.jenetics.IntegerChromosome> writer() { 370 return writer(alleleWriter()); 371 } 372 373 /** 374 * Write the given {@link io.jenetics.IntegerChromosome} to the given 375 * output stream. 376 * 377 * @param out the target output stream 378 * @param data the chromosome to write 379 * @param indent the XML level indentation 380 * @throws XMLStreamException if an error occurs while writing the 381 * chromosome 382 * @throws NullPointerException if the {@code chromosome} or output 383 * stream is {@code null} 384 */ 385 public static void write( 386 final OutputStream out, 387 final io.jenetics.IntegerChromosome data, 388 final String indent 389 ) 390 throws XMLStreamException 391 { 392 requireNonNull(data); 393 requireNonNull(out); 394 395 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 396 writer().write(xml, data); 397 } 398 } 399 400 /** 401 * Write the given {@link io.jenetics.IntegerChromosome} to the given 402 * output stream. 403 * 404 * @param out the target output stream 405 * @param data the chromosome to write 406 * @throws XMLStreamException if an error occurs while writing the 407 * chromosome 408 * @throws NullPointerException if the {@code chromosome} or output 409 * stream is {@code null} 410 */ 411 public static void write( 412 final OutputStream out, 413 final io.jenetics.IntegerChromosome data 414 ) 415 throws XMLStreamException 416 { 417 write(out, data, null); 418 } 419 } 420 421 /** 422 * This class contains static writer methods for 423 * {@link io.jenetics.LongChromosome} objects. 424 * <p> 425 * <b>Writer code</b> 426 * <pre>{@code 427 * final LongChromosome value = LongChromosome 428 * .of(Long.MIN_VALUE, Long.MAX_VALUE, 3); 429 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 430 * Writers.LongChromosome.writer().write(value, xml); 431 * } 432 * }</pre> 433 * 434 * <b>XML output</b> 435 * <pre> {@code 436 * <long-chromosome length="3"> 437 * <min>-9223372036854775808</min> 438 * <max>9223372036854775807</max> 439 * <alleles> 440 * <allele>-1345217698116542402</allele> 441 * <allele>-7144755673073475303</allele> 442 * <allele>6053786736809578435</allele> 443 * </alleles> 444 * </long-chromosome> 445 * }</pre> 446 */ 447 public static final class LongChromosome { 448 private LongChromosome() {} 449 450 static final String ROOT_NAME = "long-chromosome"; 451 452 /** 453 * Return the default long allele writer for the 454 * {@code IntegerChromosome}. 455 * 456 * @return the default long allele writer 457 */ 458 public static Writer<Long> alleleWriter() { 459 return Writer.text(); 460 } 461 462 /** 463 * Return a {@link Writer} for {@link io.jenetics.LongChromosome} 464 * objects. 465 * 466 * @param alleleWriter the allele writer used for writing the long 467 * allele. Might be useful for using different long 468 * <i>encodings</i>. 469 * @return a chromosome writer 470 * @throws NullPointerException if the given {@code alleleWriter} is 471 * {@code null} 472 */ 473 public static Writer<io.jenetics.LongChromosome> 474 writer(final Writer<? super Long> alleleWriter) { 475 return BoundedChromosome.< 476 Long, 477 LongGene, 478 io.jenetics.LongChromosome 479 >writer(ROOT_NAME, alleleWriter); 480 } 481 482 /** 483 * Return a {@link Writer} for {@link io.jenetics.LongChromosome} 484 * objects. 485 * 486 * @return a chromosome writer 487 */ 488 public static Writer<io.jenetics.LongChromosome> writer() { 489 return writer(alleleWriter()); 490 } 491 492 /** 493 * Write the given {@link io.jenetics.LongChromosome} to the given 494 * output stream. 495 * 496 * @param out the target output stream 497 * @param data the chromosome to write 498 * @param indent the XML level indentation 499 * @throws XMLStreamException if an error occurs while writing the 500 * chromosome 501 * @throws NullPointerException if the {@code chromosome} or output 502 * stream is {@code null} 503 */ 504 public static void write( 505 final OutputStream out, 506 final io.jenetics.LongChromosome data, 507 final String indent 508 ) 509 throws XMLStreamException 510 { 511 requireNonNull(data); 512 requireNonNull(out); 513 514 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 515 writer().write(xml, data); 516 } 517 } 518 519 /** 520 * Write the given {@link io.jenetics.LongChromosome} to the given 521 * output stream. 522 * 523 * @param out the target output stream 524 * @param data the chromosome to write 525 * @throws XMLStreamException if an error occurs while writing the 526 * chromosome 527 * @throws NullPointerException if the {@code chromosome} or output 528 * stream is {@code null} 529 */ 530 public static void write( 531 final OutputStream out, 532 final io.jenetics.LongChromosome data 533 ) 534 throws XMLStreamException 535 { 536 write(out, data, null); 537 } 538 } 539 540 /** 541 * This class contains static writer methods for 542 * {@link io.jenetics.DoubleChromosome} objects. 543 * <p> 544 * <b>Writer code</b> 545 * <pre>{@code 546 * final DoubleChromosome value = DoubleChromosome.of(0.0, 1.0, 3); 547 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 548 * Writers.DoubleChromosome.writer().write(value, xml); 549 * } 550 * }</pre> 551 * 552 * <b>XML output</b> 553 * <pre> {@code 554 * <double-chromosome length="3"> 555 * <min>0.0</min> 556 * <max>1.0</max> 557 * <alleles> 558 * <allele>0.27251556008507416</allele> 559 * <allele>0.003140816229067145</allele> 560 * <allele>0.43947528327497376</allele> 561 * </alleles> 562 * </double-chromosome> 563 * }</pre> 564 */ 565 public static final class DoubleChromosome 566 //extends WriterProvider<io.jenetics.DoubleChromosome> 567 { 568 private DoubleChromosome() {} 569 570 static final String ROOT_NAME = "double-chromosome"; 571 572 /** 573 * Return the default double allele writer for the 574 * {@code DoubleChromosome}. 575 * 576 * @return the default double allele writer 577 */ 578 public static Writer<Double> alleleWriter() { 579 return text().map(Object::toString); 580 } 581 582 /** 583 * Return a {@link Writer} for {@link io.jenetics.DoubleChromosome} 584 * objects. 585 * 586 * @param alleleWriter the allele writer used for writing the long 587 * allele. Might be useful for using different long 588 * <i>encodings</i>. 589 * @return a chromosome writer 590 * @throws NullPointerException if the given {@code alleleWriter} is 591 * {@code null} 592 */ 593 public static Writer<io.jenetics.DoubleChromosome> 594 writer(final Writer<? super Double> alleleWriter) { 595 return BoundedChromosome.< 596 Double, 597 DoubleGene, 598 io.jenetics.DoubleChromosome 599 >writer(ROOT_NAME, alleleWriter); 600 } 601 602 /** 603 * Return a {@link Writer} for {@link io.jenetics.DoubleChromosome} 604 * objects. 605 * 606 * @return a chromosome writer 607 */ 608 public static Writer<io.jenetics.DoubleChromosome> writer() { 609 return writer(alleleWriter()); 610 } 611 612 public Class<io.jenetics.DoubleChromosome> type() { 613 return io.jenetics.DoubleChromosome.class; 614 } 615 616 /** 617 * Write the given {@link io.jenetics.DoubleChromosome} to the given 618 * output stream. 619 * 620 * @param out the target output stream 621 * @param data the chromosome to write 622 * @param indent the XML level indentation 623 * @throws XMLStreamException if an error occurs while writing the 624 * chromosome 625 * @throws NullPointerException if the {@code chromosome} or output 626 * stream is {@code null} 627 */ 628 public static void write( 629 final OutputStream out, 630 final io.jenetics.DoubleChromosome data, 631 final String indent 632 ) 633 throws XMLStreamException 634 { 635 requireNonNull(data); 636 requireNonNull(out); 637 638 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 639 writer().write(xml, data); 640 } 641 } 642 643 /** 644 * Write the given {@link io.jenetics.DoubleChromosome} to the given 645 * output stream. 646 * 647 * @param out the target output stream 648 * @param data the chromosome to write 649 * @throws XMLStreamException if an error occurs while writing the 650 * chromosome 651 * @throws NullPointerException if the {@code chromosome} or output 652 * stream is {@code null} 653 */ 654 public static void write( 655 final OutputStream out, 656 final io.jenetics.DoubleChromosome data 657 ) 658 throws XMLStreamException 659 { 660 write(out, data, null); 661 } 662 } 663 664 /** 665 * This class contains static writer methods for 666 * {@link io.jenetics.PermutationChromosome} objects. 667 * <p> 668 * <b>Writer code</b> 669 * <pre>{@code 670 * final PermutationChromosome<Integer> value = 671 * PermutationChromosome.ofInteger(5) 672 * 673 * final Writer<PermutationChromosome<Integer> writer = 674 * Writers.PermutationChromosome.writer(); 675 * 676 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 677 * Writers.PermutationChromosome.writer().write(value, xml); 678 * } 679 * }</pre> 680 * 681 * <b>XML output</b> 682 * <pre> {@code 683 * <permutation-chromosome length="5"> 684 * <valid-alleles type="java.lang.Integer"> 685 * <allele>0</allele> 686 * <allele>1</allele> 687 * <allele>2</allele> 688 * <allele>3</allele> 689 * <allele>4</allele> 690 * </valid-alleles> 691 * <order>2 1 3 5 4</order> 692 * </permutation-chromosome> 693 * }</pre> 694 */ 695 public static final class PermutationChromosome { 696 private PermutationChromosome() {} 697 698 static final String ROOT_NAME = "permutation-chromosome"; 699 static final String LENGTH_NAME = "length"; 700 static final String VALID_ALLELES_NAME = "valid-alleles"; 701 static final String ALLELE_NAME = "allele"; 702 static final String ORDER_NAME = "order"; 703 704 /** 705 * Create a writer for permutation-chromosomes. How to write the valid 706 * alleles is defined by the given {@link Writer}. 707 * 708 * @param alleleWriter the allele writer 709 * @param <A> the allele type 710 * @return a new permutation chromosome writer 711 * @throws NullPointerException if the given allele {@code writer} is 712 * {@code null} 713 */ 714 public static <A> Writer<io.jenetics.PermutationChromosome<A>> 715 writer(final Writer<? super A> alleleWriter) { 716 return Writer.<io.jenetics.PermutationChromosome<A>>elem( 717 ROOT_NAME, 718 attr(LENGTH_NAME).map(io.jenetics.PermutationChromosome::length), 719 elem(VALID_ALLELES_NAME, 720 attr("type").map(PermutationChromosome::toAlleleTypeName), 721 Writer.<A>elems(ALLELE_NAME, alleleWriter) 722 .map(ch -> ch.getValidAlleles()) 723 ), 724 elem(ORDER_NAME, text()) 725 .map(ch -> ch.stream() 726 .map(g -> Integer.toString(g.getAlleleIndex())) 727 .collect(Collectors.joining(" "))) 728 ); 729 } 730 731 private static String toAlleleTypeName( 732 final io.jenetics.PermutationChromosome<?> ch 733 ) { 734 return ch.getGene().getAllele().getClass().getCanonicalName(); 735 } 736 737 /** 738 * Create a writer for permutation-chromosomes. The valid alleles are 739 * serialized by calling the {@link Object#toString()} method. Calling 740 * this method is equivalent with: 741 * <pre>{@code 742 * final Writer<PermutationChromosome<Double> writer = 743 * PermutationChromosome.write(text().map(Objects::toString)); 744 * }</pre> 745 * 746 * Example output: 747 * <pre> {@code 748 * <permutation-chromosome length="15"> 749 * <valid-alleles type="java.lang.Double"> 750 * <allele>0.27251556008507416</allele> 751 * <allele>0.003140816229067145</allele> 752 * <allele>0.43947528327497376</allele> 753 * <allele>0.10654807463069327</allele> 754 * <allele>0.19696530915810317</allele> 755 * <allele>0.7450003838065538</allele> 756 * <allele>0.5594416969271359</allele> 757 * <allele>0.02823782430152355</allele> 758 * <allele>0.5741102315010789</allele> 759 * <allele>0.4533651041367144</allele> 760 * <allele>0.811148141800367</allele> 761 * <allele>0.5710456351848858</allele> 762 * <allele>0.30166768355230955</allele> 763 * <allele>0.5455492865240272</allele> 764 * <allele>0.21068427527733102</allele> 765 * </valid-alleles> 766 * <order>13 12 4 6 8 14 7 2 11 5 3 0 9 10 1</order> 767 * </permutation-chromosome> 768 * }</pre> 769 * 770 * @param <A> the allele type 771 * @return a new permutation chromosome writer 772 */ 773 public static <A> Writer<io.jenetics.PermutationChromosome<A>> writer() { 774 return writer(text()); 775 } 776 777 /** 778 * Write the given {@link io.jenetics.PermutationChromosome} to the 779 * given output stream. 780 * 781 * @param <A> the allele type 782 * @param out the target output stream 783 * @param data the chromosome to write 784 * @param indent the XML level indentation 785 * @throws XMLStreamException if an error occurs while writing the 786 * chromosome 787 * @throws NullPointerException if the {@code chromosome} or output 788 * stream is {@code null} 789 */ 790 public static <A> void write( 791 final OutputStream out, 792 final io.jenetics.PermutationChromosome<A> data, 793 final String indent 794 ) 795 throws XMLStreamException 796 { 797 requireNonNull(data); 798 requireNonNull(out); 799 800 try (AutoCloseableXMLStreamWriter writer = XML.writer(out, indent)) { 801 PermutationChromosome.<A>writer().write(writer, data); 802 } 803 } 804 805 /** 806 * Write the given {@link io.jenetics.PermutationChromosome} to the 807 * given output stream. 808 * 809 * @param <A> the allele type 810 * @param out the target output stream 811 * @param data the chromosome to write 812 * @param indent the XML level indentation 813 * @param alleleWriter the allele writer of the permutation chromosome 814 * @throws XMLStreamException if an error occurs while writing the 815 * chromosome 816 * @throws NullPointerException if the {@code chromosome} or output 817 * stream is {@code null} 818 */ 819 public static <A> void write( 820 final OutputStream out, 821 final io.jenetics.PermutationChromosome<A> data, 822 final String indent, 823 final Writer<? super A> alleleWriter 824 ) 825 throws XMLStreamException 826 { 827 requireNonNull(data); 828 requireNonNull(alleleWriter); 829 requireNonNull(out); 830 831 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 832 PermutationChromosome.<A>writer(alleleWriter) 833 .write(xml, data); 834 } 835 } 836 837 /** 838 * Write the given {@link io.jenetics.PermutationChromosome} to the 839 * given output stream. 840 * 841 * @param <A> the allele type 842 * @param out the target output stream 843 * @param data the chromosome to write 844 * @throws XMLStreamException if an error occurs while writing the 845 * chromosome 846 * @throws NullPointerException if the {@code chromosome} or output 847 * stream is {@code null} 848 */ 849 public static <A> void write( 850 final OutputStream out, 851 final io.jenetics.PermutationChromosome<A> data 852 ) 853 throws XMLStreamException 854 { 855 write(out, data, null, text()); 856 } 857 858 /** 859 * Write the given {@link io.jenetics.PermutationChromosome} to the 860 * given output stream. 861 * 862 * @param <A> the allele type 863 * @param out the target output stream 864 * @param data the chromosome to write 865 * @param alleleWriter the allele writer used to write the chromosome 866 * alleles 867 * @throws XMLStreamException if an error occurs while writing the 868 * chromosome 869 * @throws NullPointerException if the {@code chromosome} or output 870 * stream is {@code null} 871 */ 872 public static <A> void write( 873 final OutputStream out, 874 final io.jenetics.PermutationChromosome<A> data, 875 final Writer<? super A> alleleWriter 876 ) 877 throws XMLStreamException 878 { 879 write(out, data, null, alleleWriter); 880 } 881 882 } 883 884 /** 885 * This class contains static writer methods for 886 * {@link io.jenetics.Genotype} objects. 887 * <p> 888 * <b>Writer code</b> 889 * <pre>{@code 890 * final Genotype<DoubleGene> gt = Genotype.of( 891 * DoubleChromosome.of(0.0, 1.0, 3), 892 * DoubleChromosome.of(0.0, 1.0, 2) 893 * ); 894 * final Writer<Genotype<DoubleGene>> writer = 895 * Writers.Genotype.writer(Writers.DoubleChromosome.writer()); 896 * 897 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 898 * writer.write(value, xml); 899 * } 900 * }</pre> 901 * 902 * <b>XML output</b> 903 * <pre> {@code 904 * <genotype length="2" ngenes="5"> 905 * <double-chromosome length="3"> 906 * <min>0.0</min> 907 * <max>1.0</max> 908 * <alleles> 909 * <allele>0.27251556008507416</allele> 910 * <allele>0.003140816229067145</allele> 911 * <allele>0.43947528327497376</allele> 912 * </alleles> 913 * </double-chromosome> 914 * <double-chromosome length="2"> 915 * <min>0.0</min> 916 * <max>1.0</max> 917 * <alleles> 918 * <allele>0.4026521545744768</allele> 919 * <allele>0.36137605952663554</allele> 920 * <alleles> 921 * </double-chromosome> 922 * </genotype> 923 * }</pre> 924 */ 925 public static final class Genotype { 926 private Genotype() {} 927 928 static final String ROOT_NAME = "genotype"; 929 static final String LENGTH_NAME = "length"; 930 static final String NGENES_NAME = "ngenes"; 931 932 /** 933 * Create a writer for genotypes of arbitrary chromosomes. How to write the 934 * genotypes chromosomes is defined by the given {@link Writer}. 935 * 936 * @param writer the chromosome writer 937 * @param <A> the allele type 938 * @param <G> the gene type 939 * @param <C> the chromosome type 940 * @return a new genotype writer 941 * @throws NullPointerException if the given chromosome {@code writer} is 942 * {@code null} 943 */ 944 public static < 945 A, 946 G extends Gene<A, G>, 947 C extends Chromosome<G> 948 > 949 Writer<io.jenetics.Genotype<G>> writer(final Writer<? super C> writer) { 950 return elem( 951 ROOT_NAME, 952 attr(LENGTH_NAME).map(io.jenetics.Genotype<G>::length), 953 attr(NGENES_NAME).map(io.jenetics.Genotype<G>::geneCount), 954 elems(writer).map(gt -> cast(gt.toSeq())) 955 ); 956 } 957 958 @SuppressWarnings("unchecked") 959 private static <A, B> B cast(final A value) { 960 return (B)value; 961 } 962 963 /** 964 * Write the given {@link io.jenetics.Genotype} to the given output 965 * stream. 966 * 967 * @param <A> the allele type 968 * @param <G> the gene type 969 * @param <C> the chromosome type 970 * @param out the target output stream 971 * @param data the genotype to write 972 * @param indent the XML level indentation 973 * @param chromosomeWriter the chromosome writer used to write the 974 * genotypes 975 * @throws XMLStreamException if an error occurs while writing the 976 * chromosome 977 * @throws NullPointerException if the one of the arguments is 978 * {@code null} 979 */ 980 public static < 981 A, 982 G extends Gene<A, G>, 983 C extends Chromosome<G> 984 > 985 void write( 986 final OutputStream out, 987 final io.jenetics.Genotype<G> data, 988 final String indent, 989 final Writer<? super C> chromosomeWriter 990 ) 991 throws XMLStreamException 992 { 993 requireNonNull(data); 994 requireNonNull(chromosomeWriter); 995 requireNonNull(out); 996 997 try (AutoCloseableXMLStreamWriter writer = XML.writer(out, indent)) { 998 Genotype.<A, G, C>writer(chromosomeWriter).write(writer, data); 999 } 1000 } 1001 1002 /** 1003 * Write the given {@link io.jenetics.Genotype} to the given output 1004 * stream. 1005 * 1006 * @param <A> the allele type 1007 * @param <G> the gene type 1008 * @param <C> the chromosome type 1009 * @param out the target output stream 1010 * @param data the genotype to write 1011 * @param chromosomeWriter the chromosome writer used to write the 1012 * genotypes 1013 * @throws XMLStreamException if an error occurs while writing the 1014 * chromosome 1015 * @throws NullPointerException if the one of the arguments is 1016 * {@code null} 1017 */ 1018 public static < 1019 A, 1020 G extends Gene<A, G>, 1021 C extends Chromosome<G> 1022 > 1023 void write( 1024 final OutputStream out, 1025 final io.jenetics.Genotype<G> data, 1026 final Writer<? super C> chromosomeWriter 1027 ) 1028 throws XMLStreamException 1029 { 1030 requireNonNull(data); 1031 requireNonNull(chromosomeWriter); 1032 requireNonNull(out); 1033 1034 try (AutoCloseableXMLStreamWriter xml = XML.writer(out)) { 1035 Genotype.<A, G, C>writer(chromosomeWriter).write(xml, data); 1036 } 1037 } 1038 1039 } 1040 1041 /** 1042 * This class contains static writer methods for 1043 * {@link io.jenetics.Genotype} objects. 1044 * <p> 1045 * <b>Writer code</b> 1046 * <pre>{@code 1047 * final Genotype<DoubleGene> gt = Genotype.of( 1048 * DoubleChromosome.of(0.0, 1.0, 3), 1049 * DoubleChromosome.of(0.0, 1.0, 2) 1050 * ); 1051 * 1052 * final Writer<Collection<Genotype<DoubleGene>>> writer = 1053 * Writers.Genotypes.writer(Writers.DoubleChromosome.writer()); 1054 * 1055 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) { 1056 * writer.write(asList(value), xml); 1057 * } 1058 * }</pre> 1059 * 1060 * <pre> {@code 1061 * <genotypes length="1"> 1062 * <genotype length="2" ngenes="5"> 1063 * <double-chromosome length="3"> 1064 * <min>0.0</min> 1065 * <max>1.0</max> 1066 * <alleles> 1067 * <allele>0.27251556008507416</allele> 1068 * <allele>0.003140816229067145</allele> 1069 * <allele>0.43947528327497376</allele> 1070 * </alleles> 1071 * </double-chromosome> 1072 * <double-chromosome length="2"> 1073 * <min>0.0</min> 1074 * <max>1.0</max> 1075 * <alleles> 1076 * <allele>0.4026521545744768</allele> 1077 * <allele>0.36137605952663554</allele> 1078 * <alleles> 1079 * </double-chromosome> 1080 * </genotype> 1081 * </genotypes> 1082 * }</pre> 1083 */ 1084 public static final class Genotypes { 1085 private Genotypes() {} 1086 1087 static final String ROOT_NAME = "genotypes"; 1088 static final String LENGTH_NAME = "length"; 1089 1090 /** 1091 * Create a writer for genotypes of arbitrary chromosomes. How to write the 1092 * genotypes chromosomes is defined by the given {@link Writer}. The 1093 * following writer allows to write double-gene chromosomes: 1094 * <pre>{@code 1095 * final Writer<Collection<Genotype<DoubleGene>>> writer = 1096 * Writers.Genotypes.writer(Writers.DoubleChromosome.writer()); 1097 * }</pre> 1098 * 1099 * @param writer the chromosome writer 1100 * @param <A> the allele type 1101 * @param <G> the gene type 1102 * @param <C> the chromosome type 1103 * @return a new genotype writer 1104 * @throws NullPointerException if the given chromosome {@code writer} is 1105 * {@code null} 1106 */ 1107 public static < 1108 A, 1109 G extends Gene<A, G>, 1110 C extends Chromosome<G> 1111 > 1112 Writer<Collection<io.jenetics.Genotype<G>>> 1113 writer(final Writer<? super C> writer) { 1114 return elem( 1115 ROOT_NAME, 1116 attr(LENGTH_NAME).map(Collection::size), 1117 elems(Genotype.writer(writer)) 1118 ); 1119 } 1120 1121 /** 1122 * Write the given {@link io.jenetics.Genotype} to the given output 1123 * stream. 1124 * 1125 * @param <A> the allele type 1126 * @param <G> the gene type 1127 * @param <C> the chromosome type 1128 * @param out the target output stream 1129 * @param data the genotypes to write 1130 * @param indent the XML level indentation 1131 * @param chromosomeWriter the chromosome writer used to write the 1132 * genotypes 1133 * @throws XMLStreamException if an error occurs while writing the 1134 * chromosome 1135 * @throws NullPointerException if the one of the arguments is 1136 * {@code null} 1137 */ 1138 public static < 1139 A, 1140 G extends Gene<A, G>, 1141 C extends Chromosome<G> 1142 > 1143 void write( 1144 final OutputStream out, 1145 final Collection<io.jenetics.Genotype<G>> data, 1146 final String indent, 1147 final Writer<? super C> chromosomeWriter 1148 ) 1149 throws XMLStreamException 1150 { 1151 requireNonNull(data); 1152 requireNonNull(chromosomeWriter); 1153 requireNonNull(out); 1154 1155 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) { 1156 Genotypes.<A, G, C>writer(chromosomeWriter).write(xml, data); 1157 } 1158 } 1159 1160 /** 1161 * Write the given {@link io.jenetics.Genotype} to the given output 1162 * stream. 1163 * 1164 * @param <A> the allele type 1165 * @param <G> the gene type 1166 * @param <C> the chromosome type 1167 * @param out the target output stream 1168 * @param data the genotypes to write 1169 * @param chromosomeWriter the chromosome writer used to write the 1170 * genotypes 1171 * @throws XMLStreamException if an error occurs while writing the 1172 * chromosome 1173 * @throws NullPointerException if the one of the arguments is 1174 * {@code null} 1175 */ 1176 public static < 1177 A, 1178 G extends Gene<A, G>, 1179 C extends Chromosome<G> 1180 > 1181 void write( 1182 final OutputStream out, 1183 final Collection<io.jenetics.Genotype<G>> data, 1184 final Writer<? super C> chromosomeWriter 1185 ) 1186 throws XMLStreamException 1187 { 1188 requireNonNull(data); 1189 requireNonNull(chromosomeWriter); 1190 requireNonNull(out); 1191 1192 try (AutoCloseableXMLStreamWriter xml = XML.writer(out)) { 1193 Genotypes.<A, G, C>writer(chromosomeWriter).write(xml, data); 1194 } 1195 } 1196 1197 } 1198 1199 1200 /** 1201 * Write the given {@link io.jenetics.Genotype} to the given output 1202 * stream. 1203 * 1204 * @see Genotypes#write(OutputStream, Collection, Writer) 1205 * 1206 * @param <A> the allele type 1207 * @param <G> the gene type 1208 * @param <C> the chromosome type 1209 * @param out the target output stream 1210 * @param data the genotypes to write 1211 * @param chromosomeWriter the chromosome writer used to write the 1212 * genotypes 1213 * @throws XMLStreamException if an error occurs while writing the 1214 * chromosome 1215 * @throws NullPointerException if the one of the arguments is 1216 * {@code null} 1217 */ 1218 public static < 1219 A, 1220 G extends Gene<A, G>, 1221 C extends Chromosome<G> 1222 > 1223 void write( 1224 final OutputStream out, 1225 final Collection<io.jenetics.Genotype<G>> data, 1226 final Writer<? super C> chromosomeWriter 1227 ) 1228 throws XMLStreamException 1229 { 1230 Genotypes.write(out, data, chromosomeWriter); 1231 } 1232 1233}