
    h$S                       S SK Jr  S SKJrJrJrJrJr  S SKrS SK	r	S SK
Jr  S SKrS SKrS SKr " S S\R                  5      rS;S jr " S S	\R                  5      r " S
 S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\R                  5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      rS<S jrS<S jrS<S  jr " S! S"\5      r  " S# S$\5      r! " S% S&\5      r" " S' S(\5      r# " S) S*\R                  5      r$ " S+ S,\R                  5      r% " S- S.5      r& " S/ S05      r'        S=S1 jr( " S2 S35      r)S>S4 jr* " S5 S6\$5      r+ " S7 S8\+5      r, " S9 S:\$5      r-g)?    )annotations)SequenceIterableOptionalCallableUnionN)	dataclassc                      \ rS rSr% SrSrS\S'   S\S'   \R                  SS j5       r	\
\R                  SS	 j5       5       rS
 rS rS rS rS rS rS rS r\R                  SS j5       rSrg)DNA   zAbstract DNA class.NzOptional[float]fitnesslist_datac                    g N selfvaluess     P/var/www/html/env/lib/python3.13/site-packages/ezdxf/addons/genetic_algorithm.pyreset	DNA.reset           c                    g r   r   r   s    r   is_validDNA.is_valid!   s     	r   c                .    [         R                  " U 5      $ r   )copydeepcopyr   s    r   r    DNA.copy&   s    }}T""r   c                    S U l         g r   r   r   s    r   _taint
DNA._taint)   s	    r   c                `    U R                   R                   S[        U R                  5       S3$ )N())	__class____name__strr   r   s    r   __repr__DNA.__repr__,   s)    ..))*!C

O+<A>>r   c                l    [        XR                  5      (       d   eU R                  UR                  :H  $ r   )
isinstancer*   r   )r   others     r   __eq__
DNA.__eq__/   s*    %0000zzU[[((r   c                ,    [        U R                  5      $ r   )lenr   r   s    r   __len__DNA.__len__3   s    4::r   c                8    U R                   R                  U5      $ r   )r   __getitem__)r   items     r   r9   DNA.__getitem__6   s    zz%%d++r   c                Z    U R                   R                  X5        U R                  5         g r   )r   __setitem__r%   )r   keyvalues      r   r=   DNA.__setitem__9   s    

s*r   c                ,    [        U R                  5      $ r   )iterr   r   s    r   __iter__DNA.__iter__=   s    DJJr   c                    g r   r   r   indexs     r   flip_mutate_atDNA.flip_mutate_at@   r   r   r$   r   r   returnboolrG   intrL   None)r+   
__module____qualname____firstlineno____doc__r   __annotations__abcabstractmethodr   propertyr   r    r%   r-   r2   r6   r9   r=   rC   rH   __static_attributes__r   r   r   r   r      s    #G_#K    #?),  	 r   r   c                    U R                   $ r   r$   )dnas    r   dna_fitnessr\   E   s    ;;r   c                  @    \ rS rSrSr\R                  SS j5       rSrg)MutateI   zAbstract mutation.c                    g r   r   )r   r[   rates      r   mutateMutate.mutateL   r   r   r   Nr[   r   ra   float)	r+   rQ   rR   rS   rT   rV   rW   rb   rY   r   r   r   r^   r^   I   s     r   r^   c                  "    \ rS rSrSrSS jrSrg)
FlipMutateQ   zFlip one bit mutation.c                    [        [        U5      5       H/  n[        R                  " 5       U:  d  M  UR                  U5        M1     g r   )ranger5   randomrH   )r   r[   ra   rG   s       r   rb   FlipMutate.mutateT   s0    3s8_E}}%""5) %r   r   Nrd   r+   rQ   rR   rS   rT   rb   rY   r   r   r   rg   rg   Q   s
     *r   rg   c                  "    \ rS rSrSrSS jrSrg)NeighborSwapMutateZ   zSwap two neighbors mutation.c                    [        [        U5      5       H1  n[        R                  " 5       U:  d  M  US-
  nX   nX   X'   XQU'   M3     g N   rj   r5   rk   )r   r[   ra   rG   i2tmps         r   rb   NeighborSwapMutate.mutate]   sB    3s8_E}}%QYg* E
 %r   r   Nrd   rm   r   r   r   ro   ro   Z   s
    &!r   ro   c                  "    \ rS rSrSrSS jrSrg)RandomSwapMutatef   z Swap two random places mutation.c                    [        U5      n[        U5       HM  n[        R                  " 5       U:  d  M  [        R                  " SU5      nXT:X  a  US-  nX   nX   X'   XaU'   MO     g )Nr   rs   )r5   rj   rk   	randrange)r   r[   ra   lengthrG   ru   rv   s          r   rb   RandomSwapMutate.mutatei   s^    S6]E}}%%%a0;!GBg* E
 #r   r   Nrd   rm   r   r   r   ry   ry   f   s
    *	!r   ry   c                  0    \ rS rSrSrSSS jjrS	S jrSrg)
ReverseMutateu   z'Reverse some consecutive bits mutation.c                8    [        [        US5      5      U l        g rr   rO   max_bitsr   bitss     r   __init__ReverseMutate.__init__x       T1&
r   c                    [        U5      n[        R                  " 5       UX0R                  -  -  :  aB  [        R                  " X0R                  -
  5      nX@R                  -   nXU n[	        U5      XU& g g r   )r5   rk   r   r|   reversedr   r[   ra   r}   i1ru   r   s          r   rb   ReverseMutate.mutate{   si    S==?TZZ
 
 !!&::"56BjjB":D!$C2J
r   r   N   r   rO   rd   r+   rQ   rR   rS   rT   r   rb   rY   r   r   r   r   r   u   s    1'(r   r   c                  0    \ rS rSrSrSSS jjrS	S jrSrg)
ScrambleMutate   z(Scramble some consecutive bits mutation.c                8    [        [        US5      5      U l        g rr   r   r   s     r   r   ScrambleMutate.__init__   r   r   c                   [        U5      n[        R                  " 5       UX0R                  -  -  :  aN  [        R                  " X0R                  -
  5      nX@R                  -   nXU n[        R                  " U5        XaXE& g g r   )r5   rk   r   r|   shuffler   s          r   rb   ScrambleMutate.mutate   so    S==?TZZ
 
 !!&::"56BjjB":DNN4 J
r   r   Nr   r   rd   r   r   r   r   r   r      s    2'	r   r   c                  @    \ rS rSrSr\R                  SS j5       rSrg)Mate   zAbstract recombination.c                    g r   r   r   dna1dna2s      r   	recombineMate.recombine   s    r   r   Nr   r   r   r   )	r+   rQ   rR   rS   rT   rV   rW   r   rY   r   r   r   r   r      s    ! r   r   c                  "    \ rS rSrSrSS jrSrg)Mate1pCX   z"One point crossover recombination.c                `    [        U5      n[        R                  " SU5      n[        XXC5        g Nr   r5   rk   r|   recombine_dna_2pcx)r   r   r   r}   rG   s        r   r   Mate1pCX.recombine   s'    T  F+4u5r   r   Nr   r+   rQ   rR   rS   rT   r   rY   r   r   r   r   r      s
    ,6r   r   c                  "    \ rS rSrSrSS jrSrg)Mate2pCX   z"Two point crossover recombination.c                    [        U5      n[        R                  " SU5      n[        R                  " SU5      nXE:  a  XTpT[        XXE5        g r   r   r   r   r   r}   r   ru   s         r   r   Mate2pCX.recombine   C    Ta(a(74r.r   r   Nr   r   r   r   r   r   r      s
    ,/r   r   c                  "    \ rS rSrSrSS jrSrg)MateUniformCX   zUniform recombination.c                    [        [        U5      5       H,  n[        R                  " 5       S:  d  M  X   nX#   X'   XBU'   M.     g )Ng      ?rt   )r   r   r   rG   rv   s        r   r   MateUniformCX.recombine   s:    3t9%E}}$k"k!U	 &r   r   Nr   r   r   r   r   r   r      s
     "r   r   c                  "    \ rS rSrSrSS jrSrg)MateOrderedCX   z8Recombination class for ordered DNA like UniqueIntDNA().c                    [        U5      n[        R                  " SU5      n[        R                  " SU5      nXE:  a  XTpT[        XXE5        g r   )r5   rk   r|   recombine_dna_ocx1r   s         r   r   MateOrderedCX.recombine   r   r   r   Nr   r   r   r   r   r   r      s
    B/r   r   c                     XU nXU nXPX#& XAX#& g)zTwo point crossover.Nr   )r   r   r   ru   part1part2s         r   r   r      s"    BKEBKEKKr   c                T    U R                  5       n[        XX#5        [        XX#5        g)zOrdered crossover.N)r    replace_dna_ocx1)r   r   r   ru   copy1s        r   r   r      s!    IIKET(T")r   c                    U R                  5       nXU nXPX#& Sn[        U5      nU H  nX;   a  M
  Xb:X  a  UnXU'   US-  nM     g)zOReplace a part in dna1 by dna2 and preserve order of remaining values in
dna1.
r   rs   N)r    set)	r   r   r   ru   oldnewrG   new_setr?   s	            r   r   r      sZ     ))+C
"+CKE#hG;EU
 r   c                      \ rS rSrSrSrSS jr\SS j5       r\SS j5       r	\
SS j5       rS rS	 rSS
 jrSS jrSrg)FloatDNA   z,Arbitrary float numbers in the range [0, 1].r   r   c                R    [        U5      U l        U R                  5         S U l        g r   )r   r   _check_valid_datar   r   s     r   r   FloatDNA.__init__   s     "&v,
 (,r   c                2    U " S [        U5       5       5      $ )Nc              3  L   #    U  H  n[         R                   " 5       v   M     g 7fr   )rk   .0_s     r   	<genexpr>"FloatDNA.random.<locals>.<genexpr>   s     ;]FMMOO]   "$rj   clsr}   s     r   rk   FloatDNA.random   s    ;U6];<<r   c                `    [        U5       Vs/ s H  o0R                  U5      PM     sn$ s  snf r   rj   rk   r   nr}   r   s       r   n_randomFloatDNA.n_random   %    ,1!H5Hq

6"H555   +c                :    [        S U R                   5       5      $ )Nc              3  L   #    U  H  nS Us=:*  =(       a    S:*  Os  v   M     g7f              ?Nr   r   vs     r   r   $FloatDNA.is_valid.<locals>.<genexpr>  s     7Jq3!??s??Jr   allr   r   s    r   r   FloatDNA.is_valid   s    7DJJ777r   c                <    U R                   (       d  [        S5      eg )Nzdata value out of range)r   
ValueErrorr   s    r   r   FloatDNA._check_valid_data  s    }}677 r   c           	         U R                   c  SnOSU R                   S 3n[        U R                   Vs/ s H  n[        US5      PM     sn5       U 3$ s  snf )N, fitness=None
, fitness=.4f   )r   r,   r   roundr   r   r   s      r   __str__FloatDNA.__str__  sU    <<&G"4<<"45GDJJ7JquQ{J789'CC7s   Ac                d    [        U5      U l        U R                  5         U R                  5         g r   )r   r   r   r%   r   s     r   r   FloatDNA.reset  s"    &\
 r   c                B    SU R                   U   -
  U R                   U'   g Nr   r   rF   s     r   rH   FloatDNA.flip_mutate_at  s    $**U"33

5r   N)r   Iterable[float])r}   rO   rL   r   )r   rO   r}   rO   rL   zlist[FloatDNA]rK   rN   )r+   rQ   rR   rS   rT   	__slots__r   classmethodrk   r   rX   r   r   r   r   rH   rY   r   r   r   r   r      s`    6$I-
 = = 6 6 8 88D
