
    Og$S                       d dl mZ d dlmZmZmZmZmZ d dlZd dl	Z	d dl
mZ d dlZd dlZd dlZ G d dej                        Zd;dZ G d d	ej                        Z G d
 de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d dej                        Z G d de      Z G d de      Z G d de      Z G d de      Zd<dZd<dZd<d Z G d! d"e      Z  G d# d$e      Z! G d% d&e      Z" G d' d(e      Z# G d) d*ej                        Z$ G d+ d,ej                        Z% G d- d.      Z& G d/ d0      Z'	 	 	 	 	 	 	 	 d=d1Z( G d2 d3      Z)d>d4Z* G d5 d6e$      Z+ G d7 d8e+      Z, G d9 d:e$      Z-y)?    )annotations)SequenceIterableOptionalCallableUnionN)	dataclassc                      e Zd ZU dZdZded<   ded<   ej                  dd       Ze	ej                  dd              Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zej                  dd       Zy)DNAzAbstract DNA class.NzOptional[float]fitnesslist_datac                     y N selfvaluess     c/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/addons/genetic_algorithm.pyresetz	DNA.reset           c                     y r   r   r   s    r   is_validzDNA.is_valid!   s     	r   c                ,    t        j                  |       S r   )copydeepcopyr   s    r   r   zDNA.copy&   s    }}T""r   c                    d | _         y r   r   r   s    r   _taintz
