算法优化 - 并行AsyncTasks还是线程?

时间:2013-04-23 02:07:08

标签: java android algorithm image-comparison

我目前只有一个AsyncTask,目前使用OpenCV使用bubble sort技术比较图像。说,我必须将400图像相互比较。这意味着400*401/2=80,200比较。我们假设一次比较需要1秒钟。那么80,200 sec就是22.27 hours,这是非常长的。所以,我开发了这种类型的算法:

它将400图像划分为5组。因此每组中都有80张图片。

算法的第一部分是在小组成员中比较自己的图像。

因此,image1会将自己与image2-80进行比较,这意味着有79次比较。 image2将进行78次比较,等等。这使得3,160进行了比较。或3,160 sec。同样,image81会将自己与image82-160进行比较,依此类推。因此,所有“组比较”都在3,160 sec中完成,因为它们是并行运行的。

算法的第二部分将group 1元素与group 2元素进行比较,将group 2group 3group 3group 4进行比较,等等上。这意味着image1将与image81-160进行比较,这是80比较,因此group 1group 2之间的总比较将是80*80=6400比较。是否可以将每个图像与组比较并行比较?也就是说,如果image1将自己与image81-160进行比较,则image2应该执行相同的操作,依此类推,而其他组也在执行相同操作。因此,此部分应仅采用6400 sec

现在,group1将与group3group2group4group3group5进行比较。 - > 6400 sec

之后,group1 will be compared with group4group2group5。 - > 6400 sec

所以比较所有组。

总时间= 3160+6400+6400+6400=22,360sec。我意识到群体越多,花费的时间就越多。所以,我必须增加团队规模以减少时间的增加。无论哪种方式,它都会将时间减少到几乎1/4th的实际时间。

这个算法不现实吗?如果是这样,为什么?有什么缺点?我该如何解决?是否有更好的算法来更快地比较图像列表?显然不是quick sort,我无法按升序或降序排列图像。或者我可以吗?

如果可以使用此算法?实施它的最佳方法是什么? ThreadAsyncTask

1 个答案:

答案 0 :(得分:1)

这是一个现实的算法,但理想情况下,您希望能够在整个程序中使用相同数量的工作线程。为此,你需要使用偶数个线程,比如8。

在Pass1上,Thread1处理图像1-50,Thread2处理图像51-100等

在Pass2上,Thread1和Thread2都处理图像1-100。 Thread1处理图像1-25和50-75,Thread2处理图像26-50和图像76-100。然后,Thread1处理图像1-25和76-100,而Thread2处理图像26-75。

通过3到8遵循相同的模式 - 分配给正在处理的两个组的两个线程将它们之间的组拆分。这样你就可以保持所有线程的忙碌。但是,为了简化组分区,您需要偶数个线程。

4个帖子的示例代码

class ImageGroup {
    final int index1;
    final int index2;
}

class ImageComparer implements Runnable {
    final Image[] images;
    ImageGroup group1;
    ImageGroup group2;

    public ImageComparer(Image[] images, ImageGroup group1, ImageGroup group2) {
        ...
    }

    public void run() {
        if(group2 == null) { // Compare images within a single group
            for(int i = group1.index1; i < group1.index2; i++) {
                for(int j = i + 1; j < group1.inex2; j++) {
                    compare(images[i], images[j]);
                }
            }
        } else { // Compare images between two groups
            for(int i = group1.index1; i < group1.index2; i++) {
                for(int j = group2.index1; j < group2.index2; j++) {
                    compare(images[i], images[j]);
                }
            }
        }
    }
}

ExecutorService executor = new ThreadPoolExecutor(); // use a corePoolSize equal to the number of target threads
// for 4 threads we need 8 image groups
ImageGroup group1 = new ImageGroup(0, 50);
ImageGroup group2 = new ImageGroup(50, 100);
...
ImageGroup group8 = new ImageGroup(450, 500);

ImageComparer comparer1 = new ImageComparer(images, group1, null);
ImageComparer comparer2 = new ImageComparer(images, group3, null);
...
ImageComparer comparer4 = new ImageComparer(images, group7, null);

// submit comparers to executor service
Future future1 = executor.submit(comparer1);
Future future2 = executor.submit(comparer2);
Future future3 = executor.submit(comparer3);
Future future4 = executor.submit(comparer4);

// wait for threads to finish
future1.get();
future2.get();
future3.get();
future4.get();

comparer1 = new ImageComparer(images, group2, null);
...
comparer4 = new ImageComparer(images, group8, null);

// submit to executor, wait to finish

comparer1 = new ImageComparer(images, group1, group3);
...
comparer4 = new ImageComparer(images, group7, group6);

// submit to executor, wait to finish

comparer1 = new ImageComparer(images, group1, group4);
...
comparer4 = new ImageComparer(images, group7, group5);