8

さまざまな種類の並べ替え (バブル、挿入、選択) を実装しました。ソートごとに次のように実装を比較したいことを知っています(これはバブルソートの例です):

ここに画像の説明を入力

たとえば、これが私のバブルソートです:

private static int[] bubbleSort(int[] tabToSort) {
   int [] tab = tabToSort.clone();
   boolean tabSort = false;
   while(!tabSort){
        tabSort = true;
        for(int i = 0; i < tab.length -1; i++){
            if(tab[i]> tab[i+1]){
                int temp = tab[i+1];
                tab[i+1] = tab[i];
                tab[i] = temp;
                tabSort = false;
            }
        }
    }
    return tab;
}

GUI を起動し、その上に 1000 個のランダム ポイントを配置しましたy=x

@Override
    public void paintComponent (Graphics g){
        super.paintComponent(g);
        Graphics2D g2d  = (Graphics2D) g;
        g2d.setColor(Color.BLACK);
        Dimension size = getSize();
        Insets  insets= getInsets();
        int w =  size.width - insets.left - insets.right;
        int h =  size.height - insets.top - insets.bottom;
        
        g2d.drawLine(size.width ,0, 0, size.height);
        Random r = new Random();

        for (int i  =0; i < 1000; i++) {
           int x = Math.abs(r.nextInt()) % w;
           int y = Math.abs(r.nextInt()) % h;
           Point p = new Point(x, y);
           g2d.drawLine(p.x, p.y, p.x, p.y);
        }
    }

これが私がやったことです:

ここに画像の説明を入力

どうやって始めればいいのかわかりません。それを実装するために従うべき手順/ヒントを誰かに教えてもらえますか?

ありがとう :)

4

4 に答える 4

1

私は学士号のためにこれを行いました。私はこのようにしました(完璧ではありませんが、役立つかもしれません):

(以下のコードからいくつかの重要でないメソッド/関数を削除しました。これは主に、コードをどのように視覚化したかを説明するためのものです。たとえば、GRectangle クラスを単純な java.awt.Point に置き換えることができます。)

初期化メソッドは、データの最大値と最小値を見つける方法の例を示しているので、datavalues => 座標を変換する方法がわかります。

public class DotVisualisation extends Visualisation {

    private ArrayList<GRectangle> m_points;

    private Comparable[] m_data;

    private Comparable m_maxValue;
    private Comparable m_minValue;

    private int MAX_HEIGHT; // max height in pixels of visualization

    /**
     * Creates a new DotVisualisation.<br>
     * <br>
     * This class is a runnable JComponent that will visualize data as a function. 
     * The visualisation will plot the data with X and Y coordinates on the window. 
     * The X coordinate of the point is index of the dataelement. 
     * The Y coordinate of the point is relative to the value of the dataelement.<br>
     * <br>
     * This visualisation should be used for medium and large arrays.
     * 
     * @author David Nysten
     */
    public DotVisualisation()
    {
        m_points = new ArrayList<GRectangle>();
        MAX_HEIGHT = 150;
    }

    /**
     * Returns the maximum supported dimension by this visualisation.
     * 
     * @return The supported dimension.
     */
    public static int getSupportedDimension()
    {
        return 1;
    }

    @Override
    public Dimension getMaximumSize() 
    {
        return getPreferredSize();
    }

    @Override
    public Dimension getPreferredSize() 
    {
        return new Dimension(m_points.size() + 2, MAX_HEIGHT + 6);
    }

    @Override
    public Dimension getMinimumSize() 
    {
        return getPreferredSize();
    }

    @Override
    public void paintComponent(Graphics g)
    {
        for(int i = 0; i < m_points.size(); ++i)
            m_points.get(i).paintComponent(g);
    }

    private void swap(int index, int index2) { // See below }

    private void initialise()
    {
        findMinimum();
        findMaximum();
        m_points.clear();
        double multiplier;
        int x = 0, y = 0, h;
        for(int i = 0; i < m_data.length; ++i)
        {
            if(m_data[i].compareTo(-1) <= 0)
                h = 0;
            else
            {
                Integer value = (Integer) m_data[i];
                Integer min = (Integer) m_minValue;
                Integer diff = (Integer) m_maxValue - min;
                multiplier = MAX_HEIGHT / diff.doubleValue();
                h = (int) ((value - min) * multiplier);
            }
            y = (int) (MAX_HEIGHT - h);
            GRectangle r = new GRectangle(x, y, 1, 1); // 1, 1 = width and height
            r.setColor(Color.BLACK);
            m_points.add(r);
            ++x;
        }
    }

    private void findMaximum()
    {
        Comparable max = null;
        if(m_data.length > 0)
        {
            max = m_data[0];
            for(int i = 1; i < m_data.length; ++i)
                if(m_data[i].compareTo(max) > 0)
                    max = m_data[i];
        }
        m_maxValue = max;
    }

    private void findMinimum()
    {
        Comparable min = null;
        if(m_data.length > 0)
        {
            min = m_data[0];
            for(int i = 1; i < m_data.length; ++i)
                if(m_data[i].compareTo(min) < 0)
                    min = m_data[i];
        }
        m_minValue = min;
    }
}

これを考慮してください。150 ピクセルの高さで 0 から 150 までの整数を視覚化するのは簡単です。高さ 150 で値 565 と 3544545 の間の整数のセットを視覚化するのは、少し難しくなります。

PS: コードは、inputarray 内の要素のインデックスを X 座標として使用します。
PS: クラスは inputarray (m_data 変数) への参照を保持しますが、それはもちろん必要ありません。ポイントを初期化するためだけに必要です。
PS: すべてのビジュアライゼーションによって拡張される私の「ビジュアライゼーション」クラスは、基本的に JPanel です。
PS: 上記のコードは正の整数用に書かれているため、おそらく負の整数を処理するために追加のコーディングが必要になるでしょう ;)。