4r   r   c                  |    \ rS rSrSrSrSS jr\SS j5       r\	SS j5       r
\	SS j5       rS rSS	 jrSS
 jrSrg)BitDNAi  zOne bit DNA.r   c                @    [        S U 5       5      U l        S U l        g )Nc              3  8   #    U  H  n[        U5      v   M     g 7fr   rM   r   s     r   r   "BitDNA.__init__.<locals>.<genexpr>  s     %>v!d1ggv   )r   r   r   r   s     r   r   BitDNA.__init__  s    !%%>v%>!>
(,r   c                    g)NTr   r   s    r   r   BitDNA.is_valid   s    r   c                2    U " S [        U5       5       5      $ )Nc              3  b   #    U  H%  n[        [        R                  " S S5      5      v   M'     g7f)r   rs   N)rM   rk   randintr   s     r   r    BitDNA.random.<locals>.<genexpr>&  s#     E}!4q!,--}s   -/r   r   s     r   rk   BitDNA.random$  s    EuV}EEEr   c                `    [        U5       Vs/ s H  o0R                  U5      PM     sn$ s  snf r   r   r   s       r   r   BitDNA.n_random(  r   r   c                    U R                   c  SnOSU R                   S 3n[        U R                   Vs/ s H  n[        U5      PM     sn5       U 3$ s  snf Nr   r   r   r   r,   r   rO   r   s      r   r   BitDNA.__str__,  S    <<&G"4<<"45Gtzz2z!s1vz234WI>>2   Ac                R    [        S U 5       5      U l        U R                  5         g )Nc              3  8   #    U  H  n[        U5      v   M     g 7fr   r  r   s     r   r   BitDNA.reset.<locals>.<genexpr>4  s     26a$q''6r  r   r   r%   r   s     r   r   BitDNA.reset3  s    2622
r   c                F    U R                   U   (       + U R                   U'   g r   r  rF   s     r   rH   BitDNA.flip_mutate_at7  s     $

5 11

5r   NrJ   rK   )r}   rO   rL   r	  )r   rO   r}   rO   rL   zlist[BitDNA]r   r   rL   rP   rN   )r+   rQ   rR   rS   rT   r  r   rX   r   r  rk   r   r   r   rH   rY   r   r   r   r	  r	    s\    $I-   F F 6 6?2r   r	  c                  |    \ rS rSrSrSrSS jr\SS j5       r\SS j5       r	\
SS j5       rS rSS	 jrSS
 jrSrg)UniqueIntDNAi;  a=  Unique integer values in the range from 0 to length-1.
