2010-07-18 37 views
8

Tôi có danh sách giá trị (1 chiều) và tôi muốn biết cấu trúc/thuật toán dữ liệu tốt nhất để tìm giá trị truy vấn gần nhất mà tôi có. Hầu hết các giải pháp (tất cả?) Tôi tìm thấy các câu hỏi ở đây dành cho 2 hoặc nhiều thứ nguyên. Ai có thể đề xuất với tôi cách tiếp cận cho trường hợp của tôi?Cấu trúc dữ liệu tốt nhất cho hàng xóm gần nhất trong 1 chiều

Bản năng của tôi cho tôi biết sắp xếp dữ liệu và sử dụng tìm kiếm nhị phân bằng cách nào đó. Bằng cách này, không có giới hạn về thời gian xây dựng hoặc chèn cho bất kỳ cây nào cần thiết, vì vậy có lẽ ai đó có thể đề xuất một cây tốt hơn so với chỉ đơn giản là một danh sách được sắp xếp.

+2

một BST kết hợp với tìm kiếm nhị phân có vẻ hoàn toàn phù hợp với tôi. –

Trả lời

9

Nếu bạn cần một cái gì đó nhanh hơn O (log (n)), bạn có thể dễ dàng tìm được với một mảng được sắp xếp hoặc tìm kiếm nhị phân cây, bạn có thể sử dụng van Emde Boas Tree. Cây vEB cung cấp cho bạn O (log (log (n))) để tìm kiếm phần tử gần nhất ở hai bên.

+7

So với một mảng được sắp xếp, một cây vEB là một con heo không gian phức tạp. Trừ khi các điểm là rất dày đặc, các hiệu ứng của hệ thống phân cấp bộ nhớ có khả năng quét sạch sự khác biệt lý thuyết giữa O (log n) và O (log log n) và sau đó một số. – user382751

+0

Điều đó thật ấn tượng. Tôi chấp nhận câu trả lời này như là một lý thuyết tốt nhất cho đến nay cho dữ liệu tuyến tính rất lớn. Mặc dù thực tế tôi sẽ sử dụng danh sách được sắp xếp/tìm kiếm nhị phân mà đủ cho mục đích của tôi. –

1

Sắp xếp danh sách và sử dụng tìm kiếm nhị phân để tìm phần tử bạn đang tìm kiếm, sau đó so sánh các hàng xóm bên trái và bên phải của bạn. Bạn có thể sử dụng một mảng là truy cập O (1).

Cái gì như:

int nearest(int[] list, int element) { 

    sort(list); 
    int idx = binarySearch(element, list); 

    // make sure you are accessing elements that exist 
    min = (element - list[idx-1] <= list[idx+1] - element) ? idx-1 : idx+1; 

    return list[min]; 
} 

này là O (n log n), mà sẽ được khấu hao theo nếu bạn đang đi để thực hiện nhiều cái nhìn up.

EDIT: Cho rằng bạn sẽ phải di chuyển các phân loại ra của phương pháp này

+0

Đầu tiên, tôi vẫn không thấy cách hàm min trả về đúng mục. Bạn thậm chí không so sánh với điểm truy vấn. Thứ hai, chi phí phân bổ dường như không cải thiện bất cứ điều gì ... bạn không nên sắp xếp danh sách khi thực hiện truy vấn. Bạn chỉ nên làm như vậy khi sửa đổi tập hợp các điểm. –

+0

@ Eyal-Schneider Cảm ơn – quantumSoup

+0

thực sự, nếu bạn di chuyển việc sắp xếp tìm kiếm nhị phân phải là O (log n) –

1

Như bạn đã đề cập, cách nhanh nhất và dễ nhất nên được phân loại dữ liệu và sau đó tìm kiếm bên trái và hàng xóm bên phải của một điểm dữ liệu.

2

Nếu thời gian chèn không liên quan, thì tìm kiếm nhị phân trên mảng được sắp xếp là cách đơn giản nhất để đạt được thời gian truy vấn O (log N). Mỗi lần một mục được thêm vào sắp xếp mọi thứ. Đối với mỗi truy vấn, thực hiện tìm kiếm nhị phân. Nếu tìm thấy một kết quả phù hợp, hãy trả lại. Nếu không, tìm kiếm nhị phân sẽ trả về chỉ mục của mục, nơi nó cần được chèn vào. Sử dụng chỉ mục này để kiểm tra hai mục lân cận và xác định mục nào trong số đó gần với điểm truy vấn.

Tôi cho rằng có các giải pháp với thời gian O (1). Tôi sẽ cố gắng nghĩ về điều không liên quan đến việc sử dụng quá nhiều bộ nhớ ...

+0

Điều đó sẽ rất thú vị. Tôi không thể thấy làm thế nào bạn có thể tìm thấy hàng xóm gần nhất trong thời gian đó là độc lập với kích thước của tập dữ liệu. Vì vậy, nếu bạn có bất kỳ giải pháp như thế xin vui lòng thêm nó ở đây, mặc dù nó là sự tò mò học thuật hơn ở giai đoạn này. –

+1

@Muhammad: Đây là sự cân bằng giữa phức tạp về thời gian và độ phức tạp của không gian. Giả sử rằng bạn không có vấn đề về không gian (hoặc phạm vi của các giá trị không quá lớn), thì bạn có thể chỉ cần tạo một mảng lớn chứa tại vị trí k điểm gần nhất với giá trị truy vấn k.Điều này có độ phức tạp thời gian truy vấn O (1) và độ phức tạp của không gian O (max-min). Tôi không chắc chắn làm thế nào sự phức tạp không gian có thể được cải thiện, tuy nhiên ... –

+0

Ý tưởng tuyệt vời. Vì vậy, điều này trông giống như một bảng tra cứu thực hiện chức năng tìm gần nhất. Vấn đề là bất kỳ băm nào tôi có thể nghĩ đến cho trường hợp này sẽ biến đổi nó cho một cái gì đó O (log n). –

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