Untitled
unknown
plain_text
2 years ago
4.1 kB
8
Indexable
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]);
}
}
}
Editor is loading...