Random graphs connected - python

I have a random graph and I want to check if in this graph the nodes are connected and show which are the strongly connected items, if any
#grafo 1
grafo1=erdosRenyi(5,0.7)
def not_in(x,y):
#RODA VETOR X SOBRE Y
for i in x:
#VERIFICA SE CADA ITEM DE X ESTA EM Y, SE ESTIVE, REMOVE DO Y
if i in y:
y.remove(i)
#RETORNA SO OS ELEMENTOS RESTANTES DE Y
return y
#VETOR TOTAL DE COMPONENTES | NOS VISITADOS | TOTAL TEMPORARIO
tc = []; visitado = []; tot =0;
#EXECUTA SOBRE TODOS OS NOS
for no in grafo1:
#ADICIONA NO ATUAL AOS VISITADOS
visitado.append(no)
print('BUSCANDO PELOS VERTICES DE ', no)
#ADICIONA AO TOTAL TEMPORARIO DE NOS DO COMPONENTE
tot=tot+1
# VERIFICA SE O NO FOI VISITADO E SE ELE NAO POSSUI NOVOS ELEMENTOS PARA SEREM VISITADOS
if no in visitado and len(not_in(visitado, list(grafo1[no]))) == 0:
#CASO POSITIVO, FINALIZA O COMPONENTE
#ADICIONA UM COMPONENTE NOVO COMPONENTE AO VETOR DE COMPONENTES COMO O SEU TOTAL DE NOS
tc = tc+[tot]
#ZERA A VARIAVEL TEMPORARIA DE NOS
tot=0
print("NOVO COMPONENTE\n")
print('\nTOTAL DE COMPONENTES ',len(tc))
print('MAIOR COMPONENTE CONEXO ', max(tc))
print('TAMANHO DE TODOS OS COMPONENTES ', tc)

Related

Iterative solution of Laplace's equation

I made this code in matlab, but now I want to pass it to Python. Is there a method or supporting documentation for this?
clear all;
close all;
% Dimensiones de la regi?n (mts)
length_x=50;
length_y=length_x;
h=1; % Dimension de la celda de Finite difference
% N?mero de nodos en x y y
nnx=length_x/h; % Numero de nodos de malla de celdas en eje x
nny=nnx; % Numero de nodos de malla de celdas en eje y
%
V=zeros(nnx);
for j=1:nnx
V(nnx,j)=1000;
end
% V(nnx,1)=50;
% V(nnx,nnx)=50;
err=1; % Valor inicial del error para prueba de convergencia de m?todo
cont=0; % Contador de iteraciones
epsilon=1e-5; % Criterio de convergencia.
while err > 0.0
for i=2:nnx-1
for j=2:nnx-1
V(i,j)=(V(i,j-1)+V(i-1,j)+V(i,j+1)+V(i+1,j))/4;
end
end
% Prueba de convergencia
for i=2:nnx-1
for j=2:nnx-1
C=(V(i,j-1)+V(i-1,j)+V(i,j+1)+V(i+1,j))/4;
B(i,j)=V(i,j)-C;
err=(abs(B(i,j))-epsilon);
if err > 0
break
end
end
if err > 0
break
end
end
cont=cont+1;
err;
end
% Postprocesamiento de resultados
[X,Y] = meshgrid(h:h:length_x,h:h:length_y);
% Malla con elementos FD
figure(1)
mesh(X,Y,zeros(nnx));
az = 0;
el = 90;
view(az, el);
% Grafica de superficie
figure(2);
% Magnitud de V
surf(X,Y,V)
colorbar
% Grafica de contorno
figure(3);
% Contorno de V
contourf(X,Y,V,20);
colorbar;
figure(4);
% Contornos con valores de V
[C,h] = contour(X,Y,V);
clabel(C,h)
% C?lculo de la intensidad del campo el?ctrico
figure(5);
%Campo Vectorial E y campo escalar V
[Ex,Ey]=gradient(V);
quiver(X,Y,-Ex,-Ey);
hold on;
contour(X,Y,V,10);
% Densidad del campo el?ctrico
e0=8.8541878176*10^-12; % Permitividad el?ctrica del vacio
er=3; % Permitividad relativa de papel
figure(6);
%Campo Vectorial D y campo escalar V
em=e0*er;
Dx=-em*Ex;
Dy=-em*Ey;
quiver(X,Y,Dx,Dy);
hold on;
contour(X,Y,V,10);
This are the graphics that MATLAB is generating:
enter image description here
I tried to do the Figure 1 with some videos that I saw, but I don't know if it is the correct methodenter image description here

