In [26]:
# 假如 Jupyter 所在機器並未安裝 sympy, 可以利用 sudo pip3 install sympy 安裝
import sympy
#print("已經可以使用 sympy!")
# 假設 hinge 旋轉點為 A, handle 與 connection 連接旋轉點為 B, piston 與 connection 的滑塊點為 C
# B 點向 AC 線段的垂直投影點設為 D
# 首先, 令 theta 為 sympy 模式下的符號變數
theta = sympy.Symbol('theta')
# A 點到 B 點的距離為 r
r = 1.5
# B 點到 C 點的距離為 2.3
bc = 2.3
# A 點的 x 座標為 0
ax = 0
# A 點的 y 座標為 0
ay = 0
# 利用 sc 與 ss 表示 sympy 模式下的 cos(theta) 與 sin(theta)
sc = sympy.cos(theta)
ss = sympy.sin(theta)
# ad 為 A 點到 D 點的距離
ad = r*sc
bd = r*ss
# 利用三角函數求 B 點的座標, bx 為 B 點 x 分量, by 為 B 點 y 分量
bx = ax + ad
by = ay + bd
# 根據 BCD 三點所圍成的三角形, 已知 bd 與 bc 長度, 從畢氏定理可以求 dc 長度
dc = sympy.sqrt(bc*bc - bd*bd)
# 求 C 點的座標, cx 為 C 點的 x 座標, cy 為 C 點的 y 座標
cx = ax + ad + dc
cy = ay
#print("bx = ", bx, ", by = ", by)
#print("cx = ", cx, ", cy = ", cy)
# 以下透過 B 點與 C 點座標, 求 connect 零件 B' 與 C' 的座標
# 關鍵角度為 <BCD
# 利用 dc 與 bd 長度計算 <BCD
angle_bcd = sympy.atan2(dc, bd)
offset_r = 0.25
bprimex = bx-offset_r*sympy.sin(angle_bcd)
bprimey = by-offset_r*sympy.cos(angle_bcd)
cprimex = cx-offset_r*sympy.sin(angle_bcd)
cprimey = cy-offset_r*sympy.cos(angle_bcd)
#b = sympy.Point(bx, by)
#c = sympy.Point(cx, cy)
# 根據 B' 與 C' 的座標, 建立 sympy 模式下的 Point 物件案例
bprime = sympy.Point(bprimex, bprimey)
cprime = sympy.Point(cprimex, cprimey)
# 設 sympy 模式下的 Line 方程式變數為 t,當 t=0, 指 Line 的 B' 點
# 而 t=1 時, 指 Line 的 C' 點
t = sympy.Symbol('t')
#bcline = sympy.Line(b, c)
# 利用 bprime 與 cprime 建立 Line
bcprimeline = sympy.Line(bprime, cprime)
# 列出 BC 線段上的點座標
#p = bcline.arbitrary_point(t)
#print(p.x, p.y, sep=", ")
# 令 p 為 B'C' 直線的方程式, 從上述推導知此方程式為 t 與 theta 變數的函式
p = bcprimeline.arbitrary_point(t)
# 將此 B'C' 直線方程式的 x 分量與 y 分量方程式列出
print(p.x, p.y, sep=", ")
#將符號式運算與數值運算分開, 可以提升運算速度
# 進行數值分析, 搜尋交點對應的 t 與 theta
#ax = 0.75/2
#ay = 0.5
#deg  = math.pi/ 180
# 準確到小數二位
#num = 500
#for j in range(0, 180*num):
#    for i in range(0, 501):
#        theta_value = j/num*deg
#        t_value = i/500
#        x = p.x.evalf(subs={theta: theta_value, t: t_value})
#        y = p.y.evalf(subs={theta: theta_value, t: t_value})
#        if math.sqrt((math.pow(x-ax, 2)+math.pow(y-ay, 2))/2) < 0.001:


t*sqrt(-225*sin(theta)**2 + 529)/10 - sqrt(-225*sin(theta)**2 + 529)/92 + 3*cos(theta)/2, (-3*t/2 + 123/92)*sin(theta)

In [31]:
# 進行數值分析, 搜尋交點對應的 t 與 theta
from math import *
ax = 0.75/2
ay = 0.5
deg  = pi/ 180
# 準確到小數二位
num = 200
for j in range(0, 180*num):
    for i in range(0, 201):
        theta_value = j/num*deg
        t_value = i/200
        theta = theta_value
        t = t_value
        x = t*sqrt(-225*sin(theta)**2 + 529)/10 - sqrt(-225*sin(theta)**2 + 529)/92 + 3*cos(theta)/2
        y = (-3*t/2 + 123/92)*sin(theta)
        if abs(x-ax)<0.0001 and abs(y-ay)<0.0001:
            print(round(x,5), round(y, 5), round(theta_value/deg, 3), round(t_value, 5))
            #print(abs(x-ax), abs(y-ay))