E.g. UniqueIntDNA(10) = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Requires MateOrderedCX() as recombination class to preserve order and
validity after DNA recombination.

Requires mutation by swapping like SwapRandom(), SwapNeighbors(),
ReversMutate() or ScrambleMutate()
r   c                   U   [        U[        5      (       a  [        [        U5      5      U l        OGU Vs/ s H  n[        U5      PM     snU l        U R
                  (       d  [        U R                  5      eS U l        g s  snf r   )r0   rO   r   rj   r   r   	TypeErrorr   )r   r   r   s      r   r   UniqueIntDNA.__init__H  s^    fc""eFm,DJ*01&Q#a&&1DJ==

++(, 2s   Bc                V    U " U5      n[         R                  " UR                  5        U$ r   )rk   r   r   )r   r}   r[   s      r   rk   UniqueIntDNA.randomR  s     &ksyy!
r   c                `    [        U5       Vs/ s H  o0R                  U5      PM     sn$ s  snf r   r   r   s       r   r   UniqueIntDNA.n_randomX  r   r   c                j    [        [        U R                  5      5      [        U R                  5      :H  $ r   )r5   r   r   r   s    r   r   UniqueIntDNA.is_valid\  s"    3tzz?#s4::66r   c                    U R                   c  SnOSU R                   S 3n[        U R                   Vs/ s H  n[        U5      PM     sn5       U 3$ s  snf r  r  r   s      r   r   UniqueIntDNA.__str__`  r  r  c                R    [        S U 5       5      U l        U R                  5         g )Nc              3  8   #    U  H  n[        U5      v   M     g 7fr   rO   r   s     r   r   %UniqueIntDNA.reset.<locals>.<genexpr>h       1&Q#a&&&r  r"  r   s     r   r   UniqueIntDNA.resetg      1&11
r   c                    [        S5      e)Nzflip mutation not supported)r*  rF   s     r   rH   UniqueIntDNA.flip_mutate_atk  s    566r   N)r   zUnion[int, Iterable])r}   rO   rL   r(  )r   rO   r}   rO   rL   zlist[UniqueIntDNA]rK   r&  rN   )r+   rQ   rR   rS   rT   r  r   r  rk   r   rX   r   r   r   rH   rY   r   r   r   r(  r(  ;  s^     %I-  
 6 6 7 7?7r   r(  c                      \ rS rSrSrSrSS jr\SS j5       r\SS j5       r	\
SS j5       rS rS	 rSS
 jrSS jrSrg)
IntegerDNAio  zcInteger values in the range from 0 to max_ - 1.
E.g. IntegerDNA([0, 1, 2, 3, 4, 0, 1, 2, 3, 4], 5)
r   c                    [        U5      U l        [        U5      U l        U R                  (       d  [        U R                  5      eS U l        g r   )rO   _maxr   r   r   r*  r   )r   r   max_s      r   r   IntegerDNA.__init__v  s5    I	 $V
}}DJJ''(,r   c                R   ^ [        U5      mU " U4S j[        U5       5       T5      $ )Nc              3  R   >#    U  H  n[         R                  " S T5      v   M     g7fr   N)rk   r|   )r   r   imaxs     r   r   $IntegerDNA.random.<locals>.<genexpr>  s!     E}!F$$Q--}s   $')rO   rj   )r   r}   rA  rF  s      @r   rk   IntegerDNA.random}  s#    4yEuV}EtLLr   c                `    [        U5       Vs/ s H  o@R                  X#5      PM     sn$ s  snf r   r   )r   r   r}   rA  r   s        r   r   IntegerDNA.n_random  s%    27(;(Q