DNA._taint)   s	    r   c                `    | j                   j                   dt        | j                         dS )N())	__class____name__strr   r   s    r   __repr__zDNA.__repr__,   s)    ..))*!C

O+<A>>r   c                d    t        || j                        sJ | j                  |j                  k(  S r   )
isinstancer%   r   )r   others     r   __eq__z
DNA.__eq__/   s)    %000zzU[[((r   c                ,    t        | j                        S r   )lenr   r   s    r   __len__zDNA.__len__3   s    4::r   c                8    | j                   j                  |      S r   )r   __getitem__)r   items     r   r1   zDNA.__getitem__6   s    zz%%d++r   c                \    | j                   j                  ||       | j                          y r   )r   __setitem__r!   )r   keyvalues      r   r4   zDNA.__setitem__9   s    

sE*r   c                ,    t        | j                        S r   )iterr   r   s    r   __iter__zDNA.__iter__=   s    DJJr   c                     y r   r   r   indexs     r   flip_mutate_atzDNA.flip_mutate_at@   r   r   r   r   returnboolr<   intr@   None)r&   
__module____qualname____doc__r   __annotations__abcabstractmethodr   propertyr   r   r!   r(   r,   r/   r1   r4   r9   r=   r   r   r   r   r      s    #G_#K    #?),  	 r   r   c                    | j                   S r   r    )dnas    r   dna_fitnessrN   E   s    ;;r   c                  6    e Zd ZdZej
                  dd       Zy)MutatezAbstract mutation.c                     y r   r   )r   rM   rates      r   mutatezMutate.mutateL   r   r   NrM   r   rR   float)r&   rE   rF   rG   rI   rJ   rS   r   r   r   rP   rP   I   s     r   rP   c                      e Zd ZdZddZy)
FlipMutatezFlip one bit mutation.c                    t        t        |            D ]+  }t        j                         |k  s|j                  |       - y r   )ranger.   randomr=   )r   rM   rR   r<   s       r   rS   zFlipMutate.mutateT   s5    3s8_ 	*E}}%""5)	*r   NrT   r&   rE   rF   rG   rS   r   r   r   rW   rW   Q   s
     *r   rW   c                      e Zd ZdZddZy)NeighborSwapMutatezSwap two neighbors mutation.c                    t        t        |            D ]1  }t        j                         |k  s|dz
  }||   }||   ||<   |||<   3 y N   rY   r.   rZ   )r   rM   rR   r<   i2tmps         r   rS   zNeighborSwapMutate.mutate]   sO    3s8_ 	!E}}%QY"ge*B E
	!r   NrT   r[   r   r   r   r]   r]   Z   s
    &!r   r]   c                      e Zd ZdZddZy)RandomSwapMutatez Swap two random places mutation.c                    t        |      }t        |      D ]L  }t        j                         |k  st        j                  d|      }||k(  r|dz  }||   }||   ||<   |||<   N y )Nr   r`   )r.   rY   rZ   	randrange)r   rM   rR   lengthr<   rb   rc   s          r   rS   zRandomSwapMutate.mutatei   sm    S6] 	!E}}%%%a0;!GB"ge*B E
	!r   NrT   r[   r   r   r   re   re   f   s
    *	!r   re   c                  "    e Zd ZdZdddZddZy)ReverseMutatez'Reverse some consecutive bits mutation.c                8    t        t        |d            | _        y r_   rC   max_bitsr   bitss     r   __init__zReverseMutate.__init__x       T1&
r   c                    t        |      }t        j                         ||| j                  z  z  k  rEt        j                  || j                  z
        }|| j                  z   }||| }t	        |      ||| y y r   )r.   rZ   rn   rg   reversedr   rM   rR   rh   i1rb   rp   s          r   rS   zReverseMutate.mutate{   ss    S==?TTZZ
 
 !!&4::"56BdjjBr":D!$C2J
r   N   rp   rC   rT   r&   rE   rF   rG   rq   rS   r   r   r   rj   rj   u   s    1'(r   rj   c                  "    e Zd ZdZdddZddZy)ScrambleMutatez(Scramble some consecutive bits mutation.c                8    t        t        |d            | _        y r_   rl   ro   s     r   rq   zScrambleMutate.__init__   rr   r   c                
   t        |      }t        j                         ||| j                  z  z  k  rQt        j                  || j                  z
        }|| j                  z   }||| }t        j                  |       |||| y y r   )r.   rZ   rn   rg   shuffleru   s          r   rS   zScrambleMutate.mutate   s{    S==?TTZZ
 
 !!&4::"56BdjjBr":DNN4 C2J
r   Nrw   ry   rT   rz   r   r   r   r|   r|      s    2'	r   r|   c                  6    e Zd ZdZej
                  dd       Zy)MatezAbstract recombination.c                     y r   r   r   dna1dna2s      r   	recombinezMate.recombine   s    r   Nr   r   r   r   )r&   rE   rF   rG   rI   rJ   r   r   r   r   r   r      s    ! r   r   c                      e Zd ZdZddZy)Mate1pCXz"One point crossover recombination.c                b    t        |      }t        j                  d|      }t        ||||       y Nr   r.   rZ   rg   recombine_dna_2pcx)r   r   r   rh   r<   s        r   r   zMate1pCX.recombine   s+    T  F+4uf5r   Nr   r&   rE   rF   rG   r   r   r   r   r   r      s
    ,6r   r   c                      e Zd ZdZddZy)Mate2pCXz"Two point crossover recombination.c                    t        |      }t        j                  d|      }t        j                  d|      }||kD  r||}}t        ||||       y r   r   r   r   r   rh   rv   rb   s         r   r   zMate2pCX.recombine   M    Ta(a(7B4r2.r   Nr   r   r   r   r   r   r      s
    ,/r   r   c                      e Zd ZdZddZy)MateUniformCXzUniform recombination.c                    t        t        |            D ],  }t        j                         dkD  s||   }||   ||<   |||<   . y )Ng      ?ra   )r   r   r   r<   rc   s        r   r   zMateUniformCX.recombine   sG    3t9% 	"E}}$5k"5kU!U		"r   Nr   r   r   r   r   r   r      s
     "r   r   c                      e Zd ZdZddZy)MateOrderedCXz8Recombination class for ordered DNA like UniqueIntDNA().c                    t        |      }t        j                  d|      }t        j                  d|      }||kD  r||}}t        ||||       y r   )r.   rZ   rg   recombine_dna_ocx1r   s         r   r   zMateOrderedCX.recombine   r   r   Nr   r   r   r   r   r   r      s
    B/r   r   c                ,    | || }||| }|| || |||| y)zTwo point crossover.Nr   )r   r   rv   rb   part1part2s         r   r   r      s.    BKEBKEDBKDBKr   c                \    | j                         }t        | |||       t        ||||       y)zOrdered crossover.N)r   replace_dna_ocx1)r   r   rv   rb   copy1s        r   r   r      s)    IIKET4R(T5"b)r   c                    | j                         }||| }|| || d}t        |      }|D ]  }||v r||k(  r|}|| |<   |dz  } y)zWReplace a part in dna1 by dna2 and preserve order of remaining values in
    dna1.
    r   r`   N)r   set)	r   r   rv   rb   oldnewr<   new_setr6   s	            r   r   r      sk     ))+C
r"+CDBKE#hG GB;EU
r   c                  n    e Zd ZdZdZddZedd       Zedd       Ze	dd       Z
d Zd Zdd	Zdd
Zy)FloatDNAz,Arbitrary float numbers in the range [0, 1].r   r   c                R    t        |      | _        | j                          d | _        y r   )r   r   _check_valid_datar   r   s     r   rq   zFloatDNA.__init__   s     "&v,
 (,r   c                2     | d t        |      D              S )Nc              3  D   K   | ]  }t        j                            y wr   )rZ   .0_s     r   	<genexpr>z"FloatDNA.random.<locals>.<genexpr>   s     ;FMMO;s    rY   clsrh   s     r   rZ   zFloatDNA.random   s    ;U6];<<r   c                \    t        |      D cg c]  }| j                  |       c}S c c}w r   rY   rZ   r   nrh   r   s       r   n_randomzFloatDNA.n_random   #    ,1!H5q

6"555   )c                :    t        d | j                  D              S )Nc              3  <   K   | ]  }d |cxk  xr dk  nc   yw              ?Nr   r   vs     r   r   z$FloatDNA.is_valid.<locals>.<genexpr>  s     7q3!?s??7s   allr   r   s    r   r   zFloatDNA.is_valid   s    7DJJ777r   c                2    | j                   st        d      y )Nzdata value out of range)r   
ValueErrorr   s    r   r   zFloatDNA._check_valid_data  s    }}677 r   c           	         | j                   d}nd| j                   d}t        | j                  D cg c]  }t        |d       c}       | S c c}w )N, fitness=None
, fitness=.4f   )r   r'   r   roundr   r   r   s      r   __str__zFloatDNA.__str__  sQ    <<&G"4<<"45GDJJ7quQ{789'CC7s   Ac                d    t        |      | _        | j                          | j                          y r   )r   r   r   r!   r   s     r   r   zFloatDNA.reset  s"    &\
 r   c                B    d| j                   |   z
  | j                   |<   y Nr   r   r;   s     r   r=   zFloatDNA.flip_mutate_at  s    $**U"33

5r   N)r   Iterable[float])rh   rC   r@   r   )r   rC   rh   rC   r@   zlist[FloatDNA]r?   rB   )r&   rE   rF   rG   	__slots__rq   classmethodrZ   r   rK   r   r   r   r   r=   r   r   r   r   r      s`    6$I-
 = = 6 6 8 88D
4r   r   c                  h    e Zd ZdZdZddZedd       Zedd       Z	edd       Z
d ZddZdd	Zy
)BitDNAzOne bit DNA.r   c                @    t        d |D              | _        d | _        y )Nc              3  2   K   | ]  }t        |        y wr   rA   r   s     r   r   z"BitDNA.__init__.<locals>.<genexpr>  s     %>!d1g%>   )r   r   r   r   s     r   rq   zBitDNA.__init__  s    !%%>v%>!>
(,r   c                     y)NTr   r   s    r   r   zBitDNA.is_valid   s    r   c                2     | d t        |      D              S )Nc              3  Z   K   | ]#  }t        t        j                  d d             % yw)r   r`   N)rA   rZ   randintr   s     r   r   z BitDNA.random.<locals>.<genexpr>&  s      E!4q!,-Es   )+r   r   s     r   rZ   zBitDNA.random$  s    EuV}EEEr   c                \    t        |      D cg c]  }| j                  |       c}S c c}w r   r   r   s       r   r   zBitDNA.n_random(  r   r   c                    | j                   d}nd| j                   d}t        | j                  D cg c]  }t        |       c}       | S c c}w Nr   r   r   r   r'   r   rC   r   s      r   r   zBitDNA.__str__,  O    <<&G"4<<"45Gtzz2!s1v234WI>>2   Ac                R    t        d |D              | _        | j                          y )Nc              3  2   K   | ]  }t        |        y wr   r   r   s     r   r   zBitDNA.reset.<locals>.<genexpr>4  s     2a$q'2r   r   r   r!   r   s     r   r   zBitDNA.reset3  s    2622
r   c                >    | j                   |    | j                   |<   y r   r   r;   s     r   r=   zBitDNA.flip_mutate_at7  s     $

