我正在嘗試優化聯合查找算法以查找映像中的連接組件。我的圖像可以是2d或3d文件,由0和1組成。我在這個線程中找到了一個實現:Connected Component Labelling,用戶Dukering給出了答案。聯盟查找的效率提高
我改編了我的目的代碼。代碼有效,但執行時間很快變得太大。我不明白這個問題。
我的代碼如下所示。我正在測試的文件鏈接如下:https://utexas.box.com/s/k12m17rg24fw1yh1p21hytxwq5q8959u 這是一個2223x2223大小的文件(在下面的程序中定義)。
正如原始用戶提到的,這是union-find的基本實現,並且可以使其更有效。我不明白如何。另外,我在Matlab中測試了這個圖像,並且Matlab速度更快。例如,上面鏈接的圖像在我的計算機上需要大約1.5分鐘,但Matlab使用bwlabel在一秒鐘內完成。我檢查了bwlabel使用的算法,它似乎是union-find的一些變體,這就是我首先開始這項工作的原因。如何讓我的代碼儘快運行?我還應該提到,我希望在更大的圖像上運行我的代碼(高達1000^3)。我目前的版本無法做到這一點。
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#define w 2223
#define h 2223
void writeArrayInt(int *data, int dims[], char *filename)
{
FILE *fp;
fp = fopen(filename,"w");
/* write grid dimensions */
fwrite(dims, sizeof(int), 3, fp);
/* write data array */
fwrite(data, sizeof(int), w*h, fp);
fclose(fp);
}
void readArrayInt(int *data, int dims[], char *filename)
{
FILE *fp;
fp = fopen(filename,"r");
/* read grid dimensions */
fread(dims, sizeof(int), 3, fp);
/* read data array */
fread(data, sizeof(int), w*h, fp);
fclose(fp);
}
void doUnion(int a, int b, int *component)
{
// get the root component of a and b, and set the one's parent to the other
while (component[a] != a)
a = component[a];
while (component[b] != b)
b = component[b];
component[b] = a;
}
void unionCoords(int x, int y, int x2, int y2, int *component, int *input)
{
int ind1 = x*h + y;
int ind2 = x2*h + y2;
if (y2 < h && x2 < w && input[ind1] && input[ind2] && y2 >= 0 && x2 >= 0)
doUnion(ind1, ind2, component);
}
int main()
{
int i, j;
int *input = (int *)malloc((w*h)*sizeof(int));
int *output = (int *)malloc((w*h)*sizeof(int));
int dims[3];
char fname[256];
sprintf(fname, "phi_w_bin");
readArrayInt(input, dims, fname);
int *component = (int *)malloc((w*h)*sizeof(int));
for (i = 0; i < w*h; i++)
component[i] = i;
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
{
unionCoords(x, y, x+1, y, component, input);
unionCoords(x, y, x, y+1, component, input);
unionCoords(x, y, x-1, y, component, input);
unionCoords(x, y, x, y-1, component, input);
unionCoords(x, y, x+1, y+1, component, input);
unionCoords(x, y, x-1, y+1, component, input);
unionCoords(x, y, x+1, y-1, component, input);
unionCoords(x, y, x-1, y-1, component, input);
}
for (int x = 0; x < w; x++)
{
for (int y = 0; y < h; y++)
{
int c = x*h + y;
if (input[c] == 0)
{
output[c] = input[c];
continue;
}
while (component[c] != c) c = component[c];
int c1 = x*h + y;
output[c1] = component[c];
}
}
sprintf(fname, "outputImage2d");
writeArrayInt(output, dims, fname);
free(input);
free(output);
free(component);
}
如果您的代碼正在工作,並且您希望提供有關如何改進其性能的建議,那麼[codereview.se]是此問題的更合適的位置。 – kaylum
請縮進您的代碼。如果您使用Tab鍵縮進,現在是時候去找到如何告訴您的IDE插入空格... – Lundin
您的縮進真的需要幫助:修復它可以幫助您獲得幫助。 – Richard