6((;;;r   c                B   ^  [        U 4S jT R                   5       5      $ )Nc              3  b   >#    U  H$  nS Us=:*  =(       a    TR                   :  Os  v   M&     g7frE  )r@  )r   r   r   s     r   r   &IntegerDNA.is_valid.<locals>.<genexpr>  s%     :z!1%%DII%%zs   ,/r   r   s   `r   r   IntegerDNA.is_valid  s    :tzz:::r   c                z    U R                   R                   S[        U R                  5       SU R                   S3$ )Nr(   z, r)   )r*   r+   r,   r   r@  r   s    r   r-   IntegerDNA.__repr__  s3    ..))*!C

O+<BtyykKKr   c                    U R                   c  SnOSU R                   S 3n[        U R                   Vs/ s H  n[        U5      PM     sn5       U 3$ s  snf r  r  r   s      r   r   IntegerDNA.__str__  r  r  c                R    [        S U 5       5      U l        U R                  5         g )Nc              3  8   #    U  H  n[        U5      v   M     g 7fr   r6  r   s     r   r   #IntegerDNA.reset.<locals>.<genexpr>  r8  r  r"  r   s     r   r   IntegerDNA.reset  r:  r   c                \    U R                   U R                  U   -
  S-
  U R                  U'   g rr   )r@  r   rF   s     r   rH   IntegerDNA.flip_mutate_at  s'     II

5(99A=

5r   )r   r@  r   N)r   zIterable[int]rA  rO   )r}   rO   rA  rO   rL   r>  )r   rO   r}   rO   rA  rO   rL   zlist[IntegerDNA]rK   r&  rN   )r+   rQ   rR   rS   rT   r  r   r  rk   r   rX   r   r-   r   r   rH   rY   r   r   r   r>  r>  o  sf     %I- M M < < ; ;L?>r   r>  c                  h    \ rS rSrSr\R                  SS j5       r\R                  SS j5       rSr	g)		Selectioni  zAbstract selection class.c                    g r   r   r   counts     r   pickSelection.pick  r   r   c                    g r   r   r   
candidatess     r   r   Selection.reset  r   r   r   Nr]  rO   rL   Iterable[DNA]rb  re  )
r+   rQ   rR   rS   rT   rV   rW   r^  r   rY   r   r   r   rZ  rZ    s7    #  	 r   rZ  c                  @    \ rS rSrSr\R                  SS j5       rSrg)	Evaluatori  zAbstract evaluation class.c                    g r   r   r   r[   s     r   evaluateEvaluator.evaluate  r   r   r   Nr[   r   rL   re   )	r+   rQ   rR   rS   rT   rV   rW   rk  rY   r   r   r   rh  rh    s    $ r   rh  c                  d    \ rS rSr\ " S S5      5       rS
S jrSS jrSS jr\	SS j5       r
Srg	)Logi  c                  4    \ rS rSr% S\S'   S\S'   S\S'   Srg)	Log.Entryi  re   runtimer   avg_fitnessr   N)r+   rQ   rR   rS   rU   rY   r   r   r   Entryrq    s    r   rt  c                    / U l         g r   entriesr   s    r   r   Log.__init__  s	    (*r   c                b    U R                   R                  [        R                  XU5      5        g r   )rw  appendro  rt  )r   rr  r   rs  s       r   addLog.add  s    CIIgDEr   c                    U R                    Vs/ s H%  o"R                  UR                  UR                  4PM'     nn[	        US5       n[
        R                  " X4SS9  S S S 5        g s  snf ! , (       d  f       g = f)Nwtr   )indent)rw  rr  r   rs  openjsondump)r   filenameedatafps        r   r  Log.dump  sZ    ?C||L|!AIIq}}5|L(D!RIIdq) "! M!!s   ,A(	A--
A;c                    [        US5       n[        R                  " U5      nS S S 5        [        5       nW H  u  pVnUR	                  XVU5        M     U$ ! , (       d  f       N8= f)Nrt)r  r  loadro  r{  )r   r  r  r  logrr  r   rs  s           r   r  Log.load  sR    (D!R99R=D "e-1)GkGGGk2 .2
 "!s   A
A$rv  NrL   rP   )rr  re   r   re   rs  re   rL   rP   )r  r,   rL   rP   )r  r,   rL   ro  )r+   rQ   rR   rS   r	   rt  r   r{  r  r  r  rY   r   r   r   ro  ro    s=      
+F*
  r   ro  c                  @    \ rS rSrS rS rS rS
S jrSS jrS r	Sr
g	)
HallOfFamei  c                .    Xl         [        5       U l        g r   )r]  dict_unique_entriesr\  s     r   r   HallOfFame.__init__  s    
#vr   c                R   ^  U 4S jT R                  5       S T R                    5       $ )Nc              3  B   >#    U  H  nTR                   U   v   M     g 7fr   )r  )r   kr   s     r   r   &HallOfFame.__iter__.<locals>.<genexpr>  s       
-ND  #-Ns   )_sorted_keysr]  r   s   `r   rC   HallOfFame.__iter__  s)    
-1->->-@4::-N
 	