5 11

5r   Nr>   r?   )rh   rC   r@   r   )r   rC   rh   rC   r@   zlist[BitDNA]r   r   r@   rD   rB   )r&   rE   rF   rG   r   rq   rK   r   r   rZ   r   r   r   r=   r   r   r   r   r     s\    $I-   F F 6 6?2r   r   c                  h    e Zd ZdZdZddZedd       Zedd       Ze	dd       Z
d ZddZdd	Zy
)UniqueIntDNAaU  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                    |  t        |t              r!t        t        |            | _        d | _        y |D cg c]  }t        |       c}| _        | j
                  st        | j                        d | _        y c c}w r   )r*   rC   r   rY   r   r   	TypeErrorr   )r   r   r   s      r   rq   zUniqueIntDNA.__init__H  sb    fc"eFm,DJ
 )- +11Q#a&1DJ==

++(, 2s   A;c                T     | |      }t        j                  |j                         |S r   )rZ   r   r   )r   rh   rM   s      r   rZ   zUniqueIntDNA.randomR  s     &ksyy!
r   c                \    t        |      D cg c]  }| j                  |       c}S c c}w r   r   r   s       r   r   zUniqueIntDNA.n_randomX  r   r   c                j    t        t        | j                              t        | j                        k(  S r   )r.   r   r   r   s    r   r   zUniqueIntDNA.is_valid\  s"    3tzz?#s4::66r   c                    | j                   d}nd| j                   d}t        | j                  D cg c]  }t        |       c}       | S c c}w r   r   r   s      r   r   zUniqueIntDNA.__str__`  r   r   c                R    t        d |D              | _        | j                          y )Nc              3  2   K   | ]  }t        |        y wr   rC   r   s     r   r   z%UniqueIntDNA.reset.<locals>.<genexpr>h       1Q#a&1r   r   r   s     r   r   zUniqueIntDNA.resetg      1&11
r   c                    t        d      )Nzflip mutation not supported)r   r;   s     r   r=   zUniqueIntDNA.flip_mutate_atk  s    566r   N)r   zUnion[int, Iterable])rh   rC   r@   r   )r   rC   rh   rC   r@   zlist[UniqueIntDNA]r?   r   rB   )r&   rE   rF   rG   r   rq   r   rZ   r   rK   r   r   r   r=   r   r   r   r   r   ;  s^     %I-  
 6 6 7 7?7r   r   c                  n    e Zd ZdZdZddZedd       Zedd       Ze	dd       Z