0.37505 0.50006 105.705 0.545
0.37494 0.50005 105.71 0.545

In [32]:
#encoding=utf8
# genetic.py
#
import random
import operator
# for Intersect
from math import *
MAXIMIZE, MINIMIZE = 11, 22
class Individual:
    chromosome = None
    score = None
    # Here the size of var depends on var_number
    var = []
    var_number = 2
    for i in range(var_number):
        var.append(0)
    alleles = (0,1)
    # 以下為參數可負數時的編碼考量
    #前10為小數,後10為整數,第21則為正負號
    #0~9表示小數,10~19表示整數,而指標第20則表示第一數的正號或負號,若為0則表示正,若為1表示負號.
    #21~30表示第二數的小數部分,31~40則表示第二數的整數部分,第41指標則表示第二數的正號或負號
    #42~51表示第三數的小數部分,52~61則表示第二數的整數部分,第62指標則表示第三數的正號或負號
    # -1023 ~ 1023
    #length = 21*var_number,若接受負數參數,則必須同步修改 20->21
    length = 20*var_number
    seperator = ''
    optimization = MINIMIZE
    def __init__(self, chromosome=None):
        self.chromosome = chromosome or self._makechromosome()
        self.score = None  # set during evaluation
    def _getvar(self,chromosome=None):
        x = 0
        for i in range(0,self.var_number):
            for j in range(i*20,i*20+10):
                x +=self.chromosome[j]<<(j-(i*20))
            if (x>999):
                x=999
            x/=1000.
            for j in range(i*20+10,i*20+20):
                x +=self.chromosome[j]<<(j-(i*20+10))
            self.var[i] = x
        return self.var
        ''' for -1023 ~ 1023,當設計變數可以接受負值時使用,每一變數使用21個 bit strings
#for design variable -1023 ~1023
        for i in range(self.var_number):
            x = 0
            for j in range(i*21,i*21+10):
                x +=self.chromosome[j]<<(j-(i*21))
            if (x>999):
                x=999
            x/=1000.
            for j in range(i*(21)+10,i*(21)+20):
                x +=self.chromosome[j]<<(j-(i*21+10))
            if(self.chromosome[i*(21)+20] == 1):
                self.var[i] = -x
            else:
                self.var[i] = x
            x = 0
        return self.var
        '''
    def _makechromosome(self):
        "makes a chromosome from randomly selected alleles."
        return [random.choice(self.alleles) for gene in range(self.length)]
    def evaluate(self, optimum=None):
        "this method MUST be overridden to evaluate individual fitness score."
        pass
    def crossover(self, other):
        "override this method to use your preferred crossover method."
        return self._twopoint(other)
    def mutate(self, gene):
        "override this method to use your preferred mutation method."
        self._pick(gene)
    # sample mutation method
    def _pick(self, gene):
        "chooses a random allele to replace this gene's allele."
        self.chromosome[gene] = random.choice(self.alleles)
    # sample crossover method
    def _twopoint(self, other):
        "creates offspring via two-point crossover between mates."
        left, right = self._pickpivots()
        def mate(p0, p1):
            chromosome = p0.chromosome[:] # 交配時,以p0的基因為基礎(複製整個 p0 的染色體內容
            chromosome[left:right] = p1.chromosome[left:right] # 接續上一個 p0 的染色體內容,將索引 left 至 right 的內容,替換成 p1 的基因
            child = p0.__class__(chromosome)
            child._repair(p0, p1)
            return child
        return mate(self, other), mate(other, self)
    # some crossover helpers ...
    def _repair(self, parent1, parent2):
        "override this method, if necessary, to fix duplicated genes."
        pass
    def _pickpivots(self):
        left = random.randrange(1, self.length-2)
        right = random.randrange(left, self.length-1)
        return left, right
    #
    # other methods
    #
    def __repr__(self):
        "returns string representation of self"
        '''
        return '<%s chromosome="%s" score=%s var=%s>' % \
               (self.__class__.__name__,
                self.seperator.join(map(str,self.chromosome)), self.score,self._getvar(self.chromosome))
        '''
        return '<%s score=%s var=%s>' % \
               (self.__class__.__name__,self.score,self._getvar(self.chromosome))
    # since the __cmp__ special function is gone  use the __lt__ in stead
    # use the expression (a > b) - (a < b) as the equivalent for cmp(a, b)
    #def __cmp__(self, other):
    # these are for python 3
    def __cmp__(self, other):
        if self.optimization == MINIMIZE:
            #return cmp(self.score, other.score)
            return (self.score > other.score) - (self.score < other.score)
        else: # MAXIMIZE
            #return cmp(other.score, self.score)
            return (other.score > self.score) - (other.score < self.score)
            
    def __lt__(self, other):
        return self.__cmp__(other) < 0
    def __le__(self, other):
        return self.__cmp__(other) <= 0
    def __gt__(self, other):
        return self.__cmp__(other) > 0
    def __ge__(self, other):
        return self.__cmp__(other) >= 0 
    def copy(self):
        twin = self.__class__(self.chromosome[:])
        twin.score = self.score
        return twin