r   c                F    [        U R                  R                  5       SS9$ )NT)reverse)sortedr  keysr   s    r   r  HallOfFame._sorted_keys  s    d**//14@@r   c                R    UR                   c   eXR                  UR                   '   g r   )r   r  rj  s     r   r{  HallOfFame.add  s$    {{&&&,/S[[)r   c                    U R                   nU R                  5       nUS [        XR                  5        Vs/ s H  oBU   PM	     sn$ s  snf r   )r  r  minr]  )r   r]  rw  r  r  s        r   getHallOfFame.get  sH    &&  "$()A3ujj+A$BC$Bq
$BCCCs   Ac                    [        U R                  5      U R                  ::  a  g U R                  nU R                  5       nUS U R                    Vs0 s H  o3X   _M	     snU l        g s  snf r   )r5   r  r]  r  )r   rw  r  r  s       r   purgeHallOfFame.purge  s`    t##$

2&&  "7;Ldjj7IJ7I!7:7IJJs   A))r  r]  N)r[   r   )r]  rO   rL   z	list[DNA])r+   rQ   rR   rS   r   rC   r  r{  r  r  rY   r   r   r   r  r    s#    &

A0D
Kr   r  c                r   ^ US::  a!  [        U [        S9nSU-
  UR                  -  mOX-  mU4S jU  5       $ )Nr   r>   r   c              3  J   >#    U  H  oR                   T:  d  M  Uv   M     g 7fr   r$   )r   c	min_values     r   r   #threshold_filter.<locals>.<genexpr>  s     ;z!YY%:AAzs   #	#)r  r\   r   )rb  best_fitness	thresholdminimumr  s       @r   threshold_filterr    s>     sjk29_7	 ,	;z;;r   c                      \ rS rSrSr S     SS jjrSS jr\SS j5       r\SS j5       r	SS jr
  S     SS	 jjrSS
 jrSS jrSS jrSS jrSS jrSrg)GeneticOptimizeri  a  A genetic algorithm (GA) is a meta-heuristic inspired by the process of
natural selection. Genetic algorithms are commonly used to generate
high-quality solutions to optimization and search problems by relying on
biologically inspired operators such as mutation, crossover and selection.

Source: https://en.wikipedia.org/wiki/Genetic_algorithm

This implementation searches always for the maximum fitness, fitness
comparisons are always done by the "greater than" operator (">").
The algorithm supports negative values to search for the minimum fitness
(e.g. Travelling Salesmen Problem: -900 > -1000). Reset the start fitness
by the method :meth:`reset_fitness` accordingly::

    optimizer.reset_fitness(-1e99)

c                   US:  a  [        S5      eSU l        [        5       U l        / U l        Xl        [        5       U l        [        5       U l	        [        5       U l        [        U5      U l        [        U5      U l        SU l        SU l        SU l        SU l        SU l        S	U l        S
U l        S	U l        S	U l        [3        / 5      U l        S	U l        S
U l        [;        S5      U l        g )Nrs   zrequires max_generations > 0r  g.B}Td   gffffff?g{Gz?   r   r   
   )r   namero  r  rb  	evaluatorRouletteSelection	selectionr   materg   mutationrO   max_generationsre   max_fitnessmax_runtimemax_stagnationcrossover_ratemutation_rateelitismr  
generation
start_timerr  r	  best_dnar  
stagnationr  hall_of_fame)r   r  r  r  s       r   r   GeneticOptimizer.__init__  s     Q;<<&	5%' %.$5$7"*	"  #?3"'"4"&!"! !$  !!#BZ#& &rNr   c                $    [        U5      U l        g r   )re   r  )r   r?   s     r   reset_fitnessGeneticOptimizer.reset_fitness/  s    !%Lr   c                ,    [        U R                  5      $ r   )rM   r  r   s    r   is_executedGeneticOptimizer.is_executed2  s    DOO$$r   c                ,    [        U R                  5      $ r   )r5   rb  r   s    r   r]  GeneticOptimizer.count6  s    4??##r   c                r    U R                   (       d  U R                  R                  U5        g [        S5      e)Nzalready executed)r  rb  extendr*  rj  s     r   add_candidatesGeneticOptimizer.add_candidates:  s)    OO""3'.//r   Nc                d   U R                   (       a  [        S5      eU R                  (       d  [        S5        [        R
                  " 5       nX0l        [        SU R                  S-   5       H  U l	        U R                  5         [        R
                  " 5       nX@R                  -
  U l        U R                  U R                  :  d4  U R                  U R                  :  d  U R                  U R                   :  a    g U(       a  XC-
  U:  a  U" U 5      (       a    g UnU R#                  5         M     g )Nzcan only run oncezno DNA defined!rs   )r  r*  rb  printtimeperf_counterr  rj   r  r  measure_fitnessrr  r  r  r  r  r  next_generation)r   feedbackintervalt0t1s        r   executeGeneticOptimizer.execute@  s    
 /00#$ $Q(<(<q(@ADO  """$B/DL!!T%5%55<<4#3#33??d&9&99BGh.D>>  "  Br   c                r   U =R                   S-  sl         SnU R                   H  nUR                  b  XR                  -  nM   U R                  R	                  U5      nX2l        X-  nU R
                  R                  U5        X0R                  :  d  Mq  X0l        X l        SU l         M     U R
                  R                  5          U[        U R                  5      -  nU R                  R                  [        R                  " 5       U R                  -
  U R                  U5        g ! [         a    Sn NVf = f)Nrs   r   r   )r  rb  r   r  rk  r  r{  r  r  r  r5   ZeroDivisionErrorr  r  r  r  )r   fitness_sumr[   r   rs  s        r   r   GeneticOptimizer.measure_fitness[  s   1 ??C{{&{{*nn--c2G!K"K!!#&***$+! #"# # 	!	%DOO(<<K 	$//1	
 ! 	K	s   D' 'D65D6c                `   [        U R                  5      n/ nU R                  nUR                  U R	                  U R                  5      5        U R
                  S:  a4  UR                  U R                  R                  U R
                  5      5        [        U5      U:  a  UR                  S5      u  pEUR                  5       nUR                  5       nU R                  XE5        U R                  XE5        UR                  U5        UR                  U5        [        U5      U:  a  M  X l        g )Nr   r  )r5   rb  r  r   filter_thresholdr  r  r  r  r^  r    r   rb   rz  )r   r]  rb  selectorr   r   s         r   r   GeneticOptimizer.next_generationv  s    DOO$ "