d Zd Zdd	Zdd
Zy)
IntegerDNAzkInteger 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                    t        |      | _        t        |      | _        | j                  st        | j                        d | _        y r   )rC   _maxr   r   r   r   r   )r   r   max_s      r   rq   zIntegerDNA.__init__v  s5    I	 $V
}}DJJ''(,r   c                P    t        |       | fdt        |      D              S )Nc              3  J   K   | ]  }t        j                  d         ywr   N)rZ   rg   )r   r   imaxs     r   r   z$IntegerDNA.random.<locals>.<genexpr>  s     E!F$$Q-Es    #)rC   rY   )r   rh   r   r   s      @r   rZ   zIntegerDNA.random}  s#    4yEuV}EtLLr   c                ^    t        |      D cg c]  }| j                  ||       c}S c c}w r   r   )r   r   rh   r   r   s        r   r   zIntegerDNA.n_random  s%    27(;Q

64(;;;s   *c                @     t         fd j                  D              S )Nc              3  R   K   | ]  }d |cxk  xr j                   k  nc    ywr   )r   )r   r   r   s     r   r   z&IntegerDNA.is_valid.<locals>.<genexpr>  s"     :!1%DII%%:s   $'r   r   s   `r   r   zIntegerDNA.is_valid  s    :tzz:::r   c                z    | j                   j                   dt        | j                         d| j                   dS )Nr#   z, r$   )r%   r&   r'   r   r   r   s    r   r(   zIntegerDNA.__repr__  s3    ..))*!C