class Environment(object):
    x = [0]
    y = [0]
    def __init__(self, kind, population=None, size=100, maxgenerations=100,
                 crossover_rate=0.90, mutation_rate=0.07, optimum=None):
        self.kind = kind
        self.size = size
        self.optimum = optimum
        self.population = population or self._makepopulation()
        for individual in self.population:
            individual.evaluate(self.optimum)
        self.crossover_rate = crossover_rate
        self.mutation_rate = mutation_rate
        self.maxgenerations = maxgenerations
        self.generation = 0
        self.report()
    def _makepopulation(self):
        return [self.kind() for individual in range(self.size)]
    def run(self):
        while not self._goal():
            self.step()
    def _goal(self):
        return self.generation > self.maxgenerations or \
               self.best.score == self.optimum
    def step(self):
        # this sort is not working with python 3.0, modification is needed
        self.population.sort()
        self._crossover()
        self.generation += 1
        self.report()
        self.x.append(self.generation)
        # 設定為只附加所選定範圍的值,這裡只取大於或等於 0 的 score 值
        if self.best.score <=5:
            self.y.append(self.best.score)
        else:
            self.y.append(5)
    def _crossover(self):
        next_population = [self.best.copy()]
        while len(next_population) < self.size:
            mate1 = self._select()
            if random.random() < self.crossover_rate:
                mate2 = self._select()
                offspring = mate1.crossover(mate2)
            else:
                offspring = [mate1.copy()]
            for individual in offspring:
                self._mutate(individual)
                individual.evaluate(self.optimum)
                next_population.append(individual)
        self.population = next_population[:self.size]
    def _select(self):
        "override this to use your preferred selection method"
        return self._tournament()
    def _mutate(self, individual):
        for gene in range(individual.length):
            if random.random() < self.mutation_rate:
                individual.mutate(gene)
    #
    # sample selection method
    #
    def _tournament(self, size=8, choosebest=0.90):
        competitors = [random.choice(self.population) for i in range(size)]
        competitors.sort()
        if random.random() < choosebest:
            return competitors[0]
        else:
            return random.choice(competitors[1:])
    def best():
        doc = "individual with best fitness score in population."
        def fget(self):
            return self.population[0]
        return locals()
    best = property(**best())
    def report(self):
        print ("="*70)
        print ("generation: ", self.generation)
        print ("best:       ", self.best)

# 以上為 genetic.py 目前將兩者結合在一起
#encoding=utf8
# volume.py - useage example
#
# the fittest individual will have a chromosome consisting of 40 '1's
#
#
#import genetic
class Volume(Individual):
    optimization = MAXIMIZE
    def evaluate(self, optimum=None):
        SURFACE = 80
        # self.score is the fitness value
        self._getvar(self.chromosome)
        
        x = self.var[0]
        y = self.var[1]
        z=(SURFACE - x*y)/(2.*(x+y))
        fitness_value = x*y*z
        
        self.score = fitness_value
        
    def mutate(self, gene):
        self.chromosome[gene] = not self.chromosome[gene] # bit flip

class Intersect(Individual):
    optimization = MINIMIZE
    def evaluate(self, optimum=None):
        # self.score is the fitness value
        self._getvar(self.chromosome)
        
        t = self.var[0]
        deg = pi/180
        theta = self.var[1]*deg
        xtarget = 0.75/2
        ytarget = 0.5
        x = t*sqrt(-225*sin(theta)**2 + 529)/10 - sqrt(-225*sin(theta)**2 + 529)/92 + 3*cos(theta)/2
        y = (-3*t/2 + 123/92)*sin(theta)
        # 適應值
        fitness_value = pow(x-xtarget, 8)+pow(y-ytarget, 8)

        # 指定 t 的範圍, 小於 1 大於 0, 否則給予處罰
        if t > 1:
            fitness_value += 1000
        if t < 0:
            fitness_value += 1000
        # 指定 theta 的範圍, 小於 2pi 大於 0, 否則給予處罰
        if theta > 2*pi:
            fitness_value += 1000
        if theta < 0:
            fitness_value += 1000

        
        self.score = fitness_value
        
    def mutate(self, gene):
        self.chromosome[gene] = not self.chromosome[gene] # bit flip
        

