Untitled

mail@pastecode.io avatarunknown
plain_text
2 months ago
4.1 kB
3
Indexable
Never
using System.Collections.Generic;
using UnityEngine;

public class KMeansClustering : MonoBehaviour
{
    // El número de clusters que deseamos obtener
    public int numClusters = 3;

    // La lista de puntos en el espacio tridimensional (X, Y, Z)
    public List<Vector3> points;

    // Lista para almacenar los centroides de los clusters
    private List<Vector3> centroids;

    // Lista para almacenar los puntos agrupados en cada cluster
    private List<List<Vector3>> clusters;

    private void Start()
    {
        // Inicializar los centroides de los clusters de manera aleatoria
        centroids = InitializeCentroids();

        // Ejecutar el algoritmo K-Means para agrupar los puntos
        clusters = KMeans();

        // Imprimir los resultados
        PrintClusters();
    }

    // Inicializar los centroides de los clusters de manera aleatoria
    private List<Vector3> InitializeCentroids()
    {
        List<Vector3> randomCentroids = new List<Vector3>();
        for (int i = 0; i < numClusters; i++)
        {
            Vector3 randomPoint = points[Random.Range(0, points.Count)];
            randomCentroids.Add(randomPoint);
        }
        return randomCentroids;
    }

    // Algoritmo K-Means
    private List<List<Vector3>> KMeans()
    {
        for (int iteration = 0; iteration < 100; iteration++) // Número máximo de iteraciones
        {
            // Asignar cada punto al cluster más cercano
            List<List<Vector3>> newClusters = new List<List<Vector3>>();
            for (int i = 0; i < numClusters; i++)
            {
                newClusters.Add(new List<Vector3>());
            }

            foreach (Vector3 point in points)
            {
                int closestClusterIndex = FindClosestCluster(point);
                newClusters[closestClusterIndex].Add(point);
            }

            // Calcular los nuevos centroides de los clusters
            for (int i = 0; i < numClusters; i++)
            {
                centroids[i] = CalculateCentroid(newClusters[i]);
            }

            // Comprobar si los centroides han cambiado
            bool centroidsChanged = false;
            for (int i = 0; i < numClusters; i++)
            {
                if (centroids[i] != CalculateCentroid(newClusters[i]))
                {
                    centroidsChanged = true;
                    break;
                }
            }

            // Si los centroides no han cambiado, terminar el algoritmo
            if (!centroidsChanged)
            {
                return newClusters;
            }
        }

        return null; // Si el algoritmo no converge, retornar null
    }

    // Encontrar el cluster más cercano a un punto dado
    private int FindClosestCluster(Vector3 point)
    {
        int closestClusterIndex = 0;
        float closestDistance = Vector3.Distance(point, centroids[0]);

        for (int i = 1; i < numClusters; i++)
        {
            float distance = Vector3.Distance(point, centroids[i]);
            if (distance < closestDistance)
            {
                closestClusterIndex = i;
                closestDistance = distance;
            }
        }

        return closestClusterIndex;
    }

    // Calcular el centroide de un cluster (promedio de los puntos en el cluster)
    private Vector3 CalculateCentroid(List<Vector3> cluster)
    {
        if (cluster.Count == 0)
        {
            return Vector3.zero;
        }

        Vector3 sum = Vector3.zero;
        foreach (Vector3 point in cluster)
        {
            sum += point;
        }

        return sum / cluster.Count;
    }

    // Imprimir los resultados (clusters y centroides) en la consola
    private void PrintClusters()
    {
        Debug.Log("Clusters:");
        for (int i = 0; i < numClusters; i++)
        {
            string clusterPoints = string.Join(", ", clusters[i]);
            Debug.Log("Cluster " + (i + 1) + ": " + clusterPoints);
            Debug.Log("Centroid " + (i + 1) + ": " + centroids[i]);
        }
    }
}