O+<BtyykKKr   c                    | j                   d}nd| j                   d}t        | j                  D cg c]  }t        |       c}       | S c c}w r   r   r   s      r   r   zIntegerDNA.__str__  r   r   c                R    t        d |D              | _        | j                          y )Nc              3  2   K   | ]  }t        |        y wr   r   r   s     r   r   z#IntegerDNA.reset.<locals>.<genexpr>  r   r   r   r   s     r   r   zIntegerDNA.reset  r   r   c                \    | j                   | j                  |   z
  dz
  | j                  |<   y r_   )r   r   r;   s     r   r=   zIntegerDNA.flip_mutate_at  s'     II

5(99A=

5r   N)r   zIterable[int]r   rC   )rh   rC   r   rC   r@   r   )r   rC   rh   rC   r   rC   r@   zlist[IntegerDNA]r?   r   rB   )r&   rE   rF   rG   r   rq   r   rZ   r   rK   r   r(   r   r   r=   r   r   r   r   r   o  sf     %I- M M < < ; ;L?>r   r   c                  \    e Zd ZdZej
                  dd       Zej
                  dd       Zy)	SelectionzAbstract selection class.c                     y r   r   r   counts     r   pickzSelection.pick  r   r   c                     y r   r   r   
candidatess     r   r   zSelection.reset  r   r   Nr  rC   r@   Iterable[DNA]r  r  )r&   rE   rF   rG   rI   rJ   r  r   r   r   r   r
  r
    s7    #  	 r   r
  c                  6    e Zd ZdZej
                  dd       Zy)	EvaluatorzAbstract evaluation class.c                     y r   r   r   rM   s     r   evaluatezEvaluator.evaluate  r   r   NrM   r   r@   rU   )r&   rE   rF   rG   rI   rJ   r  r   r   r   r  r    s    $ r   r  c                  T    e Zd Ze G d d             ZddZd	dZd