Pickle not saving in to file

So, i'm coding an discord bot for playing rpg with my friends, and i writed something about 1,3k lines, using pickle and some other librarys, and until my last function it's worked very well, but in this " Atualizar_inventario()" the pickle just dont' save my list " ITEM " in my " Abrir_Para_Escrita", and i dont have any ideia why.
def Autualizar_inventario():
# Booleano para quebrar o looping quando quisermos sair
Sair = False
# Variavel que vai receber nome para comparação
Nome = input("Qual inventario você deseja atualizar?")
print(Nome)
#Abrir arquivo para leitura
Abrir_Inv = open(f"Inventario/{Nome}.pickle", "rb")
Ler_Inv = pickle.load(Abrir_Inv)
# Lista que vai receber os itens que vamos adicionar depois
Item = [Ler_Inv]
# Sender_ID vai servir para só o dono do inventario poder alteralo
Sender_ID = "Jorge" # Yamo altera essa string pra um comando que recebe o ID do usuario
# Se o sender ID for o mesmo que o primeiro parametro " QUE NO CASO SERA O ID"
# if vai ser ativado, nos botando em um looping onde adicionaremos os itens
if Sender_ID == Ler_Inv[0] : # or Sender_ID == "350364616657862679" < -- Codigo para reconhecer o meu discord
while Sair == False:
Input_Item = input("Escreva o nome do item")
# Comando para sair do inventario
if Input_Item == "sair" or Input_Item == "Sair" or Input_Item == "SAIR":
break
# Se sair não for ativado começam as etapas de salvar os novos itens no inventario
else :
# Adiciona o item digitado pelo usuario na lista " ITEM "
Item.append(Input_Item)
# Mostra os parametros // serve apenas para configuração
print("printando item = ", Item)
Abrir_Para_Escrita = open(f"Inventario/{Nome}.pickle", 'wb')
pickle.dump(Item, Abrir_Para_Escrita)
Abrir_Para_Escrita.close()
print("printando arquivo ", Ler_Inv)

How can I get the exact result of 10**20 + 10**-20 in Python? It gives me 1e+20

