8

与えられたアイテムのリストの可能な順列をすべて見つけるプログラムを作成しました。これは、私のプログラムが r=0 から n のすべての可能な P(n,r) 値を出力することを正確に意味します。

以下はコードです:

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;
    }
}

出力

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) :- [[]]

私の問題は、入力リストの数字を増やしていくことです。実行時間は増加し、入力リストに 11 個の数値が入力されると、プログラムはほとんど停止します。実行には約 2 GB のメモリが必要です。

私はこれを 8GB の RAM と i5 プロセッサを搭載したマシンで実行しているので、速度とスペースは問題になりません。

誰かがより効率的なコードを書くのを手伝ってくれれば幸いです。

4

4 に答える 4

16

保存していない場合(繰り返し処理している場合)は、Heapのアルゴリズム(http://www.cut-the-knot.org/do_you_know/AllPerm.shtmlの#3 )の使用を検討してください。または、あなたの生活を楽にするために、Guavaを使用してくださいCollections2.permutations。これは、実際には順列のリスト全体を構築するのではなく、その場でそれらをウォークスルーします。(開示:私はグアバに貢献します。)

于 2012-05-08T17:44:00.163 に答える
8

15以上の要素のすべての順列が必要な場合は、メモリに収まらないため、ディスクまたはデータベースなどに書き込みます。編集:Steinhaus–Johnson–Trotterアルゴリズム。これはおそらくあなたが探しているものです。

于 2012-05-08T17:37:39.720 に答える
7

Google (Guava) の Java ライブラリには、このためのユーティリティ メソッドがあります: Collections2#permutations(Collection)

于 2013-07-15T14:25:23.583 に答える
2

非常に大きなリストを生成していること、およびリストの長さが長くなるにつれて実行時間が長くなることを実感しています。問題を引き起こしているリストの長さを決定しましたか?

一部の人を助けるかもしれない1つのことは、それらをすべてリストにまとめてから印刷するのではなく、見つけたとおりに各順列を印刷することです。もちろん、リストを印刷するだけでなく、実際にリスト全体を保存することがポイントである場合、それは役に立ちません。

于 2012-05-08T17:34:36.797 に答える