dZedd       Z	y)Logc                  ,    e Zd ZU ded<   ded<   ded<   y)	Log.EntryrU   runtimer   avg_fitnessN)r&   rE   rF   rH   r   r   r   Entryr    s    r   r!  c                    g | _         y r   )entriesr   s    r   rq   zLog.__init__  s	    (*r   c                d    | j                   j                  t        j                  |||             y r   )r#  appendr  r!  )r   r  r   r   s       r   addzLog.add  s!    CIIgwDEr   c                    | j                   D cg c]%  }|j                  |j                  |j                  f' }}t	        |d      5 }t        j                  ||d       d d d        y c c}w # 1 sw Y   y xY w)Nwtr   )indent)r#  r  r   r   openjsondump)r   filenameedatafps        r   r,  zLog.dump  sh    ?C||L!AIIq}}5LL(D! 	*RIIdBq)	* 	* M	* 	*s   *A)A..A7c                    t        |d      5 }t        j                  |      }d d d        t               }D ]  \  }}}|j	                  |||        |S # 1 sw Y   3xY w)Nrt)r*  r+  loadr  r&  )r   r-  r0  r/  logr  r   r   s           r   r3  zLog.load  sb    (D! 	!R99R=D	!e-1 	3)GWkGGGWk2	3
	! 	!s   AANr@   rD   )r  rU   r   rU   r   rU   r@   rD   )r-  r'   r@   rD   )r-  r'   r@   r  )
r&   rE   rF   r	   r!  rq   r&  r,  r   r3  r   r   r   r  r    s=      
+F*
  r   r  c                  4    e Zd Zd Zd Zd ZddZd	dZd Zy)

HallOfFamec                0    || _         t               | _        y r   )r  dict_unique_entriesr  s     r   rq   zHallOfFame.__init__  s    
#vr   c                P      fd j                         d  j                   D        S )Nc              3  <   K   | ]  }j                   |     y wr   )r:  )r   kr   s     r   r   z&HallOfFame.__iter__.<locals>.<genexpr>  s!      
()D  #
s   )_sorted_keysr  r   s   `r   r9   zHallOfFame.__iter__  s)    
-1->->-@4::-N
 	
r   c                L    t        | j                  j                         d      S )NT)reverse)sortedr:  keysr   s    r   r>  zHallOfFame._sorted_keys  s    d**//14@@r   c                R    |j                   J || j                  |j                   <   y r   )r   r:  r  s     r   r&  zHallOfFame.add  s&    {{&&&,/S[[)r   c                    | j                   }| j                         }|d t        || j                         D cg c]  }||   	 c}S c c}w r   )r:  r>  minr  )r   r  r#  rB  r=  s        r   getzHallOfFame.get  sF    &&  "$()A3udjj+A$BCq
CCCs   Ac                    t        | j                        | j                  k  ry | j                  }| j                         }|d | j                   D ci c]  }|||   
 c}| _        y c c}w r   )r.   r:  r  r>  )r   r#  rB  r=  s       r   purgezHallOfFame.purge  s^    t##$

2&&  "7;Ldjj7IJ!71:JJs   A'N)rM   r   )r  rC   r@   z	list[DNA])	r&   rE   rF   rq   r9   r>  r&  rF  rH  r   r   r   r7  r7    s#    &

A0D
Kr   r7  c                v    |dk  r$t        | t              }d|z
  |j                  z  n||z  fd| D        S )Nr   r5   r   c              3  B   K   | ]  }|j                   kD  s|  y wr   r    )r   c	min_values     r   r   z#threshold_filter.<locals>.<genexpr>  s     ;!QYY%:A;s   )rE  rN   r   )r  best_fitness	thresholdminimumrM  s       @r   threshold_filterrQ    s@     sjk29_7	 9,	;z;;r   c                      e Zd ZdZ	 d	 	 	 	 	 ddZddZedd       Zedd       ZddZ		 	 d	 	 	 	 	 ddZ
dd	Zdd
ZddZddZddZy)GeneticOptimizera  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                   |dk  rt        d      d| _        t               | _        g | _        || _        t               | _        t               | _	        t               | _        t        |      | _        t        |      | _        d| _        d| _        d| _        d| _        d| _        d	| _        d
| _        d	| _        d	| _        t3        g       | _        d	| _        d
| _        t;        d      | _        y )Nr`   zrequires max_generations > 0rS  g.B}Td   gffffff?g{Gz?   r   r   
   )r   namer  r4  r  	evaluatorRouletteSelection	selectionr   materW   mutationrC   max_generationsrU   max_fitnessmax_runtimemax_stagnationcrossover_ratemutation_rateelitismrO  
