def group_connections(clock): # Returns a big list of connections, redundant, ordered by piece connection_list = gen.list_connections(clock) cn_group = [] for piece in clock[1:]: cn_group += [find_connections(piece, connection_list)] return cn_group
def initial_clock_run(clock): #INPUT : LIST OF OBJECTS OF A CLOCK #OUTPUT : IF THE CLOCK RUNS< INITIALIZE THE MOVEMENT OF ESCAPE WHEEL. connection_list = gen.list_connections(clock) if does_clock_run(connection_list): for i in range(1, len(clock)): if clock[i].__class__.__name__ == "EscapeWheel": clock[i].speed = VITESSE_INITIAL
def fitness(clock): """ INPUT : A LIST OF CONNECTION OF A CLOCK OUTPUT: FITNESS SCORE OF THAT CLOCK This part gives score based on connections in a clock that appears in ConnectionData """ connection_list = gen.list_connections(clock) score = 0 for cn in connection_list: if (is_in_connectdata(cn)!=0): score += is_in_connectdata(cn) # EVALUATE THE CLOCK WHEN IT RUNS if (does_clock_run(connection_list)): initial_clock_runs(clock) # AWARD FOR RUNNING CLOCK score += 100.0 ; # CHECK FOR EACH CONNECTION OF RUNNING CLOCK for cn in connection_list: print("Tick Tock Tick Tock Tick Tock") x = [cn[0].__class__.__name__,cn[1].__class__.__name__,cn[2]] if ((x[0]=="Hand") and (x[1]=="Gear") and (x[2]==XY_CONNECTION)): # IF 2 GEARS CONNECT HORIZONTALLY THEN THE OTHER GEAR WILL SPIN gears_XY_connection(cn[0], cn[1]) if ((x[0]=="Hand") and (x[1]=="Gear") and (x[2]==Z_CONNECTION)) or ((x[1]=="Hand") and (x[0]=="Gear") and (x[2]==Z_CONNECTION)) or ((x[0]=="Gear") and (x[1]=="Gear") and (x[2]==Z_CONNECTION)): # IF A GEAR AND A HAND CONNECT VERTICALLY THAN THE HAND WILL SPIN objects_Z_connection(cn[0], cn[1]) if (cn[1] == gen.Hand): hand = cn[1] if (cn[0] == gen.Hand): hand = cn[0] """ EVALUATE CLOCK """ if (hand.speed < 1./30) and (hand.speed > 1./90): # IN THIS CASE THE HAND MAYBE THE SECOND HAND, A ROUND WILL TAKE BETWEEN 30s AND 90S SEC_SCORE = 1 - abs((abs(hand.speed) - VITESSE_SECONDHAND) / VITESSE_SECONDHAND) SCORE_HAND = SEC_SCORE elif (hand.speed < 1./1800) and (hand.speed > 1./5400): # IN THIS CASE THE HAND MAYBE THE MINUTE HAND, A ROUND WILL TAKE BETWEEN 1800s( 30 minutes) to 5400s (90 minutes). MIN_SCORE = 1 - abs((abs(hand.speed) - VITESSE_MINUTEHAND) / VITESSE_MINUTEHAND) SCORE_HAND = 60 * MIN_SCORE elif (hand.speed < 1./21600) and (hand.speed > 1./64800): # IN THIS CASE THE HAND MAYBE THE HOUR HAND, A ROUND WILL TAKE BETWEEN 21600S (12H) TO 64800(36H). HOU_SCORE = 1 - abs((abs(hand.speed) - VITESSE_HOURHAND) / VITESSE_HOURHAND) SCORE_HAND = 3600 * HOU_SCORE else : SCORE_HAND = 0 score += SCORE_HAND return round(score,3)
def display_clock(clock): connection_list = gen.list_connections(clock) for i in range(0,len(connection_list)): print (connection_list[i][0].__class__.__name__,connection_list[i][1].__class__.__name__,connection_list[i][2])
def fitness(clock): """ INPUT : A LIST OF CONNECTION OF A CLOCK OUTPUT: FITNESS SCORE OF THAT CLOCK This part gives score based on connections in a clock that appears in valid_connections """ connection_list = gen.list_connections(clock) groups = group_connections(clock) score = 0 # Each component reduces the fitness score score = score - (COMPONENT_COST * (len(clock) - 1)) # For each unique piece, give point only if it has one occurence in the watch for name in wanted_pieces: nb_of_this_piece = 0 for piece in clock[1:]: if piece.__class__.__name__ == name: nb_of_this_piece += 1 if nb_of_this_piece == wanted_pieces[name]: score += UNIQUE # For each valid connection, give points based on the connection value for cn in connection_list: score += is_in_connectdata(cn) # If a component owns three or more horizontal connexion, it blocks the whole system for piece_cn in groups: nb_xy_cn = 0 nb_z_cn = 0 for bloc in piece_cn: if bloc[2] == gen.XY_CONNECTION: nb_xy_cn += 1 elif bloc[2] == gen.Z_CONNECTION: nb_z_cn += 1 if nb_xy_cn <= 2: score += 1 else: score -= 100 ''' # EVALUATE THE CLOCK WHEN IT RUNS if (does_clock_run(connection_list)): initial_clock_runs(clock) # AWARD FOR RUNNING CLOCK score += 100.0 # CHECK FOR EACH CONNECTION OF RUNNING CLOCK for cn in connection_list: print("Tick Tock Tick Tock Tick Tock") x = [cn[0].__class__.__name__,cn[1].__class__.__name__,cn[2]] if ((x[0]=="Hand") and (x[1]=="Gear") and (x[2]==XY_CONNECTION)): # IF 2 GEARS CONNECT HORIZONTALLY THEN THE OTHER GEAR WILL SPIN gears_XY_connection(cn[0], cn[1]) if ((x[0]=="Hand") and (x[1]=="Gear") and (x[2]==Z_CONNECTION)) or ((x[1]=="Hand") and (x[0]=="Gear") and (x[2]==Z_CONNECTION)) or ((x[0]=="Gear") and (x[1]=="Gear") and (x[2]==Z_CONNECTION)): # IF A GEAR AND A HAND CONNECT VERTICALLY THAN THE HAND WILL SPIN objects_Z_connection(cn[0], cn[1]) if (cn[1] == gen.Hand): hand = cn[1] if (cn[0] == gen.Hand): hand = cn[0] """ EVALUATE CLOCK """ if (hand.speed < 1./30) and (hand.speed > 1./90): # IN THIS CASE THE HAND MAYBE THE SECOND HAND, A ROUND WILL TAKE BETWEEN 30s AND 90S SEC_SCORE = 1 - abs((abs(hand.speed) - VITESSE_SECONDHAND) / VITESSE_SECONDHAND) SCORE_HAND = SEC_SCORE elif (hand.speed < 1./1800) and (hand.speed > 1./5400): # IN THIS CASE THE HAND MAYBE THE MINUTE HAND, A ROUND WILL TAKE BETWEEN 1800s( 30 minutes) to 5400s (90 minutes). MIN_SCORE = 1 - abs((abs(hand.speed) - VITESSE_MINUTEHAND) / VITESSE_MINUTEHAND) SCORE_HAND = 60 * MIN_SCORE elif (hand.speed < 1./21600) and (hand.speed > 1./64800): # IN THIS CASE THE HAND MAYBE THE HOUR HAND, A ROUND WILL TAKE BETWEEN 21600S (12H) TO 64800(36H). HOU_SCORE = 1 - abs((abs(hand.speed) - VITESSE_HOURHAND) / VITESSE_HOURHAND) SCORE_HAND = 3600 * HOU_SCORE else : SCORE_HAND = 0 score += SCORE_HAND ''' return score
print(connection_list[i][0].__class__.__name__, connection_list[i][1].__class__.__name__, connection_list[i][2]) """ Test """ try: input_database() population = gen.generate(100, 3, 100) natural_selection(population) except KeyboardInterrupt: pass finally: best = best_clock(population) print("Best fitness : ", fitness(best)) for piece in gen.classes: counter = 0 for part in best[1:]: if isinstance(part, piece): counter += 1 print("Number of ", piece, " : ", counter) print("------ connections ------") print(gen.list_connections(best)) ''' for i in range(len(valid_connections)) : print(i, " : ", valid_connections[i].name, " -> ", valid_connections[i].point) print( " ",1 - abs((abs(1./60) - VITESSE_SECONDHAND) / VITESSE_SECONDHAND)) print( " ",1 - abs((abs(1/.60) - VITESSE_MINUTEHAND) / VITESSE_MINUTEHAND)) print( " ",1 - abs((abs(1./60) - VITESSE_HOURHAND) / VITESSE_HOURHAND)) '''