質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

5回答

14122閲覧

javaで0,1,2,3,4の5つの数の並べ方をすべて導出したい

Rino-T_C

総合スコア95

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

2クリップ

投稿2015/06/12 05:55

現在javaの学習を行っております。
5点の最短閉路を再帰を用いて求めるプログラムを作りたいです。
今、5点のすべての並び方を調べて、すべての経路の長さを図ることで
最短閉路を求めたいと覆っています。

そこで、0,1,2,3,4の数字の並べ方をすべて導出するプログラムを教えてください。

また、ほかによい考え方があればぜひ教えてください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

もっと良い方法があるかも知れませんが、一例を紹介します。

すべての並び替えた組み合わせを実現するにはpermutationという操作を行います。他の言語では標準関数になっていることもある操作です。

Javaの場合、permutationするのに標準ライブラリーだけではたぶん難しいと思いますので、Uncommons Mathsというライブラリーを使います。

Uncommons Maths

Uncommons Mathsを使う場合、Mavenなら下記の依存関係を追加します。Mavenを使わない場合は、上記ページからライブラリーをダウンロードしてください。

lang

1 <dependency> 2 <groupId>org.uncommons.maths</groupId> 3 <artifactId>uncommons-maths</artifactId> 4 <version>1.2.2</version> 5 </dependency> 6 <dependency> 7 <groupId>jfree</groupId> 8 <artifactId>jfreechart</artifactId> 9 <version>1.0.13</version> 10 </dependency>

5個だとここでは結果が多すぎるので、数字4個の例を示します。

lang

1// import java.util.Arrays; 2// import java.util.List; 3// import org.uncommons.maths.combinatorics.PermutationGenerator; 4 5PermutationGenerator<Integer> gen = new PermutationGenerator<>(Arrays.asList(0, 1, 2, 3)); 6while (gen.hasMore()) { 7 List<Integer> a = gen.nextPermutationAsList(); 8 System.out.println(a); 9}

実行結果。

[0, 1, 2, 3] [0, 1, 3, 2] [0, 2, 1, 3] [0, 2, 3, 1] [0, 3, 1, 2] [0, 3, 2, 1] [1, 0, 2, 3] [1, 0, 3, 2] [1, 2, 0, 3] [1, 2, 3, 0] [1, 3, 0, 2] [1, 3, 2, 0] [2, 0, 1, 3] [2, 0, 3, 1] [2, 1, 0, 3] [2, 1, 3, 0] [2, 3, 0, 1] [2, 3, 1, 0] [3, 0, 1, 2] [3, 0, 2, 1] [3, 1, 0, 2] [3, 1, 2, 0] [3, 2, 0, 1] [3, 2, 1, 0]

投稿2015/06/12 06:35

argius

総合スコア9390

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Rino-T_C

2015/06/15 08:08

コメント遅れまして申し訳ありません。 そのようなライブラリがあるんですね! 参考にさせていただきます!! ありがとうございます!
guest

0

ベストアンサー

こんにちは。

 お手本になるようなアルゴリズムや、それを実装したコードがきっと
あるのだろうなと思いつつ、自分の頭の体操としてやってみました。

 基本的な考え方は以下です。

0 以上 n以下の(n+1)個の整数を要素とする順列 p(n+1) は、
0 以上 (n-1)以下の n個の整数を要素とするある順列 p(n)に、
要素 n を追加して作成する。
その際に、要素 n を追加する場所は、以下の(n+1)ヶ所ある。
・p(n)の先頭
・p(n)の要素と要素の間(これは、(n-1)ヶ所ある。)
・p(n)の末尾

たとえば、0以上2以下を要素として持つ、[0,1,2]という順列に
要素 3 を加える位置は、先頭、0と1の間、1と2の間、末尾の
4カ所あり、これらの追加する位置の違いによって4つの順列、
[3,0,1,2]
[0,3,1,2]
[0,1,3,2]
[0,1,2,3]
が作成されます。この考え方で再帰のアルゴリズムを作成しました。
以下のソースで、
private static List<List<Integer>> getPermutations(Integer n)
が再帰で解のリストを求めるメソッドです。

lang