generation
start_timer  r   best_dnarN  
stagnationr7  hall_of_fame)r   rY  r^  r_  s       r   rq   zGeneticOptimizer.__init__  s     Q;<<&	5%' %.$5$7"*	"  #?3"'"4"&!"! !$  !!#BZ#& &rNr   c                $    t        |      | _        y r   )rU   rN  )r   r6   s     r   reset_fitnesszGeneticOptimizer.reset_fitness/  s    !%Lr   c                ,    t        | j                        S r   )rA   re  r   s    r   is_executedzGeneticOptimizer.is_executed2  s    DOO$$r   c                ,    t        | j                        S r   )r.   r  r   s    r   r  zGeneticOptimizer.count6  s    4??##r   c                h    | j                   s| j                  j                  |       y t        d      )Nzalready executed)rm  r  extendr   r  s     r   add_candidateszGeneticOptimizer.add_candidates:  s)    OO""3'.//r   Nc                2   | j                   rt        d      | j                  st        d       t	        j
                         }|| _        t        d| j                  dz         D ]  | _	        | j                          t	        j
                         }|| j                  z
  | _        | j                  | j                  k\  s2| j                  | j                  k\  s| j                  | j                   k\  r y |r||z
  |kD  r ||       r y |}| j#                           y )Nzcan only run oncezno DNA defined!r`   )rm  r   r  printtimeperf_counterrf  rY   r^  re  measure_fitnessr  rN  r_  r`  rh  ra  next_generation)r   feedbackintervalt0t1s        r   executezGeneticOptimizer.execute@  s    
 /00#$ $Q(<(<q(@A 	#DO  """$B/DL!!T%5%55<<4#3#33??d&9&99BGh.D>  "	#r   c                n   | xj                   dz  c_         d}| j                  D ]  }|j                  ||j                  z  }| j                  j	                  |      }||_        ||z  }| j
                  j                  |       || j                  kD  sq|| _        || _        d| _          | j
                  j                          	 |t        | j                        z  }| j                  j                  t        j                         | j                  z
  | j                  |       y # t        $ r d}Y Tw xY w)Nr`   r   r   )rh  r  r   rY  r  ri  r&  rN  rg  rH  r.   ZeroDivisionErrorr4  rt  ru  rf  )r   fitness_sumrM   r   r   s        r   rv  z GeneticOptimizer.measure_fitness[  s   1 ?? 	$C{{&s{{*nn--c2G!CK7"K!!#&***$+! #"#	$ 	!	%DOO(<<K 	$//1	
 ! 	K	s   D& &D43D4c                `   t        | j                        }g }| j                  }|j                  | j	                  | j                               | j
                  dkD  r4|j                  | j                  j                  | j
                               t        |      |k  r|j                  d      \  }}|j                         }|j                         }| j                  ||       | j                  ||       |j                  |       |j                  |       t        |      |k  r|| _        y )Nr   rV  )r.   r  r[  r   filter_thresholdrd  rp  ri  rF  r  r   r   rS   r%  )r   r  r  selectorr   r   s         r   rw  z GeneticOptimizer.next_generationv  s    DOO$ "
>>t,,T__=><<!d//33DLLAB*o%!q)JD$99;D99;DNN4&KKd#d#d# *o% %r   c                f    | j                   dkD  r!t        || j                  | j                         S |S )Nr   )rO  rQ  rN  r  s     r   r  z!GeneticOptimizer.filter_threshold  s4    >>C#D--t~~  r   c                    t        j                          | j                  k  r| j                  j                  ||       y y r   )rZ   rb  r\  r   r   s      r   r   zGeneticOptimizer.recombine  s/    ==?T000IId+ 1r   c                    | j                   j                  || j                         | j                   j                  || j                         y r   )r]  rS   rc  r   s      r   rS   zGeneticOptimizer.mutate  s6    T4#5#56T4#5#56r   )r   )rY  r  r^  rC   r_  rU   )r6   rU   r@   rD   r?   )r@   rC   )rM   r  r   )rx  z,Optional[Callable[[GeneticOptimizer], bool]]ry  rU   r@   rD   r5  )r  Sequence[DNA]r@   r  r   )r&   rE   rF   rG   rq   rk  rK   rm  r  rq  r|  rv  rw  r  r   rS   r   r   r   rS  rS    s    * !	&+&+ &+ 	&+P) % % $ $0 BF#># # 
	#6
6%&,7r   rS  c                    d | D        S )Nc              3  F   K   | ]  }|d k(  rd ndt        |      z    ywr   )abs)r   ws     r   r   z(conv_negative_weights.<locals>.<genexpr>  s#     ?!18Cs1v-?s   !r   )weightss    r   conv_negative_weightsr    s    ?w??r   c                  *    e Zd ZdZdddZddZd	dZy)
rZ  zSelection by fitness values.c                @    g | _         g | _        t        |      | _        y r   )_candidates_weightsrA   _negative_values)r   negative_valuess     r   rq   zRouletteSelection.__init__  s    &(%' $_ 5r   c                    t        |      | _        | j                  r+t        t        d | j                  D                    | _        y | j                  D cg c]  }|j
                   c}| _        y c c}w )Nc              3  4   K   | ]  }|j                     y wr   r    )r   rM   s     r   r   z*RouletteSelection.reset.<locals>.<genexpr>  s     %Ncckk%Ns   )r   r  r  r  r  r   )r   r  rM   s      r   r   zRouletteSelection.reset  sY    
+   %%NT=M=M%NNDM 594D4DESS[[EDMEs   A2c                Z    t        j                  | j                  | j                  |      S )N)r=  )rZ   choicesr  r  r  s     r   r  zRouletteSelection.pick  s    ~~d..GGr   N)F)r  rA   r@   rD   r  r  r&   rE   rF   rG   rq   r   r  r   r   r   rZ  rZ    s    &6
FHr   rZ  c                      e Zd ZdZddZy)RankBasedSelectionzSelection by rank of fitness.c                    t        |      | _        | j                  j                  t               t        t	        dt        | j                        dz               | _        y )NrJ  r`   )r   r  sortrN   rY   r.   r  r  s     r   r   zRankBasedSelection.reset  sK    
++. U1c$*:*:&;a&?@Ar   Nr  )r&   rE   rF   rG   r   r   r   r   r  r    s    'Br   r  c                  (    e Zd ZdZddZddZddZy)	TournamentSelectionz@Selection by choosing the best of a certain count of candidates.c                     g | _         || _        y r   )r  r  r  s     r   rq   zTournamentSelection.__init__  s    &($r   c                $    t        |      | _        y r   )r   r  r  s     r   r   zTournamentSelection.reset  s    
+r   c              #     K   t        |      D ]^  }t        | j                        D cg c]!  }t        j                  | j                        # }}|j                  t               |d    ` y c c}w w)NrJ  )rY   r  rZ   choicer  r  rN   )r   r  r   r   s       r   r  zTournamentSelection.pick  sj     u 	A9>t9O45d../F  KKKK(*	s   &A5&A0'A5N)r  rC   r  r  r  r   r   r   r  r    s    J%,r   r  r  )
r   r   r   r   rv   rC   rb   rC   r@   rD   )r  r  rN  rU   rO  rU   r@   r  )r  r   r@   r   ).
__future__r   typingr   r   r   r   r   rI   r   dataclassesr	   r+  rZ   rt  ABCr   rN   rP   rW   r]   re   rj   r|   r   r   r   r   r   r   r   r   r   r   r   r   r
  r  r  r7  rQ  rS  r  rZ  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   