<?php
/************************************/
/* Hopfieldネットワーク(連想記憶) */
/* Coded by Y.Suganuma) */
/************************************/
$a = array(3);
$a[0] = array(0, 0, 1, 1, 0, 0,
0, 0, 1, 1, 0, 0,
0, 0, 1, 1, 0, 0,
0, 0, 1, 1, 0, 0,
0, 0, 1, 1, 0, 0,
0, 0, 1, 1, 0, 0);
$a[1] = array(0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0);
$a[2] = array(1, 1, 0, 0, 0, 0,
1, 1, 1, 0, 0, 0,
0, 1, 1, 1, 0, 0,
0, 0, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1,
0, 0, 0, 0, 1, 1);
$n = 36;
$p = 3;
// 重みの設定(学習)
$W = array($n);
for ($i1 = 0; $i1 < $n; $i1++)
$W[$i1] = array($n);
for ($i1 = 0; $i1 < $n-1; $i1++) {
for ($i2 = $i1+1; $i2 < $n; $i2++) {
$W[$i1][$i2] = 0;
for ($i3 = 0; $i3 < $p; $i3++)
$W[$i1][$i2] += (2 * $a[$i3][$i1] - 1) * (2 * $a[$i3][$i2] - 1);
$W[$i2][$i1] = $W[$i1][$i2];
}
}
for ($i1 = 0; $i1 < $n; $i1++)
$W[$i1][$i1] = 0;
// 初期状態
mt_srand();
$u = array(36);
printf("パターン番号(0~1)と修正ユニット数 ");
fscanf(STDIN, "%d %d", $pn, $m);
for ($i1 = 0; $i1 < $n; $i1++)
$u[$i1] = $a[$pn][$i1];
for ($i1 = 0; $i1 < $m; $i1++) {
$k = intval(mt_rand() / mt_getrandmax() * $n);
if ($k >= $n)
$k = $n - 1;
if ($u[$k] > 0)
$u[$k] = 0;
else
$u[$k] = 1;
}
printf("初期状態:\n");
$k = 0;
for ($i1 = 0; $i1 < 6; $i1++) {
for ($i2 = 0; $i2 < 6; $i2++) {
printf("%2d", $u[$k]);
$k++;
}
printf("\n");
}
// 更新
$count1 = 0;
$count2 = 0;
$count3 = 0;
while ($count1 < 100) {
$count2++;
$sw = false;
$k = intval(mt_rand() / mt_getrandmax() * $n);
if ($k >= $n)
$k = $n - 1;
$s = 0;
for ($i1 = 0; $i1 < $n; $i1++)
$s += $W[$k][$i1] * $u[$i1];
if ($s >= 0) {
if ($u[$k] == 0) {
$sw = true;
$u[$k] = 1;
}
}
else {
if ($u[$k] > 0) {
$sw = true;
$u[$k] = 0;
}
}
if ($sw) {
$count1 = 0;
$count3++;
}
else
$count1++;
}
// 結果
printf("試行回数 = %d,更新回数 = %d\n", $count2, $count3);
$k = 0;
for ($i1 = 0; $i1 < 6; $i1++) {
for ($i2 = 0; $i2 < 6; $i2++) {
printf("%2d", $u[$k]);
$k++;
}
printf("\n");
}
?>