I am writing a code to solve second-grade equations and it works just well.
However, when I input the following equation:
x^2 + (10^(20) + 10^(-20)) + 1 = 0
(Yes, my input is 10**20 + 10**(-20)
I get:
x1 = 0 x2 = -1e+20
However, it is taking (10^(20) + 10^(-20) as 10e+20 while, if you do the math:
Here is the LaTeX formatted formula:
Which is almost 10^20 but not 10^20.
How can I get the exact result of that operation so I can get the exact value of the equation in x2?
My code is the following:
#===============================Función para obtener los coeficientes===============================
#Se van a anidar dos funciones. Primero la de coeficientes, luego la de la solución de la ecuación.
#Se define una función recursiva para obtener los coeficientes de la ecuación del usuario
def cof():
#Se determina si el coeficiente a introducir es un número o una cadena de operaciones
op = input("Si tu coeficiente es un número introduce 1, si es una cadena de operaciones introduce 2")
#Se compara la entrada del usuario con la opción.
if op == str(1):
#Se le solicita el número
num = input("¿Cuál es tu número?")
#Se comprueba que efectívamente sea un número
try:
#Si la entrada se puede convertir a flotante
float(num)
#Se establece el coeficiente como el valor flotante de la entrada
coef = float(num)
#Se retorna el valor del coeficiente
return coef
#Si no se pudo convertir a flotante...
except ValueError:
#Se le informa al usuario del error
print("No introdujiste un número. Inténtalo de nuevo")
#Se llama a la función de nuevo
return cofa()
#Si el coeficiente es una cadena (como en 10**20 + 10**-20)
elif op == str(2):
#La entrada se establece como la entrada del usuario
entrada = input("Input")
#Se intenta...
try:
#Evaluar la entrada. Si se puede...
eval(entrada)
#El coeficiente se establece como la evaluación de la entrada
coef = eval(entrada)
#Se regresa el coeficiente
return coef
#Si no se pudo establecer como tal...
except:
#Se le informa al usuario
print("No introdujiste una cadena de operaciones válida. Inténtalo de nuevo")
#Se llama a la función de nuevo
return cofa()
#Si no se introdujo ni 1 ni 2 se le informa al usuario
else:
#Se imprime el mensaje
print("No introdujiste n ni c, inténtalo de nuevo")
#Se llama a la función de nuevo
return cof()
#===============================Función para resolver la ecuación===============================
#Resuelve la ecuación
def sol_cuadratica():
#Se pide el valor de a
print("Introduce el coeficiente para a")
#Se llama a cof y se guarda el valor para a
a = cof()
#Se pide b
print("Introduce el coeficiente para b")
#Se llama cof y se guarda b
b = cof()
#Se pide c
print("Introduce el coeficiente para c")
#Se llama cof y se guarda c
c = cof()
#Se le informa al usuario de la ecuación a resolver
print("Vamos a encontrar las raices de la ecuación {}x² + {}x + {} = 0".format(a, b, c))
#Se analiza el discriminante
discriminante = (b**2 - 4*a*c)
#Si el discriminante es menor que cero, las raices son complejas
if discriminante < 0:
#Se le informa al usuario
print("Las raices son imaginarias. Prueba con otros coeficientes.")
#Se llama a la función de nuevo
return sol_cuadratica()
#Si el discriminante es 0, o mayor que cero, se procede a resolver
else:
#Ecuación para x1
x1 = (-b + discriminante**(1/2))/(2*a)
#Ecuación para x2
x2 = (-b - discriminante**(1/2))/(2*a)
#Se imprimen los resultados
print("X1 = " + str(x1))
print("X2 = " + str(x2))
sol_cuadratica()
Ignore the comments, I'm from a Spanish-speaking country.
The limitations of the machine floating point type is the reason why when adding a very small number to a very big number, the small number is just ignored.
This phenomenon is called absorption or cancellation.
With custom floating point objects (like the ones decimal module) you can achieve any precision (computations are slower, because floating point is now emulated, and not relying on the machine FPU capabilities anymore)
From the decimal module docs:
Unlike hardware based binary floating point, the decimal module has a user alterable precision (defaulting to 28 places) which can be as large as needed for a given problem
This can be achieved by changing the following global parameter decimal.getcontext().prec
import decimal
decimal.getcontext().prec = 41 # min value for the required range
d = decimal.Decimal(10**20)
d2 = decimal.Decimal(10**-20)
now
>>> d+d2
Decimal('100000000000000000000.00000000000000000001')
As suggested in comments, for the small number it's safer to let decimal module handle the division by using power operator on an already existing Decimal object (even if here, the result is the same):
d2 = decimal.Decimal(10)**-20
So you can use decimal.Decimal objects for your computations instead of native floats.

Error: float() argument must be a string or a number, not 'dict_keys'

Hello I always get the error "Error: float() argument must be a string or a number, not 'dict_keys'" when running this code. I thought i ran it before without any problem but it seems like now it does not work anymore. Is that possible? And if so, what can I do to get it working again? My problem is within the very last part where I want to graph the time it took to do calculations. But I guess maybe one of the earlier variables isnt defined correctly or something? Appreaciate your help!
Thank you!
from sklearn.linear_model import LinearRegression
import numpy as np
from datetime import datetime
import pandas as pd
import matplotlib.pyplot as plt #biblioteca de gráficos a partir de listas o arreglos
import time
import threading #para hacer subprocesos
import gc #gc.collect va borrando lo de la memoria
#Definicion de filas y columnas (Parte de arriba)
np.random.seed(42)
n_rows = 100 #número fijo de filas
cols_min = 100 #comienzo numero de columnas
cols_max = 12_800 #máximo de columnas para que salga del loop
timeout = 90 # segundos maximos para correr la iteracion, se puede ir modificando para testeo
#Generaremos funciones para ir llamando
def mult_range(start, end): #Finalidad es que irá duplicando las columnas
val = start
while val <= end:
yield val
val *= 2
#gen_dataset irá generando un conjunto de datos, partiendo de 100 columnas que son las fijadas en la parte de arriba
#la gracia es tener por separado x e y para luego hacer en una linea los gráficos
def gen_dataset(n_rows, n_cols):
y = np.random.rand(n_rows) #crea la matriz y la rellena con el valor de n_rows // las n filas
x = np.random.rand(n_rows, n_cols) #para la matriz n filas m columnas
return x, y
#cromometrará el tiempo de cálculo
def timeit(timeout, n_cols, result, fn, *args, **kwargs):
try:# función que puede llegar a levantar una excepción
#link: para info https://uniwebsidad.com/libros/algoritmos-python/capitulo-12/excepciones
t1 = datetime.now() #valor actual
fn(*args, **kwargs)
t2 = datetime.now() #valor nuevo
delta = t2 - t1 #diferencia
delta_microsecs = delta.seconds * 1_000_000 + delta.microseconds #tiempo que tardará la ejecución
if (delta_microsecs / 1_000_000) < (timeout + 500_000): #condición para que imprima lo que tarda
#irá imprimiendo instantaneamente en la pantalla para saber el tiempo que tarda por cantidad
print(f"for {n_cols} columns it took {delta_microsecs / 1_000_000} seconds")
#imprime para n columnas tarda delta_microsecs de tiempo
result[n_cols] = delta_microsecs #
#else:
# print(f"for {n_cols} columns it took {delta_microsecs / 1_000_000} seconds")
except MemoryError: #cuando se genera la excepción
#en caso de que utilice muchos recursos del pc
print(f"data doesn't fit in memory for {n_cols} columns")
#regresion con sklearn para las x e y
def sklearn_reg(x, y):
reg = LinearRegression()
reg.fit(x, y) #toma los valor x e y ya definidos
#regresion con numpy para las x e y
def np_reg(x, y): #toma los valor x e y ya definidos
# agregar columna de unos
x_ = np.hstack((np.ones((x.shape[0], 1)), x))
# estimador (x'x)^-1 * (x'y)
return np.matmul(np.linalg.inv(np.matmul(x_.T, x_)),np.matmul(x_.T, y))
#regresion con timeout segundos m columnas de inicio, m++ columnas finales
def time_reg(timeout, cols_min, cols_max, reg_fn, square=False): #square es para poner cuando sea X2
timing = {}
threads = []
for n_cols in mult_range(cols_min, cols_max):
try:
gc.collect()
x, y = gen_dataset(n_rows, n_cols)
if square:
x = np.square(x)
thread = threading.Thread(target=timeit, args=(timeout, n_cols, timing, reg_fn, x, y))
thread.start()
for i in range(timeout):
time.sleep(1)
if not thread.is_alive():
break
else:
print(f"for {n_cols} columns it took more than {timeout} seconds")
except MemoryError:
print(f"data doesn't fit in memory for {n_cols} columns")
return timing
def plot_time(timing):
fig = plt.figure(figsize=(10, 10))
plt.plot(timing.keys(), timing.values())
#plt.axis((0, 1_000_000, 0, 1_000_000))
plt.xlabel('time (μs)')
plt.ylabel('columns')
plt.show()
plot_time(time_reg(timeout, cols_min, cols_max, sklearn_reg))
#generar gráfico con el tiempo que demora según cantidad de columnas
plot_time(time_reg(timeout, cols_min, cols_max, np_reg))
#generar gráfico con el tiempo que demora según cantidad de columnas
``

Error when I try to iterate more than once

I've got this program which calculate k-means for IA
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from random import sample
from itertools import repeat
from math import sqrt
# Parametros
k = 6
maxit = 2
def leeValoracionesFiltradas (nomFichero = "valoracionesFiltradas.data"):
lineas = [(l.strip()).split("\t") for l in (open(nomFichero).readlines())]
diccio = {}
for l in lineas:
diccio[int(l[0])] = {}
for l in lineas:
diccio[int(l[0])][int(l[1])] = (float(l[2]),float(l[3]))
return diccio
def distEuclidea(dic1, dic2):
# Se calcula la suma de cuadrados de los elementos comunes a los dos diccionarios
sum2 = sum([pow(dic1[elem]-dic2[elem], 2)
for elem in dic1 if elem in dic2])
return sqrt(sum2)
def similitudEuclidea(dic1, dic2):
return 1/(1+distEuclidea(dic1, dic2))
def coefPearson(dic1, dic2):
# Se consiguen los elementos comunes en ambos diccionarios
comunes = [x for x in dic1 if x in dic2]
nComunes = float(len(comunes))
# Si no hay comunes -> cero
if nComunes==0:
return 0
# Calculo de las medias de cada diccionario
media1 = sum([dic1[x][1] for x in comunes]) / nComunes
media2 = sum([dic2[x][1] for x in comunes]) / nComunes
# Numerador y denominador
num = sum([(dic1[x][1] - media1) * (dic2[x][1] - media2) for x in comunes])
den1 = sqrt(sum([pow(dic1[x][1] - media1, 2) for x in comunes]))
den2 = sqrt(sum([pow(dic2[x][1] - media2, 2) for x in comunes]))
den = den1 * den2
# Caculo del coeficiente
if den==0:
return 0
return num/den
# Dado un diccionario {key1 : {key2 : valor}} calcula el agrupamiento k-means
# con k clusters (grupo), ejecutando maxit iteraciones, con la funcion de similitud especificada
# Retorna una tupla
# -{key1:numero de clusters} con las asignaciones de clusters (a que clusters pertenece cada elemento)
# -[{key2:valores}] una lista con los k centroides (media de los valores para cada clusters)
def kmeans (diccionario, k, maxit, similitud = coefPearson):
# K puntos aleatorios son elegidos como centroides incialmente
# Cada centroide es {key2 : valor}
centroides = [diccionario[x] for x in sample(diccionario.keys(), k)]
# Se asigna cada key1 a un numero de cluster
previo = None
asignacion = {}
# En cada iteracion se asignan puntos a los centroides y se calculan nuevos centroides
for it in range(maxit):
# Se asignan puntos a los centroides mas cercanos
for key1 in diccionario:
similitudes = map(similitud,repeat(diccionario[key1],k), centroides)
asignacion[key1] = similitudes.index(max(similitudes))
# Si no hay cambios en la asignacion, se termina
if previo == asignacion: break
previo = asignacion
# Se recalculan los centroides (se anotan los valores de cada key a cada centroide)
valores = {x : {} for x in range(k)}
contadores = {x : {} for x in range(k)}
for key1 in diccionario:
grupo = asignacion[key1]
for key2 in diccionario[key1]:
if not valores[grupo].has_key(key2):
valores [grupo][key2] = 0
contadores [grupo][key2] = 0
valores [grupo][key2] += diccionario[key1][key2][1]
contadores[grupo][key2] += 1
# Se calculan las medias (nuevos centroides)
centroides = []
for grupo in valores:
centro = {}
for key2 in valores[grupo]:
centro[key2] = round((valores[grupo][key2] / contadores[grupo][key2]),2)
centroides.append(centro)
if None in centroides: break
return (asignacion, centroides)
# Se obtiene el diccionario de valoraciones (las valoraciones ya han sido filtradas)
diccionario = leeValoracionesFiltradas()
# Se obtienen las asignaciones y los centroides con la correlacion de Pearson
tupla = kmeans (diccionario, k, maxit)
asignaciones = tupla[0]
centroids = tupla[1]
print asignaciones
print centroids
And when I execute this for example for maxit = 2, it throws:
File "kmeans_dictio.py", line 46, in coefPearson
media2 = sum([dic2[x][1] for x in comunes]) / nComunes
TypeError: 'float' object has no attribute '__getitem__'
How can I fix this?
It looks like you have a dictionary (dic2) of floats and a dictionary of dictionaries of floats (dic1) that you are pulling an item out of with this line:
comunes = [x for x in dic1 if x in dic2]
Then you are trying to iterate over this float here:
media2 = sum([dic2[x][1] for x in comunes]) / nComunes
To fix this look at dic1 and dic2 and how they are defined.

Categories