Untitled
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]); } } }