if __name__ == "__main__":
    #env = Environment(Volume, size=500, maxgenerations=100)
    env = Environment(Intersect, size=500, maxgenerations=100)
    env.run()


======================================================================
generation:  0
best:        <Intersect score=2.826811408379918e+25 var=[812.687, 785.845687]>
======================================================================
generation:  1
best:        <Intersect score=1000.0034160632063 var=[0.29, 789.20229]>
======================================================================
generation:  2
best:        <Intersect score=0.009775064229276407 var=[0.836, 227.074836]>
======================================================================
generation:  3
best:        <Intersect score=0.0025098833501980603 var=[0.836, 161.074836]>
======================================================================
generation:  4
best:        <Intersect score=0.0006180790289501538 var=[0.29, 84.04029]>
======================================================================
generation:  5
best:        <Intersect score=0.0004710844977719737 var=[0.302, 89.025302]>
======================================================================
generation:  6
best:        <Intersect score=1.7699050714576565e-07 var=[0.55, 99.97055]>
======================================================================
generation:  7
best:        <Intersect score=2.627213594574959e-12 var=[0.566, 107.906566]>
======================================================================
generation:  8
best:        <Intersect score=2.051293315930051e-17 var=[0.55, 106.13255000000001]>
======================================================================
generation:  9
best:        <Intersect score=2.051293315930051e-17 var=[0.55, 106.13255000000001]>
======================================================================
generation:  10
best:        <Intersect score=1.1475320213907624e-17 var=[0.55, 105.83655]>
======================================================================
generation:  11
best:        <Intersect score=1.1475320213907624e-17 var=[0.55, 105.83655]>
======================================================================
generation:  12
best:        <Intersect score=1.1475320213907624e-17 var=[0.55, 105.83655]>
======================================================================
generation:  13
best:        <Intersect score=1.1475320213907624e-17 var=[0.55, 105.83655]>
======================================================================
generation:  14
best:        <Intersect score=2.429192382686878e-18 var=[0.541, 105.52654100000001]>
======================================================================
generation:  15
best:        <Intersect score=5.3229636391504915e-21 var=[0.546, 105.914546]>
======================================================================
generation:  16
best:        <Intersect score=5.3229636391504915e-21 var=[0.546, 105.914546]>
======================================================================
generation:  17
best:        <Intersect score=5.3229636391504915e-21 var=[0.546, 105.914546]>
======================================================================
generation:  18
best:        <Intersect score=8.033854965956136e-23 var=[0.544, 105.70054400000001]>
======================================================================
generation:  19
best:        <Intersect score=8.033854965956136e-23 var=[0.544, 105.70054400000001]>
======================================================================
generation:  20
best:        <Intersect score=8.033854965956136e-23 var=[0.544, 105.70054400000001]>
======================================================================
generation:  21
best:        <Intersect score=5.436671603963436e-30 var=[0.545, 105.69754499999999]>
======================================================================
generation:  22
best:        <Intersect score=5.436671603963436e-30 var=[0.545, 105.69754499999999]>
======================================================================
generation:  23
best:        <Intersect score=5.436671603963436e-30 var=[0.545, 105.69754499999999]>
======================================================================
generation:  24
best:        <Intersect score=5.436671603963436e-30 var=[0.545, 105.69754499999999]>
======================================================================
generation:  25
best:        <Intersect score=5.436671603963436e-30 var=[0.545, 105.69754499999999]>
======================================================================
generation:  26
best:        <Intersect score=5.436671603963436e-30 var=[0.545, 105.69754499999999]>
======================================================================
generation:  27
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  28
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  29
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  30
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  31
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  32
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  33
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  34
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  35
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  36
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  37
best:        <Intersect score=1.675419867509255e-32 var=[0.545, 105.702545]>
======================================================================
generation:  38
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  39
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  40
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  41
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  42
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  43
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  44
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  45
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  46
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  47
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  48
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  49
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  50
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  51
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  52
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  53
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  54
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  55
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  56
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  57
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  58
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  59
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  60
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  61
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  62
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  63
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  64
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  65
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  66
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  67
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  68
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  69
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  70
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  71
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  72
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  73
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  74
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  75
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  76
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  77
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  78
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  79
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  80
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  81
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  82
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  83
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  84
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  85
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  86
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  87
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  88
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  89
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  90
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  91
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  92
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  93
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  94
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  95
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  96
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  97
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  98
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  99
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  100
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>
======================================================================
generation:  101
best:        <Intersect score=2.804233328009431e-33 var=[0.545, 105.70354499999999]>

In [ ]: