私は学士号のためにこれを行いました。私はこのようにしました(完璧ではありませんが、役立つかもしれません):
(以下のコードからいくつかの重要でないメソッド/関数を削除しました。これは主に、コードをどのように視覚化したかを説明するためのものです。たとえば、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
幸運を!