私は、互いの距離にx
基づいてブロブをクラスター化する非常に単純なアルゴリズムを持っています。スレッドローカルデータでy
使用するために同じものを移植しましたが、結果は正しくありませんでした。Parallel.For
つまり、同期を適切に使用して各スレッドを分離していなかった可能性があります。
2 つの実装の結果が異なる理由がまったくわかりません。任意の考えをいただければ幸いです。
完全にコンパイル可能なコードを投稿したかったのですが、使用されているオブジェクトがプロジェクトのコンテキストに緊密に統合されすぎています。アルゴリズムは非常に単純なので、邪魔にならないことを願っています。
クラス レベルの宣言:
/// <summary>
/// Contains the master blobl collection to be clustered.
/// </summary>
public List<Blob> Blobs { get; private set; }
/// <summary>
/// List of clusters to be computed.
/// </summary>
public List<Cluster> Clusters { get; private set; }
線形の例 (正常に動作) :
Cluster cluster = null;
for (int i = 0; i < this.Blobs.Count; i++)
{
cluster = new Cluster();
cluster.Id = i;
if (this.Blobs [i].ClusterId == 0)
{
cluster.Blobs.Add(this.Blobs [i], i);
for (int j = 0; j < this.Blobs.Count; j++)
{
if (this.Blobs [j].ClusterId == 0)
{
if (this.Blobs [i].Rectangle.IntersectsWith(this.Blobs [j].Rectangle))
{
cluster.Blobs.Add(this.Blobs [j], i);
}
else if (this.Blobs [i].Rectangle.IsCloseTo(this.Blobs [j].Rectangle, distanceThreshold))
{
cluster.Blobs.Add(this.Blobs [j], i);
}
}
}
}
if (cluster.Blobs.Count > 2)
{
this.Clusters.Add(cluster);
}
}
パラレル ポート (不適切なクラスター) :
System.Threading.Tasks.Parallel.For<Cluster>
(
0,
this.Blobs.Count,
new ParallelOptions() { MaxDegreeOfParallelism = degreeOfParallelism },
() => new Cluster(),
(i, loop, cluster) =>
{
cluster.Id = i;
if (this.Blobs [i].ClusterId == 0)
{
cluster.Blobs.Add(this.Blobs [i], i);
for (int j = 0; j < this.Blobs.Count; j++)
{
if (this.Blobs [j].ClusterId == 0)
{
if (this.Blobs [i].Rectangle.IntersectsWith(this.Blobs [j].Rectangle))
{
cluster.Blobs.Add(this.Blobs [j], i);
}
else if (this.Blobs [i].Rectangle.IsCloseTo(this.Blobs [j].Rectangle, distanceThreshold))
{
cluster.Blobs.Add(this.Blobs [j], i);
}
}
}
}
return (cluster);
},
(cluster) =>
{
lock (this.Clusters)
{
if (cluster.Blobs.Count > 2)
{
this.Clusters.Add(cluster);
}
}
}
);