2012-05-08 51 views
7

Tôi đã viết một chương trình để tìm tất cả các hoán vị có thể có của một danh sách các mục nhất định. Đây chính xác có nghĩa là chương trình in của tôi tất cả có thể P (n, r) giá trị cho r = 0 đến nMã Java cho hoán vị của một danh sách các số

Dưới đây là các mã:

package com.algorithm; 

import java.util.ArrayList; 
import java.util.Calendar; 
import java.util.Collection; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 

public class Permutations<T> { 
    public static void main(String args[]) { 
     Permutations<Integer> obj = new Permutations<Integer>(); 
     Collection<Integer> input = new ArrayList<Integer>(); 
     input.add(1); 
     input.add(2); 
     input.add(3); 

     Collection<List<Integer>> output = obj.permute(input); 
     int k = 0; 
     Set<List<Integer>> pnr = null; 
     for (int i = 0; i <= input.size(); i++) { 
      pnr = new HashSet<List<Integer>>(); 
      for(List<Integer> integers : output){ 
      pnr.add(integers.subList(i, integers.size())); 
      } 
      k = input.size()- i; 
      System.out.println("P("+input.size()+","+k+") :"+ 
      "Count ("+pnr.size()+") :- "+pnr); 
     } 
    } 
    public Collection<List<T>> permute(Collection<T> input) { 
     Collection<List<T>> output = new ArrayList<List<T>>(); 
     if (input.isEmpty()) { 
      output.add(new ArrayList<T>()); 
      return output; 
     } 
     List<T> list = new ArrayList<T>(input); 
     T head = list.get(0); 
     List<T> rest = list.subList(1, list.size()); 
     for (List<T> permutations : permute(rest)) { 
      List<List<T>> subLists = new ArrayList<List<T>>(); 
      for (int i = 0; i <= permutations.size(); i++) { 
       List<T> subList = new ArrayList<T>(); 
       subList.addAll(permutations); 
       subList.add(i, head); 
       subLists.add(subList); 
      } 
      output.addAll(subLists); 
     } 
     return output; 
    } 
} 

Output

P(3,3) : Count (6) :- [[1, 2, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2], [2, 1, 3], [1, 3, 2]] 
P(3,2) : Count (6) :- [[3, 1], [2, 1], [3, 2], [1, 3], [2, 3], [1, 2]] 
P(3,1) : Count (3) :- [[3], [1], [2]] 
P(3,0) : Count (1) :- [[]] 

Vấn đề của tôi là , khi tôi tăng số lượng trong danh sách đầu vào. Thời gian chạy tăng và sau 11 số trong danh sách đầu vào, chương trình gần như chết. Mất khoảng 2 GB bộ nhớ để chạy.

Tôi đang chạy trên máy có RAM 8GB và bộ xử lý i5, do đó tốc độ và không gian không phải là vấn đề.

Tôi sẽ đánh giá cao, nếu có ai có thể giúp tôi viết mã hiệu quả hơn.

+4

Better phù hợp với [http://codereview.stackexchange.com/](http:/ /codereview.stackexchange.com/). –

+0

@Anthony cảm ơn bạn :) Tôi mới đến điều này vì vậy, không có ý tưởng nơi để đặt những gì. – dharam

Trả lời

8

Nếu bạn muốn tất cả hoán vị có từ 15 phần tử trở lên, hãy ghi chúng vào đĩa hoặc db hoặc một thứ gì đó, vì chúng sẽ không vừa với bộ nhớ. Chỉnh sửa: Steinhaus–Johnson–Trotter algorithm. Đây có lẽ là những gì bạn đang tìm kiếm.

+0

Tôi tin những gì bạn nói là sự thật. Vấn đề không phải là lưu trữ. Vấn đề là thời gian chạy. Mất hơn một phút để hoán vị khoảng 13 con số. – dharam

+0

Liên kết thực sự tuyệt vời. Thậm chí tăng tốc có thể giúp tôi đoán. Cảm ơn con trỏ. Hãy thử và đăng nó ở đây – dharam

+0

+1 cho liên kết, cảm ơn! – kritzikratzi

1

Bạn nhận ra rằng bạn đang tạo các danh sách rất lớn và thời gian chạy sẽ tăng khi độ dài danh sách thực hiện. Bạn đã xác định được danh sách gây rắc rối cho bạn trong bao lâu?

Một điều có thể giúp một số người có thể in từng hoán vị khi bạn tìm thấy nó, thay vì thu thập tất cả chúng vào danh sách và THEN in chúng. Tất nhiên, nếu vấn đề là lưu trữ toàn bộ danh sách và không chỉ in chúng, điều đó sẽ không giúp ích gì.

+0

Cảm ơn bạn đã phản hồi. Ngay cả trong trường hợp tôi in nó số lượng hoán vị được tạo cho 10 số là 100000. Hãy nói rằng tôi không lưu trữ nó, ngay cả trong trường hợp đó thứ tự sẽ không thay đổi. Hơn nữa vấn đề với mã của tôi là cây đệ quy là một mặt. Nếu một số có nghĩa là tôi có thể tìm thấy một thuật toán mà chia đầu vào tại mỗi đệ quy thành hai phần bằng nhau và sau đó tìm các hoán vị của các danh sách nhỏ hơn và hợp nhất chúng ở cuối. Chỉ muốn biết nếu có ai có thể giới thiệu cho tôi một cuốn sách cho các thuật toán nâng cao. – dharam

13

Nếu bạn không lưu trữ - nếu bạn chỉ duyệt qua nó - hãy xem xét sử dụng thuật toán của Heap (# 3 trên http://www.cut-the-knot.org/do_you_know/AllPerm.shtml) - hoặc, để làm cho cuộc sống của bạn dễ dàng hơn, hãy sử dụng số Collections2.permutations của ổi không thực sự xây dựng toàn bộ danh sách hoán vị - nó đi qua chúng một cách nhanh chóng. (Tiết lộ: Tôi đóng góp cho ổi.)

+0

Vâng, cảm ơn, tôi chắc chắn sẽ cho nó một thử. – dharam

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