>>t,,T__=><<!d//33DLLAB*o%!q)JD99;D99;DNN4&KK#d#d# *o% %r   c                f    U R                   S:  a   [        XR                  U R                   5      $ U$ )Nr   )r  r  r  ra  s     r   r  !GeneticOptimizer.filter_threshold  s2    >>C#--t~~  r   c                    [         R                   " 5       U R                  :  a  U R                  R                  X5        g g r   )rk   r  r  r   r   s      r   r   GeneticOptimizer.recombine  s-    ==?T000II+ 1r   c                    U R                   R                  XR                  5        U R                   R                  X R                  5        g r   )r  rb   r  r   s      r   rb   GeneticOptimizer.mutate  s2    T#5#56T#5#56r   )r  r  rb  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rr  r  r  r  r  )r   )r  rh  r  rO   r  re   )r?   re   rL   rP   rK   )rL   rO   )r[   re  r  )r  z,Optional[Callable[[GeneticOptimizer], bool]]r  re   rL   rP   r  )rb  Sequence[DNA]rL   re  r   )r+   rQ   rR   rS   rT   r   r  rX   r  r]  r  r  r  r  r  r   rb   rY   r   r   r   r  r    s    * !	&+&+ &+ 	&+P) % % $ $0 BF#># # 
	#6
