wenn ich aus Speicherbedarf und Performance Gründen bei Records bleiben möchte bzw. auch muss
...
gibt es keine Option meine Klassse generisch zu lassen (dh. ohne Informationen über die Art der Daten die ich verarbeite) und das Feld FRawData: TArray<T>; mit Daten über eine Klassenfunktion zu befüllen ?
Delphi-Quellcode:
TKMeans<T> = class
private
private
FClusteredData: TClusterList<T>;
FRawData: TArray<T>;
FNumClusters: Integer;
FDistanceMetric: TDistanceMetricfunction<T>;
FCentroidfct: TCentroidfunction<T>;
FMaxIterations: Integer;
public
constructor Create(NumClusters: Integer;
DistanceMetric: TDistanceMetricfunction<T>;
Centroidfct: TCentroidfunction<T>; MaxIterations: Integer = 10);
procedure LoadData(SoureBitMap: TBitmap); overload;
function FindNewClusterCentroids: Boolean;
procedure GroupData2NearestCluster;
procedure SaveData(OutBitMap: TBitmap);
end;
Der Code um zu Klasse zu verwenden sieht aktuell so aus:
Delphi-Quellcode:
function DistanceMetric(const A, B: TClusterDataREC): Double;
begin
Result := Sqrt(Sqr(A.x - B.x) + Sqr(A.y - B.y));
end;
// Define a centroid function that returns the TClusterData3 object with the average coordinates of all elements in the cluster
function Centroidfct(const A: TClusterDataREC): Cardinal;
begin
Result := Round((A.DrawingColor and $FF) + ((A.DrawingColor shr 8) and $FF)
+ ((A.DrawingColor shr 16) and $FF)) div 3;
end;
procedure TForm1.CornerButton1Click(Sender: TObject);
var
MyKMeans: TKMeans<TClusterDataREC>;
begin
MyKMeans := TKMeans<TClusterDataREC>.Create(5, DistanceMetric,
Centroidfct, 10);
try
/// hoer kommt dann noch was ...
finally
MyKMeans.Free;
end;
end;
Müsste ich die Loaddata Funktion der Klasse procedure
TKMeans<T>.LoadData(SoureBitMap: TBitmap);
auch als Parameter an die create Funktion meiner Klasse übergeben ? Wie würdet Ihr dies Implementieren , was ist hier ein besserer Ansatz ?
ach ja , Loaddata kann natürlich wieder von allen möglichen Daten laden müssen ( Bitmaps,
csv - Files, Datenbanken, ......)