You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel.NN/Models/Cluster.cs

134 lines
4.3 KiB

namespace ZeroLevel.NN.Models
{
public class Cluster<T>
{
private int _key;
private readonly List<T> _points = new List<T>();
public T this[int index] => _points[index];
public IReadOnlyList<T> Points => _points;
public int Key { get { return _key; } set { _key = value; } }
public Cluster()
{
}
public Cluster(T point)
{
_points.Add(point);
}
public Cluster(IEnumerable<T> points)
{
_points.AddRange(points);
}
public void Add(T point)
{
_points.Add(point);
}
public void Remove(T point)
{
_points.Remove(point);
}
/*
public bool IsNeighbor(T feature,
Func<T, float[]> embeddingFunction,
Func<float[], float[], double> similarityFunction,
float threshold,
float clusterThreshold)
{
if (_points.Count == 0) return true;
if (_points.Count == 1)
{
var similarity = similarityFunction(embeddingFunction(feature), embeddingFunction(_points[0]));
return similarity >= threshold;
}
var clusterNearestElementsCount = 0;
foreach (var f in _points)
{
var similarity = similarityFunction(embeddingFunction(feature), embeddingFunction(f));
if (similarity >= threshold)
{
clusterNearestElementsCount++;
}
}
var clusterToFaceScore = (float)clusterNearestElementsCount / (float)_points.Count;
return clusterToFaceScore > clusterThreshold;
}
*/
public bool IsNearest(T feature,
Func<T, T, double> distanceFunction,
double maxDistance)
{
if (_points.Count == 0) return true;
if (_points.Count == 1)
{
var distance = distanceFunction(feature, _points[0]);
return distance <= maxDistance;
}
foreach (var f in _points)
{
var distance = distanceFunction(feature, f);
if (distance > maxDistance)
{
return false;
}
}
return true;
}
public double MinimalDistance(T feature,
Func<T, T, double> distanceFunction)
{
if (_points.Count == 0) return int.MaxValue;
var min = distanceFunction(feature, _points[0]);
if (_points.Count == 1)
{
return min;
}
for (int i = 0; i<_points.Count; i++)
{
var distance = distanceFunction(feature, _points[i]);
if (distance < min)
{
min = distance;
}
}
return min;
}
/*
public bool IsNeighborCluster(Cluster<T> cluster,
Func<T, float[]> embeddingFunction,
Func<float[], float[], double> similarityFunction,
float threshold,
float clusterThreshold)
{
if (_points.Count == 0) return true;
if (_points.Count == 1 && cluster.IsNeighbor(_points[0], embeddingFunction, similarityFunction, threshold, clusterThreshold))
{
return true;
}
var clusterNearestElementsCount = 0;
foreach (var f in _points)
{
if (cluster.IsNeighbor(f, embeddingFunction, similarityFunction, threshold, clusterThreshold))
{
clusterNearestElementsCount++;
}
}
var localCount = _points.Count;
var remoteCount = cluster._points.Count;
var localIntersection = (float)clusterNearestElementsCount / (float)localCount;
var remoteIntersection = (float)clusterNearestElementsCount / (float)remoteCount;
var score = Math.Max(localIntersection, remoteIntersection);
return score > clusterThreshold;
}
*/
public void Merge(Cluster<T> other)
{
this._points.AddRange(other.Points);
}
}
}

Powered by TurnKey Linux.