1import java.util.ArrayList; 2import java.util.Arrays; 3import java.util.List; 4 5public class Q11179 { 6 7 public static void main(String[] args) { 8 9 // 0以上4以下の整数のすべての順列のリストを作成 10 List<List<Integer>> list = getPermutations(4); 11 12 // 結果の表示(逆順にリスト要素を出力) 13 int counter = 0; 14 for (int i = list.size() - 1; i >= 0; --i) { 15 counter++; 16 System.out.println(counter + ":" + list.get(i)); 17 } 18 } 19 20 /* 21 * 0以上 n以下の整数を要素とする順列(を表現したリスト)を 22 * 要素として持つリストを作成 23 */ 24 private static List<List<Integer>> getPermutations(Integer n) { 25 26 // n が不正な値のとき、何もせず null を返して終了 27 if (n == null || n < 0) 28 return null; 29 30 // このメソッドの返り値となるリストを作成 31 List<List<Integer>> results = new ArrayList<List<Integer>>(); 32 33 // n = 0 の場合、要素の追加が可能なリスト[0]を要素とするリストを返す。 34 if (n == 0) { 35 results.add(new ArrayList<Integer>(Arrays.asList(0))); 36 return results; 37 } 38 39 // n > 0 の場合、まず、(n-1)に対する解のリストを再帰で取得 40 List<List<Integer>> prevResults = getPermutations(n - 1); 41 42 // (n-1)のときのリストをループし、要素の順列に n を加えた順列を作成 43 for (List<Integer> permutation : prevResults) { 44 for (int i = 0; i <= n; ++i) { // n を加える位置についてのループ 45 permutation.add(i, n); 46 results.add(new ArrayList<Integer>(permutation)); 47 permutation.remove(n); 48 } 49 permutation.clear(); // 全要素を削除しておく 50 } 51 prevResults.clear(); // 全要素を削除しておく 52 53 return results; 54 } 55}

 上記を実行すると、以下のような出力が得られます。
行頭の数字は、組み合わせの数を数えるためのものです。

lang

11:[0, 1, 2, 3, 4] 22:[0, 1, 2, 4, 3] 33:[0, 1, 4, 2, 3] 44:[0, 4, 1, 2, 3] 55:[4, 0, 1, 2, 3] 6・・・ 7117:[3, 2, 1, 4, 0] 8118:[3, 2, 4, 1, 0] 9119:[3, 4, 2, 1, 0] 10120:[4, 3, 2, 1, 0]

5個の要素による順列の数は、公式nPr = n!/(n-r)! に n=r=5 を代入して

5P5 = 5!/(5-5)! = (54321)/0! = 120/1 = 120

ですので、出力例の行数は合っています。
また、ソースコードのmainメソッドの中で
List<List<Integer>> list = getPermutations(4);
としているところを
List<List<Integer>> list = getPermutations(5);
にしたり、
List<List<Integer>> list = getPermutations(0);
にしたりしてみましたが問題なく動くのを確認しました。
ただし私の手元のPCでは、
getPermutations(8);
まではいけましたが
getPermutations(9);
でヒープを使い果たして

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

となりました。

以上、ご参考になれば幸いです。

投稿2015/06/12 06:54

編集2015/06/14 21:35
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Rino-T_C

2015/06/15 08:07

コメント遅れまして申し訳ありません! 丁寧な説明、ありがとうございます!! 今は時間がないので、じっくり読ませていただくことはできないのですが、 とても参考になりそうな回答をいただけてこちらとしても非常に助かっています! ありがとうございます。
guest

0

最短閉路問題は、最短ハミルトン路問題あるいは巡回セールスマン問題として有名です。
基点(たとえば0)から隣接する点(1,2,3,4?)までの距離を情報として持つ必要があります。
私はあまり詳しくないので、上記問題名でググって確認してみてください。

投稿2015/06/12 06:55

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Rino-T_C

2015/06/15 07:57

コメント遅れました! ありがとうございます!! 今は時間がないので後でググってみますね。 有名問題の名前がわかるだけで、調べるのが楽になります。 ありがとうございました!
guest

0

こんなんいかがでしょう

lang

1package a; 2 3public class TT11179 { 4 public static void main(String[] args) { 5 try { 6 new Permutation() { 7 @Override 8 public void found(int[] list) { 9 for(int val : list) { 10 System.out.print(" " + val); 11 } 12 System.out.println(""); 13 } 14 } 15 .find(5); 16 } 17 catch(Throwable e) { 18 e.printStackTrace(); 19 } 20 } 21 22 public static abstract class Permutation { 23 private int _count; 24 private boolean[] _picked; 25 private int[] _list; 26 27 public void find(int count) { 28 _count = count; 29 _picked = new boolean[count]; 30 _list = new int[count]; 31 pick(0); 32 } 33 34 private void pick(int index) { 35 if(_count <= index) { 36 found(_list); 37 return; 38 } 39 for(int val = 0; val < _count; val++) { 40 if(_picked[val] == false) { 41 _picked[val] = true; 42 _list[index] = val; 43 pick(index + 1); 44 _picked[val] = false; 45 } 46 } 47 } 48 49 public abstract void found(int[] order); 50 } 51}

投稿2015/06/15 21:52

IchigoTaruto

総合スコア159

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

順列を求める方法はいくつもあります。

参考:

投稿2015/06/12 23:36

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Rino-T_C

2015/06/15 08:01

ありがとうございます。 教えてくださったサイトも参考にさせていただきますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問