/****************************/
/* Fisher の直接確率(AWT) */
/* coded by Y.Suganuma */
/****************************/
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main (String[] args)
{
Fisher fr = new Fisher("Fisher の直接確率");
}
}
class Fisher extends Frame implements ActionListener, TextListener
{
double bunshi, bunbo, d_sum, base;
int n_row, n_col, matrix[][], sum;
TextField row, col, tx[][];
TextArea ta;
Button bt;
ScrollPane sp;
/******************/
/* コンストラクタ */
/******************/
Fisher(String name)
{
// Frameクラスのコンストラクタ
super(name);
// Windowの大きさ
setSize(600, 400);
// レイアウト,背景色,フォント
setLayout(new BorderLayout(5, 10));
setBackground(new Color(225, 255, 225));
Font f = new Font("TimesRoman", Font.BOLD, 20);
setFont(f);
// 上のパネル
Panel pn1 = new Panel();
add(pn1, BorderLayout.NORTH);
pn1.add(new Label("行の数"));
row = new TextField(3);
row.addTextListener(this);
pn1.add(row);
pn1.add(new Label("列の数"));
col = new TextField(3);
col.addTextListener(this);
pn1.add(col);
pn1.add(new Label(" "));
bt = new Button("OK");
bt.setBackground(Color.pink);
bt.addActionListener(this);
pn1.add(bt);
// 中央のパネル
sp = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
add(sp, BorderLayout.CENTER);
// 下のパネル
Panel pn3 = new Panel();
add(pn3, BorderLayout.SOUTH);
ta = new TextArea(3, 35);
pn3.add(ta);
// ウィンドウを表示
setVisible(true);
// イベントアダプタ
addWindowListener(new WinEnd());
}
/******************************/
/* 上,左,下,右の余白の設定 */
/******************************/
public Insets getInsets()
{
return new Insets(70, 20, 20, 20);
}
/******************************/
/* ボタンが押されたときの処理 */
/******************************/
public void actionPerformed(ActionEvent e)
{
double x, s;
int i1, i2, k;
String str;
// 和の計算
for (i1 = 0; i1 < n_row; i1++)
matrix[i1][n_col] = 0;
for (i1 = 0; i1 < n_col; i1++)
matrix[n_row][i1] = 0;
sum = 0;
for (i1 = 0; i1 < n_row; i1++) {
for (i2 = 0; i2 < n_col; i2++) {
str = tx[i1][i2].getText();
if (str.length() > 0) {
matrix[i1][i2] = Integer.parseInt(str);
sum += matrix[i1][i2];
}
else
matrix[i1][i2] = 0;
matrix[i1][n_col] += matrix[i1][i2];
matrix[n_row][i2] += matrix[i1][i2];
}
}
// 実行
if (sum == 0) {
ta.setForeground(Color.red);
ta.setText(" データを入力してください\n");
}
else {
ta.setForeground(Color.black);
d_sum = kaijo(sum);
// 生起確率の計算
bunshi = 0.0;
for (i1 = 0; i1 < n_row; i1++)
bunshi += kaijo(matrix[i1][n_col]);
for (i1 = 0; i1 < n_col; i1++)
bunshi += kaijo(matrix[n_row][i1]);
bunbo = cal(matrix);
base = Math.exp(bunshi - bunbo);
ta.setText("生起確率: " + base + "\n");
// base より小さい確率の和
int mx[][] = new int [n_row+1][n_col+1];
k = 0;
s = 0.0;
while (k <= matrix[0][n_col] && k <= matrix[n_row][0]) {
for (i1 = 0; i1 < n_row; i1++) {
for (i2 = 0; i2 < n_col; i2++)
mx[i1][i2] = 0;
}
mx[0][0] = k;
s += set(mx, 0);
k++;
}
ta.append("確率の和: " + s + "\n");
}
}
/*******************************************/
/* 特定の状態における確率の分母(対数計算) */
/*******************************************/
double cal(int mx[][])
{
double s = d_sum;
int i1, i2;
for (i1 = 0; i1 < n_row; i1++) {
for (i2 = 0; i2 < n_col; i2++)
s += kaijo(mx[i1][i2]);
}
return s;
}
/**********************/
/* n の階乗(対数計算) */
/**********************/
double kaijo(int n)
{
double s = 0.0;
for (int i1 = 2; i1 <= n; i1++)
s += Math.log((double)i1);
return s;
}
/************************************/
/* 様々な状態における確率を計算 */
/* mx : 状態 */
/* i : 値を設定する位置 */
/* i/n_col 行 i%n_col 列 */
/************************************/
double set(int mx1[][], int i)
{
double x, y, s = 0.0;
int i1, i2, k, k1, k2, n, n1, n2, sw = 0, ss = 0;
// 周辺度数と一致しているかのチェック
for (i1 = 0; i1 < n_row; i1++)
mx1[i1][n_col] = 0;
for (i1 = 0; i1 < n_col; i1++)
mx1[n_row][i1] = 0;
for (i1 = 0; i1 < n_row; i1++) {
for (i2 = 0; i2 < n_col; i2++) {
mx1[i1][n_col] += mx1[i1][i2];
mx1[n_row][i2] += mx1[i1][i2];
ss += mx1[i1][i2];
}
}
for (i1 = 0; i1 < n_row && sw == 0; i1++) {
if (mx1[i1][n_col] != matrix[i1][n_col])
sw = 1;
}
if (sw == 0) {
for (i1 = 0; i1 < n_col && sw == 0; i1++) {
if (mx1[n_row][i1] != matrix[n_row][i1])
sw = 1;
}
}
// 一致している場合
if (sw == 0) {
y = cal(mx1);
x = Math.exp(bunshi - y);
if (x < base + 1.0e-10)
s = x;
// デバッグ用(計算した組み合わせの出力)
// for (i1 = 0; i1 < n_row; i1++) {
// for (i2 = 0; i2 < n_col; i2++)
// System.out.print(" " + mx1[i1][i2]);
// System.out.println();
// }
// System.out.println();
}
// 一致していない場合
else {
if (i < n_row*n_col-1 && (cal(mx1) + kaijo(sum-ss)) > bunbo - 1.0e-10) {
i++;
k1 = i / n_col;
k2 = i % n_col;
n1 = 0;
n2 = 0;
for (i1 = 0; i1 < n_row; i1++)
n1 += mx1[i1][k2];
for (i1 = 0; i1 < n_col; i1++)
n2 += mx1[k1][i1];
n1 = matrix[n_row][k2] - n1;
n2 = matrix[k1][n_col] - n2;
n = (n1 < n2) ? n1 : n2;
k = 0;
int mx2[][] = new int [n_row+1][n_col+1];
while (k <= n) {
if (k2 < n_col-1 || k2 == n_col-1 && mx1[k1][n_col]+k == matrix[k1][n_col]) {
if (k1 < n_row-1 || k1 == n_row-1 && mx1[n_row][k2]+k == matrix[n_row][k2]) {
for (i1 = 0; i1 < n_row; i1++) {
for (i2 = 0; i2 < n_col; i2++)
mx2[i1][i2] = mx1[i1][i2];
}
mx2[k1][k2] = k;
s += set(mx2, i);
}
}
k++;
}
}
}
return s;
}
/******************************/
/* 列数が変更されたときの処理 */
/******************************/
public void textValueChanged(TextEvent e)
{
try {
if ((row.getText()).length() > 0 && (col.getText()).length() > 0) {
ta.setForeground(Color.black);
n_row = Integer.parseInt(row.getText());
n_col = Integer.parseInt(col.getText());
matrix = new int [n_row+1][n_col+1];
tx = new TextField [n_row][n_col];
remove(sp);
sp = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
add(sp, BorderLayout.CENTER);
Panel pn2 = new Panel();
pn2.setLayout(new GridLayout(n_row, n_col, 10, 10));
for (int i1 = 0; i1 < n_row; i1++ ) {
for (int i2 = 0; i2 < n_col; i2++) {
tx[i1][i2] = new TextField(2);
pn2.add(tx[i1][i2]);
}
}
sp.add(pn2);
validate();
}
}
catch (NumberFormatException em) {}
}
/************/
/* 終了処理 */
/************/
class WinEnd extends WindowAdapter
{
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
}
/*****************************/
/* Fisher の直接確率(Swing)*/
/* coded by Y.Suganuma */
/*****************************/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Test {
public static void main (String[] args)
{
Fisher fr = new Fisher("Fisher の直接確率");
}
}
class Fisher extends JFrame implements ActionListener, DocumentListener
{
double bunshi, bunbo, d_sum, base;
int n_row, n_col, matrix[][], sum;
JTextField row, col, tx[][];
JTextArea ta;
JButton bt;
JScrollPane sp;
Container cp;
Font f = new Font("TimesRoman", Font.BOLD, 20);
/******************/
/* コンストラクタ */
/******************/
Fisher(String name)
{
// Frameクラスのコンストラクタ
super(name);
// Windowの大きさ
setSize(600, 400);
// レイアウト,背景色,フォント
cp = getContentPane();
cp.setLayout(new BorderLayout(5, 5));
cp.setBackground(new Color(225, 255, 225));
cp.setFont(f);
// 上のパネル
Panel pn1 = new Panel();
cp.add(pn1, BorderLayout.NORTH);
pn1.add(new Label("行の数"));
row = new JTextField(3);
row.setFont(f);
row.getDocument().addDocumentListener(this);
pn1.add(row);
pn1.add(new Label("列の数"));
col = new JTextField(3);
col.setFont(f);
col.getDocument().addDocumentListener(this);
pn1.add(col);
pn1.add(new Label(" "));
bt = new JButton("OK");
bt.setBackground(Color.pink);
bt.setFont(f);
bt.addActionListener(this);
pn1.add(bt);
// 中央のパネル
sp = new JScrollPane();
cp.add(sp, BorderLayout.CENTER);
// 下のパネル
Panel pn3 = new Panel();
cp.add(pn3, BorderLayout.SOUTH);
ta = new JTextArea(3, 24);
ta.setFont(f);
JScrollPane scroll2 = new JScrollPane(ta);
pn3.add(scroll2);
// ウィンドウを表示
setVisible(true);
// イベントアダプタ
addWindowListener(new WinEnd());
}
/******************************/
/* 上,左,下,右の余白の設定 */
/******************************/
public Insets getInsets()
{
return new Insets(70, 20, 20, 20);
}
/******************************/
/* ボタンが押されたときの処理 */
/******************************/
public void actionPerformed(ActionEvent e)
{
double x, s;
int i1, i2, k;
String str;
// 和の計算
for (i1 = 0; i1 < n_row; i1++)
matrix[i1][n_col] = 0;
for (i1 = 0; i1 < n_col; i1++)
matrix[n_row][i1] = 0;
sum = 0;
for (i1 = 0; i1 < n_row; i1++) {
for (i2 = 0; i2 < n_col; i2++) {
str = tx[i1][i2].getText();
if (str.length() > 0) {
matrix[i1][i2] = Integer.parseInt(str);
sum += matrix[i1][i2];
}
else
matrix[i1][i2] = 0;
matrix[i1][n_col] += matrix[i1][i2];
matrix[n_row][i2] += matrix[i1][i2];
}
}
// 実行
if (sum == 0) {
ta.setForeground(Color.red);
ta.setText(" データを入力してください\n");
}
else {
ta.setForeground(Color.black);
d_sum = kaijo(sum);
// 生起確率の計算
bunshi = 0.0;
for (i1 = 0; i1 < n_row; i1++)
bunshi += kaijo(matrix[i1][n_col]);
for (i1 = 0; i1 < n_col; i1++)
bunshi += kaijo(matrix[n_row][i1]);
bunbo = cal(matrix);
base = Math.exp(bunshi - bunbo);
ta.setText("生起確率: " + base + "\n");
// base より小さい確率の和
int mx[][] = new int [n_row+1][n_col+1];
k = 0;
s = 0.0;
while (k <= matrix[0][n_col] && k <= matrix[n_row][0]) {
for (i1 = 0; i1 < n_row; i1++) {
for (i2 = 0; i2 < n_col; i2++)
mx[i1][i2] = 0;
}
mx[0][0] = k;
s += set(mx, 0);
k++;
}
ta.append("確率の和: " + s + "\n");
}
}
/*******************************************/
/* 特定の状態における確率の分母(対数計算) */
/*******************************************/
double cal(int mx[][])
{
double s = d_sum;
int i1, i2;
for (i1 = 0; i1 < n_row; i1++) {
for (i2 = 0; i2 < n_col; i2++)
s += kaijo(mx[i1][i2]);
}
return s;
}
/**********************/
/* n の階乗(対数計算) */
/**********************/
double kaijo(int n)
{
double s = 0.0;
for (int i1 = 2; i1 <= n; i1++)
s += Math.log((double)i1);
return s;
}
/************************************/
/* 様々な状態における確率を計算 */
/* mx : 状態 */
/* i : 値を設定する位置 */
/* i/n_col 行 i%n_col 列 */
/************************************/
double set(int mx1[][], int i)
{
double x, y, s = 0.0;
int i1, i2, k, k1, k2, n, n1, n2, sw = 0, ss = 0;
// 周辺度数と一致しているかのチェック
for (i1 = 0; i1 < n_row; i1++)
mx1[i1][n_col] = 0;
for (i1 = 0; i1 < n_col; i1++)
mx1[n_row][i1] = 0;
for (i1 = 0; i1 < n_row; i1++) {
for (i2 = 0; i2 < n_col; i2++) {
mx1[i1][n_col] += mx1[i1][i2];
mx1[n_row][i2] += mx1[i1][i2];
ss += mx1[i1][i2];
}
}
for (i1 = 0; i1 < n_row && sw == 0; i1++) {
if (mx1[i1][n_col] != matrix[i1][n_col])
sw = 1;
}
if (sw == 0) {
for (i1 = 0; i1 < n_col && sw == 0; i1++) {
if (mx1[n_row][i1] != matrix[n_row][i1])
sw = 1;
}
}
// 一致している場合
if (sw == 0) {
y = cal(mx1);
x = Math.exp(bunshi - y);
if (x < base + 1.0e-10)
s = x;
// デバッグ用(計算した組み合わせの出力)
// for (i1 = 0; i1 < n_row; i1++) {
// for (i2 = 0; i2 < n_col; i2++)
// System.out.print(" " + mx1[i1][i2]);
// System.out.println();
// }
// System.out.println();
}
// 一致していない場合
else {
if (i < n_row*n_col-1 && (cal(mx1) + kaijo(sum-ss)) > bunbo - 1.0e-10) {
i++;
k1 = i / n_col;
k2 = i % n_col;
n1 = 0;
n2 = 0;
for (i1 = 0; i1 < n_row; i1++)
n1 += mx1[i1][k2];
for (i1 = 0; i1 < n_col; i1++)
n2 += mx1[k1][i1];
n1 = matrix[n_row][k2] - n1;
n2 = matrix[k1][n_col] - n2;
n = (n1 < n2) ? n1 : n2;
k = 0;
int mx2[][] = new int [n_row+1][n_col+1];
while (k <= n) {
if (k2 < n_col-1 || k2 == n_col-1 && mx1[k1][n_col]+k == matrix[k1][n_col]) {
if (k1 < n_row-1 || k1 == n_row-1 && mx1[n_row][k2]+k == matrix[n_row][k2]) {
for (i1 = 0; i1 < n_row; i1++) {
for (i2 = 0; i2 < n_col; i2++)
mx2[i1][i2] = mx1[i1][i2];
}
mx2[k1][k2] = k;
s += set(mx2, i);
}
}
k++;
}
}
}
return s;
}
/******************************/
/* 列数が変更されたときの処理 */
/******************************/
public void changedUpdate(DocumentEvent e) {}
public void removeUpdate(DocumentEvent e) {}
public void insertUpdate(DocumentEvent e)
{
try {
if ((row.getText()).length() > 0 && (col.getText()).length() > 0) {
remove(sp);
ta.setForeground(Color.black);
n_row = Integer.parseInt(row.getText());
n_col = Integer.parseInt(col.getText());
matrix = new int [n_row+1][n_col+1];
tx = new JTextField [n_row][n_col];
Panel pn2 = new Panel();
pn2.setBackground(new Color(225, 255, 225));
pn2.setLayout(new GridLayout(n_row, n_col, 5, 5));
for (int i1 = 0; i1 < n_row; i1++ ) {
for (int i2 = 0; i2 < n_col; i2++) {
tx[i1][i2] = new JTextField(2);
tx[i1][i2].setFont(f);
pn2.add(tx[i1][i2]);
}
}
sp = new JScrollPane(pn2);
cp.add(sp, BorderLayout.CENTER);
validate();
}
}
catch (NumberFormatException em) {}
}
/************/
/* 終了処理 */
/************/
class WinEnd extends WindowAdapter
{
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
}