2013-11-24 18 views
8

Tôi muốn có thể tạo ra các đồ thị ngẫu nhiên, không bị phát hiện và được kết nối trong Java. Ngoài ra, tôi muốn có thể kiểm soát số lượng đỉnh tối đa trong biểu đồ. Tôi không chắc điều gì sẽ là cách tốt nhất để tiếp cận vấn đề này, nhưng đây là một vài điều tôi có thể nghĩ đến:Cách tạo biểu đồ ngẫu nhiên?

(1) Tạo một số giữa 0n và để đó là số đỉnh. Sau đó, bằng cách nào đó một cách ngẫu nhiên liên kết các đỉnh với nhau (có thể tạo ra một số ngẫu nhiên trên mỗi đỉnh và để cho đó là số lượng các cạnh ra khỏi đỉnh nói). Di chuyển đồ thị bắt đầu từ một đỉnh tùy ý (nói với Breadth-First-Search) và để đồ thị ngẫu nhiên của chúng tôi G là tất cả các nút được truy cập (theo cách này, chúng tôi đảm bảo rằng G được kết nối).

(2) Tạo ma trận vuông ngẫu nhiên (trong số 01) với chiều dài cạnh giữa 0n (bằng cách nào đó). Đây sẽ là ma trận kề cho biểu đồ của chúng ta (đường chéo của ma trận sau đó sẽ là tất cả 1 's hoặc tất cả 0' s). Tạo cấu trúc dữ liệu từ biểu đồ và duyệt biểu đồ từ bất kỳ nút nào để nhận danh sách các nút được kết nối và gọi biểu đồ G.

Bất kỳ cách nào khác để tạo biểu đồ đủ ngẫu nhiên đều được hoan nghênh. Lưu ý: Tôi không cần đồ thị hoàn toàn ngẫu nhiên, tức là biểu đồ bạn tạo không cần phải có bất kỳ thuộc tính toán học đặc biệt nào (như tính đồng nhất của một số loại). Tôi chỉ cần rất nhiều và rất nhiều đồ thị cho mục đích thử nghiệm của một cái gì đó khác.

Đây là lớp Java Node Tôi đang sử dụng:

public class Node<T> { 
    T data; 
    ArrayList<Node> children= new ArrayList<Node>(); 
    ...} 

Đây là lớp Graph Tôi đang sử dụng (bạn có thể nói tại sao tôi chỉ quan tâm đến đồ thị kết nối tại thời điểm này):

public class Graph { 
    Node mainNode; 
    ArrayList<Node> V= new ArrayList<Node>(); 

    public Graph(Node node){ 
     mainNode= node; 
    } 
    ...} 

Như một ví dụ, đây là cách tôi làm cho đồ thị cho mục đích thử nghiệm ngay bây giờ:

//The following makes a "kite" graph G (with "a" as the main node). 
    /*  a-b 
      |/| 
      c-d 
    */ 
    Node<String> a= new Node("a"); 
    Node<String> b= new Node("b"); 
    Node<String> c= new Node("c"); 
    Node<String> d= new Node("d"); 
    a.addChild(b); 
    a.addChild(c); 
    b.addChild(a); 
    b.addChild(c); 
    b.addChild(d); 
    c.addChild(a); 
    c.addChild(b); 
    c.addChild(d); 
    d.addChild(c); 
    d.addChild(b); 
    Graph G1= new Graph(a); 
+0

Đối với điều này, bạn có thể sử dụng thư viện tạo dữ liệu ngẫu nhiên như Quickcheck for Java. Tuy nhiên, các thư viện như vậy thường không có phương pháp dựng sẵn để tạo biểu đồ, vì vậy điều này có thể hơi phức tạp một chút. Hãy dùng thử và trả lời nếu bạn gặp sự cố. –

+0

Tôi sẽ kết hợp hai cách tiếp cận. Ban đầu tạo một biểu đồ được kết nối đơn giản bằng cách kết nối một nút ngẫu nhiên không có trong biểu đồ với một nút ngẫu nhiên trong đó. Sau đó, từ các đỉnh có thể không được xác định ('0' trong ma trận), chọn một số để thêm vào biểu đồ để làm cho nó đậm đặc hơn. – millimoose

+0

@RobinGreen, mặc dù có vẻ như Quickcheck sẽ giúp tạo ra các nguyên thủy, tôi vẫn sẽ phải tạo ra 'Node' chứa các phần tử nguyên thủy (đó là phần khó khăn hơn nhiều). Tôi cũng đang tìm kiếm một công trình rõ ràng hơn mà không cần sử dụng thư viện. – bourbaki4481472

