def hill_climbing(quaternions, bindings, mediana, points, rot_points, variancia, av): print "\nHill climbing" #vamos sempre trabalhar com os quaternioes antigos, e guardar nas estrutras novas! new_set_quat = np.copy(quaternions) new_rot_points = np.copy(rot_points) medStart = np.copy(mediana) # Rever o valor to_much = 2 it = 0 accepted = 0 var = np.copy(variancia) start_time = time.time() while (it < number_it): for n_q in range(0, bindings.shape[0]): quat_mediana = bindings[n_q, 1, 0] if (quat_mediana < mediana): # arranjar randons randoms = np.random.uniform(-1, 1, (number_of_randoms, 4)) # temos de mexer pouco nos quaternioes, por isso temos de somar valores baixos randoms = np.divide(randoms, value_to_divide) # alterar os valores pelo numeros random # nesta posição bindings[n_q,0,0] está o numero do quaternião que está mais proximo news_quats = np.sum((randoms, quaternions[int(bindings[n_q, 0, 0])])) # mexemos nos quaterniões, temos de normalizalos news_quats = qt.normalize_quat(news_quats) new_points = qt.rotate_points(points, news_quats) dist = qt.point_dists_mine(rot_points[n_q], new_points) d = 0 for iz in range(len(dist)): if (dist[iz] > quat_mediana) and ( dist[iz] < (mediana + to_much)) and (dist[iz] > d): #guardar os novos pontos new_rot_points[int(bindings[n_q, 0, 0])] = new_points[iz] # guardar o novo quaterniao new_set_quat[int(bindings[n_q, 0, 0])] = news_quats[iz] d = dist[iz] # não se guarda a nova distancia pois ela não será usada outra vez # isto é, não se sabe como a mudança de um quat afetou o resto da distribuição if stop_at_first == 1: break mins, bindings2 = qt.evaluate(new_rot_points) var_old = np.copy(var) varTemp = np.var(mins) me = np.median(mins) it = it + 1 if ((varTemp - var_old) < 0.): rot_points = np.copy(new_rot_points) quaternions = np.copy(new_set_quat) var = np.copy(varTemp) accepted = accepted + 1 bindings = np.copy(bindings2) mediana = np.copy(me) else: var = np.copy(var_old) mins = qt.evaluate_no_bindings(rot_points) mediana2, av2, var2 = qt.draw_kde( mins, 'distribution_new_' + str(quaternions.shape[0]) + '.png', 0.75) print "Variancia antiga: ", variancia, " Variancia nova: ", var2, " diferença: ", var2 - variancia print "Mediana antiga: ", medStart, " Nova mediana: ", mediana2 print "Media antiga: ", av, " Nova media: ", av2 #print "numero de aceitações: ", accepted print "elapsed:", time.time() - start_time return var2 - variancia, accepted, quaternions
def hill_climbing(quaternions, bindings, mediana, points, rot_points, variancia, av): print "\nHill climbing greedy" #vamos sempre trabalhar com os quaternioes antigos, e guardar nas estrutras novas! #new_set_quat = np.copy(quaternions) new_rot_points = np.copy(rot_points) mvar = 0 # Rever o valor to_much = 2 it = 0 accepted = 0 var = np.copy(variancia) start_time = time.time() while (it < number_it): for n_q in range(0, bindings.shape[0]): quat_mediana = bindings[n_q, 1, 0] if (quat_mediana < mediana): # arranjar randons randoms = np.random.uniform(-1, 1, (number_of_randoms, 4)) # temos de mexer pouco nos quaternioes, por isso temos de somar valores baixos randoms = np.divide(randoms, value_to_divide) # alterar os valores pelo numeros random # nesta posição bindings[n_q,0,0] está o numero do quaternião que está mais proximo news_quats = np.sum((randoms, quaternions[int(bindings[n_q, 0, 0])])) # mexemos nos quaterniões, temos de normalizalos news_quats = qt.normalize_quat(news_quats) new_points = qt.rotate_points(points, news_quats) dist = qt.point_dists_mine(rot_points[n_q], new_points) point_new = 0 new_quat = 0 d = 0 for iz in range(len(dist)): if (dist[iz] > quat_mediana) and (dist[iz] < (mediana + to_much) and (dist[iz] > d)): #guardar os novos pontos point_new = new_points[iz] # guardar o novo quaterniao new_quat = news_quats[iz] d = dist[iz] if stop_at_first == 1: break new_rot_points[int(bindings[n_q, 0, 0])] = point_new # vamos verificar se este movimento teve influencia no sistema # ou seja, calcular de novo as distancias, os bindings e mudar o quaternião usado mins, bindings2 = qt.evaluate(new_rot_points) var_old = np.copy(var) varTemp = np.var(mins) me = np.median(mins) it = it + 1 if ((varTemp - var_old) < 0.): #print 'new solution' #print "Variancia antiga: ", var_old, " Variancia nova: ", varTemp, " diferença: ", varTemp-var_old #não é preciso copiar tudo, só o que mudou rot_points[int(bindings[n_q, 0, 0])] = point_new quaternions[int(bindings[n_q, 0, 0])] = new_quat var = np.copy(varTemp) accepted = accepted + 1 bindings[n_q] = bindings2[n_q] mediana = np.copy(me) if times == 0: mvar = varTemp - var_old else: mvar = ((varTemp - var_old) + mvar) / 2 else: var = np.copy(var_old) mins = qt.evaluate_no_bindings(rot_points) mediana2, av2, var2 = qt.draw_kde( mins, 'distribution_new_' + str(quaternions.shape[0]) + '_hill_greedy.png', 0.75) print "Variancia antiga: ", variancia, " Variancia nova: ", var2, " diferença: ", var2 - variancia #print "numero de aceitações: ", accepted print "elapsed:", time.time() - start_time print "media das mudanças: ", mvar return var2 - variancia, accepted
#para o hill climbing value_to_divide = 1000 number_of_randoms = 100 number_it = 10 stop_at_first = 0 #print points vdg = 0 acg = 0 start_time_global = time.time() for times in range(0, 3): start_time = time.time() quats, rots = qt.spread_quaternions(points, number_of_quat, quaternions_per_set) print "elapsed:", time.time() - start_time start_time = time.time() mins, bindings = qt.evaluate(rots) print "elapsed eval:", time.time() - start_time mediana, av, var = qt.draw_kde( mins, 'distribution_' + str(number_of_quat) + '.png') print "Mediana: ", mediana print "Media: ", av print "Variancia: ", var vd, a, quat_new = hill_climbing(quats, bindings, mediana, points, rots, var, av) if times == 0: vdg = vd acg = a
def hill_climbing(quaternions, bindings, mediana, points, rot_points, variancia, av): print "\nHill climbing with memory" #vamos sempre trabalhar com os quaternioes antigos, e guardar nas estrutras novas! new_set_quat = np.copy(quaternions) new_rot_points = np.copy(rot_points) # REVER ESTE VALOR! to_much = 2 it = 0 accepted = 0 var = np.copy(variancia) start_time = time.time() while (it < number_it): already_moved = np.zeros(quaternions.shape[0]) for n_q in range(0, bindings.shape[0]): # só queremos alterar alqueles que estão muito proximos quat_mediana = bindings[n_q, 1, 0] #print mediana if ((quat_mediana < mediana) & (already_moved[int(bindings[n_q, 0, 0])] == 0)): # arranjar randons randoms = np.random.uniform(-1, 1, (number_of_randoms, 4)) # temos de mexer pouco nos quaternioes, por isso temos de somar valores baixos randoms = np.divide(randoms, value_to_divide) # alterar os valores pelo numeros random # nesta posição bindings[n_q,0,0] está o numero do quaternião que está mais proximo news_quats = np.sum((randoms, quaternions[int(bindings[n_q, 0, 0])])) # mexemos nos quaterniões, temos de normalizalos news_quats = qt.normalize_quat(news_quats) new_points = qt.rotate_points(points, news_quats) dist = qt.point_dists_mine(rot_points[n_q], new_points) d = 0 for iz in range(len(dist)): if (dist[iz] > quat_mediana) and ( dist[iz] < (mediana + to_much)) and (dist[iz] > d): #guardar os novos pontos new_rot_points[int(bindings[n_q, 0, 0])] = new_points[iz] #guardar o novo quaterniao new_set_quat[int(bindings[n_q, 0, 0])] = news_quats[iz] d = dist[iz] if stop_at_first == 1: break already_moved[int(bindings[n_q, 0, 0])] = 1 mins, bindings2 = qt.evaluate(new_rot_points) var_old = np.copy(var) varTemp = np.var(mins) me = np.median(mins) it = it + 1 if ((varTemp - var_old) < 0.): rot_points = np.copy(new_rot_points) quaternions = np.copy(new_set_quat) var = np.copy(varTemp) accepted = accepted + 1 bindings = np.copy(bindings2) mediana = np.copy(me) else: var = np.copy(var_old) mins = qt.evaluate_no_bindings(rot_points) mediana2, av2, var2 = qt.draw_kde( mins, 'distribution_new_' + str(quaternions.shape[0]) + '_hill_memory.png', 0.75) print "Variancia antiga: ", variancia, " Variancia nova: ", var2, " diferença: ", var2 - variancia print "numero de aceitações: ", accepted print "elapsed:", time.time() - start_time return var2 - variancia, accepted