次に、アルゴリズムの動作を視覚化するために、オブザーバー パターンを使用しました。バブルソートなどのアルゴリズムは次のようになります。

    for(int i = 0; i < size(); ++i)
        for(int j = 1; j < size(); ++j)
            if(greaterThan(j - 1, j))
                swap(j - 1, j);

関数 swap は次のように定義されています (簡略化されたバージョン)。

protected void swap(int index1, int index2)
{
    if(index1 != index2)
    {
        incrementSwap(); // counting swaps and visualizing counter

        m_command.clear();
        m_command.setAction(Action.SWAP);
        m_command.addParameter(index1);
        m_command.addParameter(index2);
        setChanged();
        notifyObservers(m_command);

        E temp = m_data[index1];
        m_data[index1] = m_data[index2];
        m_data[index2] = temp;
    }
}

index1 と index2 でスワップが発生したことをオブザーバー (視覚化) に通知した場所。m_command 変数は Command-class (自分で書いたもの) のインスタンスであり、視覚化に必要な情報の単なるラッパーです。つまり、発生したアクションと関連情報 (スワップ アクションのインデックスなど)。

したがって、視覚化では、これらのインデックスと X 座標の GRectangle を交換しました。

private void swap(int index, int index2)
{
    if(index == index2)
        return;
    GRectangle r1 = m_points.get(index);
    GRectangle r2 = m_points.get(index2);

    int tempX = r1.getX();
    r1.setLocation(r2.getX(), r1.getY());
    r2.setLocation(tempX, r2.getY());

    m_points.set(index, r2);
    m_points.set(index2, r1);
}

次のような行を追加できます。

        try {
            Thread.sleep(100);
        } catch(InterruptedException ignore) {}

続行する前にスレッドを 100 ミリ秒スリープ状態にします。これは、視覚化が速すぎる場合に便利です。

したがって、ランダムな整数を持つ配列の場合、次のようになります。

ここに画像の説明を入力

そしてソート後:(この場合、入力配列の値はランダムに生成されたため、もちろん直線ではありません)

ここに画像の説明を入力

したがって、私がそうしなければならなかったように、複数のアルゴリズムが同じビジュアライゼーションで動作できるようにする必要がある場合は、ビジュアライゼーション クラスとアルゴリズム クラスを分離し、オブザーバー パターンを使用して、アクションが発生するたびにビジュアライゼーションを更新できるようにすることをお勧めします (セット、スワップ、...)。

そして、比較のためにこのようなものを作成できます。

http://i445.photobucket.com/albums/qq179/ultddave/DotVisualizationMany_zps63269d2a.png http://i445.photobucket.com/albums/qq179/ultddave/DotVisualizationMany2_zps65e96fa9.png

幸運を!

于 2013-05-26T17:11:31.693 に答える
1

あなたがする必要があります

  1. int[] メンバー変数としてランダムな値を持つ配列を作成します。array と呼びましょうdata。おそらく、固定の配列サイズとそれぞれ 100 の範囲から開始することをお勧めします。単純なバージョンが機能している場合は、後でウィンドウ サイズに合わせて値を調整できます。固定のサイズと範囲に固執し、 で利用可能なスペースに合わせて拡大縮小するだけpaintComponentで、ウィンドウのサイズに依存しない動作にする方が良い場合があります。
  2. paintComponentループオーバーに変更data。ループ インデックスは x 値でありdata[x]、y 値を決定します。
  3. コードが初期ランダム配列を引き続き描画することをテストします。今だけ左上隅にあるかどうかは気にしないでください。アニメーションが機能しているときに修正できます。
  4. sort メソッドの最も内側のループに何らかの呼び出しを追加する必要があるsleep()ため、手順を観察する機会が得られます。そうしないと、バブルソートでさえ速すぎて観察できなくなります。1 秒 (パラメーター値 1000) から始めることをお勧めします。すべてが機能するようになったら、後で高速化します。
  5. メソッドを新しいスレッドで開始し、bubbleSort各ステップでコンポーネントが再描画されるようにします。これは最もトリッキーな部分かもしれません。おそらく、コンポーネントをbublleSortメソッドに渡して (またはコンポーネントbubbleSortの非静的メソッドを作成して)、repaint()各ステップで を要求させます (幸いなことに、これは Swing で数少ないスレッドセーフなメソッドの 1 つです)。
  6. コードの微調整: 使用可能なスペースを掛けてから、配列のサイズまたは値の範囲で割ることにより、x 座標と y 座標をスケーリングします。必要に応じてスリープ時間を調整します。さまざまな並べ替えアルゴリズムのサポートを追加します....

不明な手順がある場合は、コメントを追加してください。

于 2013-05-26T15:47:33.833 に答える