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

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

ただいまの
回答率

87.78%

Java 実行時エラー IlligalArgumentException: bound must be positive

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 9,238

score 95

現在Javaでランダム生成した最長閉路を描画する課題をやっています。

現在次のようなエラーが返されてどこが間違っているのかが検討つきません...

java.lang.IllegalArgumentException: bound must be positive
        at java.util.Random.nextInt(Random.java:388)
        at Heiro_ln.init(Heiro_ln.java:20)
        at sun.applet.AppletPanel.run(AppletPanel.java:434)
        at java.lang.Thread.run(Thread.java:745)

そもそもIlligalArgumentExceptionってどんなエラーなのでしょうか....?

以下にプログラムを載せておきます。

import java.applet.Applet;
import java.awt.*;
import java.util.*;
import java.util.List;

public class Heiro_ln extends Applet{
    
    int max = 0;
    int dis_now;
    int fact_n = 0;
    Random rnd = new Random();
    int n = rnd.nextInt(3)+2;
    ArrayList<Point> points = new ArrayList<Point>();
    List<List<Integer>> list;
                        
    public void init(){


        for(int i = 0; i < 3*(n+1); i++){
            points.add(new Point(rnd.nextInt((int)System.currentTimeMillis()%100) + 10, rnd.nextInt((int)System.currentTimeMillis()%100) +10));
        }
    
        list = nPn(n-1);
        fact_n = fact(n);
        longest(0);
    }

    //描画

    public void paint(Graphics g){
        int px[] = new int[n+1];
        int py[] = new int[n+1];

        for(int i = 2*(n+1); i < 3*(n+1); i++){
            Point pt = points.get(i);
            px[i-2*(n+1)] = 5*pt.x;
            py[i-2*(n+1)] = 5*pt.y;
        }
    //座標を描画
        for(int i = 0; i < n ; i++){
            String string_x = String.valueOf(px[i]);
            String string_y = String.valueOf(py[i]);
            g.drawString("("+string_x+","+string_y+")", 10+55*i, 10);
        }
        g.drawPolyline(px, py, n+1);
    }

    //距離を求める

    public int distance(){
        int toatal_distance = 0;
        int dis[] = new int[n];
        for(int i = n+1; i < (n+1)*2 - 1; i++){
            int dx = 0;
            int dy = 0;
            Point pt_p = points.get(i);
            Point pt_a = points.get(i+1);
            dx = pt_a.x - pt_p.x;
            dy = pt_a.y - pt_p.y;
            dis[i-n-1] = (int)Math.sqrt(dx*dx + dy*dy);
        }
        for(int j = 0; j < n; j++){
            toatal_distance += dis[j];
        }
        return toatal_distance;
    }


    public static List<List<Integer>> nPn(Integer n) {
    
        if (n == null || n < 0){
            return null;
        }

        List<List<Integer>> Ans = new ArrayList<List<Integer>>();

        if (n == 0) {            
            Ans.add(new ArrayList<Integer>(Arrays.asList(0)));
            return Ans;
        }            
        List<List<Integer>> preAns = nPn(n - 1);
    
        for (List<Integer> permutation : preAns) {
            for (int i = 0; i <= n; ++i) {
                permutation.add(i, n);
                Ans.add(new ArrayList<Integer>(permutation));
                permutation.remove(n);
            }
            permutation.clear();
        }
        preAns.clear();
    
        return Ans;
    }

    //階乗計算
    public int fact(int t){
        int result = 1;
        for(int i = t; i > 0; i--){
            result *= i;
        }
        return result;
    }

    
    //最短距離を求める
    public int longest(int k){


        for(int i = n+1; i < 2*(n+1)-2; i++){
            points.set(i, points.get((list.get(k)).get(i-n-1)));
        }
        points.set(2*(n+1)-1, points.get((list.get(k)).get(0)));
    
        dis_now = distance();
        if(max == 0){
            max = dis_now;
        }else if(dis_now > max){
            max = dis_now;

        for(int i = 2*(n+1); i < 3*(n+1)-2; i++){
        points.set(i, points.get((list.get(k)).get(i-2*(n+1))));
        }
        points.set(3*(n+1)-1, points.get((list.get(k)).get(0)));        
        }


        if(k < fact_n - 1){
            return longest(k+1);
        }else{
            return 0;
        }
    }
}

原因がわかる方、よろしくお願いします!

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+4

「bound must be positive」と出力されている通り、RandomクラスのメソッドnextIntの引数は常に正の値(=positive)である必要があります。
これを踏まえてコードを読んでみると、initメソッド内でnextIntメソッドへ以下の値を渡しているのに気づきます。

(int)System.currentTimeMillis()%100

System.currentTimeMillis()はlong型の値を返すメソッドで、これをint型に直すとオーバーフローが発生して負の値になる可能性があります。
%演算子での剰余計算では符号は反転しないため、最終的にnextIntメソッドの引数が負の値になってしまったのではないでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/04 15:02

    maisumakunさんの指摘の通り、負数だけでなく0になった場合も例外が発生するようです。
    念のため、補足いたします。

    キャンセル

  • 2015/08/04 15:13

    回答ありがとうございます!!

    Random rnd_x = new Random();
    Random rnd_y = new Random();
    int x = rnd_x.nextInt(101)+10;
    int y = rnd_y.nextInt(101)+10;
    points.add(new Point(x, y));

    long型になるSystem.currentTimeMillis()%100を上のように書き換えたらちゃんと動くようになりました!

    ありがとうございました!

    キャンセル

+3

エラーメッセージの通り、nextInt()は正の値しか取ることができません。System.currentTimeMillis()の返り値がちょうど100で割り切れた場合、0が渡ってエラーとなります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/04 14:56

    回答ありがとうございます!
    あまり考えずに使っていたので、そのようなところに原因があったとは...
    勉強になります!

    キャンセル

+2

すでにベストアンサーが出ているので、一応、補足ですが、
IllegalArgumentExceptionは、メソッドの引数に、
何かそのメソッドが受け付けられない値が渡された場合に発生します。

大抵は、そのメソッドのJavaDocに書いてあります。今回の場合、以下の通りです。

例外:
IllegalArgumentException - n が正でない場合
JavaDocを参照する習慣をつけると良いと思います。

また、何処が間違っているか見当がつかないと言うことでしたが、
 at Heiro_ln.init(Heiro_ln.java:20)
とあるので、20行目であること、その上に
  at java.util.Random.nextInt(Random.java:388)
とあるので、その行のRandomクラスのnextIntメソッドの呼び出しで
問題が発生したことまでは分かります。

例外のスタックトレースは有用な情報の塊なので、
読めるようになった方が良いと思います。
このページが参考になるのではと思います。
 

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/04 15:41

    アドバイスありがとうございます!
    スタックトレースを読むことで原因がみえてくるということは、わかってはいたのですが、読もうとしても知らないことが多いもので....
    参考になるサイトが教えていただけるのはすごくありがたいです!
    eripongさんのように順序だてて読めるよう頑張ってみますね!

    キャンセル

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

  • ただいまの回答率 87.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る