2012-06-20 17 views
5

Tôi đang cố gắng sử dụng Thrust để phát hiện xem mỗi phần tử của mảng có thể được tìm thấy trong mảng khác hay không (cả hai mảng được sắp xếp). Tôi đi qua các thói quen tìm kiếm vectơ (lower_bound và binary_search).Tìm kiếm vectơ lực đẩy: Kết hợp hiệu quả giữa phương thức lower_bound và binary_search để tìm cả vị trí và sự tồn tại

lower_bound sẽ trả về cho mỗi giá trị mà chỉ mục có thể được chèn vào danh sách để tuân theo thứ tự của nó.

Tôi cũng cần biết liệu giá trị có được tìm thấy hay không (có thể được thực hiện với binary_search), không chỉ vị trí của nó.

Có thể đạt được cả hai cách hiệu quả mà không cần thực hiện hai tìm kiếm (gọi binary_search và sau đó là lower_bound)?

Tôi biết trong trường hợp vô hướng, lower_bound sẽ trả về một con trỏ đến cuối mảng nếu không tìm thấy giá trị, nhưng điều này không xảy ra trong phiên bản vectơ.

Cảm ơn!

Trả lời

2

Bạn có thể kiểm tra xem phần tử có trả về là lower_bound giống với số bạn đã tìm kiếm hay không. Ví dụ. được cung cấp a = {1,3,5} và tìm kiếm b = {1,4}, kết quả sẽ là c = {0,2}. Chúng tôi có a[c[0]] == b[0], vì vậy b[0] nằm trong số a, nhưng a[c[1]] != b[1] vì vậy b[1] không có trong a.

(Lưu ý rằng bạn sẽ cần phải đảm bảo rằng bạn không thực hiện bất kỳ out-of-bounds bộ nhớ truy cập, vì lower_bound có thể trở lại một chỉ số đó là vượt quá cuối của mảng.)

0

@ tat0: bạn cũng có thể chơi xung quanh với Arrayfire: tìm kiếm vectorized sử dụng LOWER_BOUND() không cung cấp cho bạn câu trả lời ngay lập tức trong khi với setintersect() trong arrayfire, bạn sẽ có được "ngã tư" của hai mảng trực tiếp:

float A_host[] = {3,22,4,5,2,9,234,11,6,17,7,873,23,45,454}; 
int szA = sizeof(A_host)/sizeof(float); 

float B_host[] = {345,5,55,6,7,8,19,2,63}; 
int szB = sizeof(B_host)/sizeof(float); 

// initialize arrays from host data 
array A(szA, 1, A_host); 
array B(szB, 1, B_host); 

array U = setintersect(A, B); // compute intersection of 2 arrays 

int n_common = U.elements(); 
std::cout << "common: ";  
print(U); 

sự đầu ra là: phổ biến: U = 2,0000 5,0000 6,0000 7,0000

để có được những vị trí thực tế của các yếu tố trong mảng A, bạn có thể sử dụng xây dựng sau (với điều kiện các yếu tố A là duy nhất):

int n_common = U.elements(); 
array loc = zeros(n_common); // empty array  

gfor(array i, n_common) // parallel for loop 
    loc(i) = sum((A == U(i))*seq(szA)); 
print(loc); 

thì: loc = 4,0000 3,0000 8,0000 10,0000

Bên cạnh đó, lực đẩy :: LOWER_BOUND() có vẻ là chậm hơn so với setintersect(), i benchmarked nó với các chương trình sau đây:

int *g_data = 0; 
int g_N = 0; 

void thrust_test() { 
thrust::device_ptr<int> A = thrust::device_pointer_cast((int *)g_data), 
    B = thrust::device_pointer_cast((int *)g_data + g_N); 
thrust::device_vector<int> output(g_N); 
thrust::lower_bound(A, A + g_N, B, B + g_N, 
        output.begin(), 
        thrust::less<int>()); 
std::cout << "thrust: " << output.size() << "\n"; 
} 
void af_test() 
{ 
    array A(g_N, 1, g_data, afDevicePointer); 
    array B(g_N, 1, g_data + g_N, afDevicePointer); 
    array U = setintersect(A, B); 
    std::cout << "intersection sz: " << U.elements() << "\n"; 
} 
int main() 
{ 
    g_N = 3e6; // 3M entries 
    thrust::host_vector<int> input(g_N*2); 
    for(int i = 0; i < g_N*2; i++) { // generate some input 
    if(i & 1) 
     input[i] = (i*i) % 1131; 
    else 
     input[i] = (i*i*i-1) % 1223 ; 
} 
thrust::device_vector<int> dev_input = input; 
// sort the vector A 
thrust::sort(dev_input.begin(), dev_input.begin() + g_N); 
// sort the vector B 
thrust::sort(dev_input.begin() + g_N, dev_input.begin() + g_N*2); 
g_data = thrust::raw_pointer_cast(dev_input.data()); 
try { 
    info(); 
    printf("thrust: %.5f seconds\n", timeit(thrust_test)); 
    printf("af: %.5f seconds\n", timeit(af_test)); 
} catch (af::exception& e) { 
    fprintf(stderr, "%s\n", e.what()); 
} 
return 0; 
} 

và kết quả:

CUDA toolkit 4.2, tài xế 295,59

GPU0 GeForce GT 650m, 2048 MB, Tính toán 3.0 (đơn, đôi)

Memory Usage: 1937 MB (2048 MB tổng số)

lực đẩy: 0,13008 giây

arrayfire: 0,06702 giây

Các vấn đề liên quan