6%&,7r   r  c                    S U  5       $ )Nc              3  L   #    U  H  oS :X  a  S OS[        U5      -  v   M     g7fr   )abs)r   ws     r   r   (conv_negative_weights.<locals>.<genexpr>  s!     ?w!8Cs1v-wr   r   )weightss    r   conv_negative_weightsr    s    ?w??r   c                  :    \ rS rSrSrSS	S jjrS
S jrSS jrSrg)r  i  zSelection by fitness values.c                @    / U l         / U l        [        U5      U l        g r   )_candidates_weightsrM   _negative_values)r   negative_valuess     r   r   RouletteSelection.__init__  s    &(%' $_ 5r   c                    [        U5      U l        U R                  (       a+  [        [        S U R                   5       5      5      U l        g U R                   Vs/ s H  o"R
                  PM     snU l        g s  snf )Nc              3  8   #    U  H  oR                   v   M     g 7fr   r$   )r   r[   s     r   r   *RouletteSelection.reset.<locals>.<genexpr>  s     %N=Mckk=Mr  )r   r  r  r  r  r   )r   rb  r[   s      r   r   RouletteSelection.reset  s]    
+   %%NT=M=M%NNDM 594D4DE4DS[[4DEDMEs   A9c                V    [         R                  " U R                  U R                  US9$ )N)r  )rk   choicesr  r  r\  s     r   r^  RouletteSelection.pick  s    ~~d..GGr   )r  r  r  N)F)r  rM   rL   rP   rf  rd  	r+   rQ   rR   rS   rT   r   r   r^  rY   r   r   r   r  r    s    &6
FHr   r  c                  "    \ rS rSrSrSS jrSrg)RankBasedSelectioni  zSelection by rank of fitness.c                    [        U5      U l        U R                  R                  [        S9  [        [	        S[        U R                  5      S-   5      5      U l        g )Nr  rs   )r   r  sortr\   rj   r5   r  ra  s     r   r   RankBasedSelection.reset  sK    
++. U1c$*:*:&;a&?@Ar   )r  r  Nrf  )r+   rQ   rR   rS   rT   r   rY   r   r   r   r	  r	    s    'Br   r	  c                  6    \ rS rSrSrSS jrS	S jrS
S jrSrg)TournamentSelectioni  z@Selection by choosing the best of a certain count of candidates.c                    / U l         Xl        g r   r  rb  ra  s     r   r   TournamentSelection.__init__  s    &($r   c                $    [        U5      U l        g r   )r   r  ra  s     r   r   TournamentSelection.reset  s    
+r   c              #     #    [        U5       H`  n[        U R                  5       Vs/ s H#  n[        R                  " U R                  5      PM%     nnUR                  [        S9  US   v   Mb     g s  snf 7f)Nr  )rj   rb  rk   choicer  r  r\   )r   r]  r   r   s       r   r^  TournamentSelection.pick  sg     uA9>t9O9OAd../9O   KKKK(* s   &A8*A3&A8r  N)rb  rO   rf  rd  r  r   r   r   r  r    s    J%,r   r  rm  )
r   r   r   r   r   rO   ru   rO   rL   rP   )rb  r  r  re   r  re   rL   re  )r  r  rL   r  ).
__future__r   typingr   r   r   r   r   rV   r    dataclassesr	   r  rk   r  ABCr   r\   r^   rg   ro   ry   r   r   r   r   r   r   r   r   r   r   r   r	  r(  r>  rZ  rh  ro  r  r  r  r  r  r	  r  r   r   r   <module>r     s   #    !   +#'' +\SWW * *	! 	!!v !(F ("V $377 6t 6	/t 	/"D "	/D 	/*$'4s '4T!2S !2H173 17h*> *>Z	 	  8K K<<<-2<?D<<b7 b7J@
H	 H,	B* 	B) r   