Trả lời

10

Bất cứ điều gì bạn muốn làm với biểu đồ của mình, tôi đoán mật độ của nó cũng là một tham số quan trọng. Nếu không, bạn chỉ cần tạo một tập hợp các dòng nhỏ (đồ thị hoàn chỉnh) bằng cách sử dụng các kích thước ngẫu nhiên và sau đó kết nối chúng một cách ngẫu nhiên.

Nếu tôi đúng, tôi khuyên bạn nên sử dụng Erdős-Rényi model: đơn giản, không xa những gì bạn đề xuất ban đầu và cho phép bạn kiểm soát mật độ biểu đồ (về cơ bản: số lượng liên kết).

Dưới đây là một mô tả ngắn gọn của mô hình này:

  1. Xác định một giá trị xác suất p (p cao hơn và dày đặc hơn đồ thị: 0 = không liên kết, 1 = hoàn toàn kết nối đồ thị);
  2. Tạo các nút n của bạn (làm đối tượng, làm ma trận kề, hoặc bất kỳ thứ gì phù hợp với bạn);
  3. Mỗi cặp nút được kết nối với xác suất (độc lập) p. Vì vậy, bạn phải quyết định sự tồn tại của một liên kết giữa chúng bằng xác suất này p. Ví dụ, tôi đoán bạn có thể vẽ một giá trị q giữa 0 và 1 và tạo liên kết iff q < p. Sau đó, thực hiện tương tự cho mỗi cặp nút có thể có trong biểu đồ.

Với mô hình này, nếu p của bạn đủ lớn thì có thể có biểu đồ của bạn được kết nối cao (xem tham chiếu Wikipedia để biết chi tiết). Trong mọi trường hợp, nếu bạn có một số thành phần, bạn cũng có thể buộc kết nối của nó bằng cách tạo liên kết giữa các nút của các thành phần riêng biệt. Trước tiên, bạn phải xác định từng thành phần bằng cách thực hiện tìm kiếm theo chiều rộng đầu tiên (một cho mỗi thành phần). Sau đó, bạn chọn các cặp nút trong hai thành phần riêng biệt, tạo một liên kết giữa chúng và xem xét cả hai thành phần được hợp nhất. Bạn lặp lại quá trình này cho đến khi bạn có một thành phần duy nhất còn lại.

+0

Cảm ơn bạn đã giải thích và liên kết. Mô hình này có thể phù hợp với tôi. – bourbaki4481472

+0

Mặc dù tôi phải nói rằng tôi hơi bối rối về sự khác biệt giữa hai mô hình mà bài viết Wikipedia nói đến. – bourbaki4481472

+2

Trong mô hình đầu tiên, bạn xem xét tất cả các đồ thị có thể tôn trọng một số tham số (số lượng các nút và liên kết) và bạn chọn ngẫu nhiên một. Trong phần thứ hai, bạn xây dựng một biểu đồ bằng cách thêm ngẫu nhiên các liên kết vào một biểu đồ rỗng ban đầu. Tôi đã tìm thấy mô hình thứ hai phù hợp hơn để thực hiện, vì vậy đây là mô hình tôi đã trình bày trong bài đăng của mình. –

2

Phần khó khăn duy nhất là đảm bảo rằng đồ thị cuối cùng được kết nối. Để làm điều đó, bạn có thể sử dụng disjoint set data structure. Theo dõi số lượng thành phần, ban đầu n. Tiếp tục chọn các cặp đỉnh u và v ngẫu nhiên, thêm cạnh (u, v) vào biểu đồ và cấu trúc phân chia, và giảm số lượng thành phần khi cấu trúc đó cho bạn biết u và v thuộc về các thành phần khác nhau. Dừng khi đếm thành phần đạt 1. (Lưu ý rằng sử dụng ma trận kề đơn giản hóa việc quản lý trường hợp cạnh (u, v) đã có trong biểu đồ: trong trường hợp này, adj [u] [v] sẽ được đặt thành 1 Nếu bạn thấy điều này tạo ra các đồ thị quá dày đặc (hoặc quá thưa thớt), thì bạn có thể sử dụng một số ngẫu nhiên khác để thêm các cạnh chỉ có k% thời gian khi giá trị này được tạo thành. điểm cuối đã là một phần của cùng một thành phần (hoặc khi chúng là một phần của các thành phần khác nhau), đối với một số k.

+0

Cảm ơn bạn. Điểm tốt khi thiết lập adj [u] [v] thành 1 trong ma trận kề (một khi hai bộ phân tách đã được xác định) vì điều này sẽ giúp quản lý vấn đề này. – bourbaki4481472