風の迷路

移転先:http://fermiumbay13.hatenablog.com/ ここはヤフーブログ終了に伴い12/15閉鎖します

全体表示

[ リスト | 詳細 ]

記事検索
検索

全162ページ

[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

[ 次のページ ]

本ブログはヤフーブログ終了に伴い12月15日に閉鎖します

フェルミウム湾です。ご無沙汰しております。
本ブログは2017年末をもって更新終了とし、以下の新ブログにすでに移転しております:

RPGツクールと数学のブログ
http://fermiumbay13.hatenablog.com/

本ブログはこのまま放置とし、ブログを消す気は全くなかったのですが、
ヤフーブログ自体が今年の12月15日に終了するとのことなので、
本ブログも自動的に12月15日に閉鎖ということになります;w;

それでは惜しいので、現在、本ブログの記事を移行計画中です。
ただ、おかしな記事も多いので、全部の記事を移行する気はありません。
全部見直して、残した方がよい記事のみ選定し、リメイクして
上記の新ブログの記事として投稿するようにしていきます。

本ブログが終了してしまうとURLも当然なくなってしまいますので、
本記事をリンク先に使って頂いている方は、記事がリメイクされましたら、
お手数ですが、そちらにリンク先を変えて頂ければまことに幸せです。

どの記事を移行するかは私の独断になってしまいますので、
この記事をぜひ移行して欲しい、など、もしありましたら、コメントしていただければ是非移行します。
(基本的にはこのブログにしか書いてないような技術内容は全て移すつもりです)
11月末までであれば対応できると思いますので、よろしくお願いします…!

イメージ 1

長かったねぇ。12年間、ありがとうございました。

ジオシティーズも終了して、ヤフーブログも終了してしまうので、
ヤフーさんとの関わりはもうなくなってしまうと思います……(知恵袋も最近のぞいてないもんね)
でもほんと、色々楽しかったです。ブログに投稿するぞ!っていうのを活力に
自分でもびっくりするぐらい色々編み出しては記事にしていけたように思います。

遊んでくれたみなさん、再三だけどありがとうございました。
これからもずっとがんばるよ。みんなもがんばってね。

開く コメント(0)

!あけましておめでとうございます!

このブログは既に放置され、新しいブログに移転して活動しています。

RPGツクールと数学のブログ
http://fermiumbay13.hatenablog.com/

今後は新ブログに記事が投稿され、このブログには投稿されなくなると思います;_;
でも、このブログを消すことはまずありません。
姑息にもこのブログにある記事を新ブログに転載している現状です。

じゃあ、なんで移転するのだというと
別にヤフーさん批判というわけではないですが、リニューアルされてしまうじゃないですか。
ヤフーブログが一新し、過去に書いた記事もレイアウトなど含めて大きく変わってしまうようで、
今までの投稿がどんなことになるのかちょっと怖くなったので、
逃げという意味ではてなブログに移転することにした、というだけのことです。
新ブログでも投稿のスタイルは全く変わりません。
むしろ数式などを新ブログの方が書きやすいので、今までより見やすい投稿が
出来るんじゃないかと思っています。

ということで、今まで読んで頂いた多くの皆さま本当ありがとうございました。
新ブログのほうもごひいきにです。
何度も書きますが、本ブログを閉鎖とか削除はしませんよ コメントいつでもウェルカムです!

あとがき(切実な会)

イメージ 1

ヤフーブログで10年続けてきました。(放置の時期は多かったわけですが)
言葉の通り10年一昔に感じるものがありまして、10年前はまさかここまで
ブログを書こうという気もなく、そしてこんなに著者自身が
ブログに翻弄されることになるとも思っていなかったことでしょう。

各年の活動の様子を表にまとめましたよ:

濃密度合い(適当)主な内容
2007★★☆☆☆ネタ目的で開設 ゲーム投稿を始め、活発に
2008★★☆☆☆気分で投稿
2009★☆☆☆☆消沈気味 このまま凍結が予想された
2010★★★★☆趣味仲間の出現により一気に加速 第一次活動期と称する(?)
2011★★★☆☆勢いは弱まるが、平常運転
2012★★★★★一番ブログしてた時期 第二次活動期と称する(?)
2013★★☆☆☆友人関係を拗らせて低迷
2014★★☆☆☆低頻度ではあるが気分で投稿を続ける
2015★★☆☆☆さらに低迷 しかし後半に謎のやる気を得て一人で活発化
2016★☆☆☆☆活発化虚しく低迷は続く
2017★☆☆☆☆落ち切った 収束 もうだめだ;w;

開設からちょうど5年目あたり(2012年あたり)が投稿のピークでして
ブログ友達さんと好き勝手に自分のことやお友達さんのことを書き合う文化が根付き、
高頻度で楽しく記事を投稿させてもらっておりました。
ブログを書き合うようなモチベーションでもないと続かないというのは、
上の表からも明らかですね;w; 自分自身が一番びっくりしてますよ。

あんまり悲観的なことばっかり書いていてもしょうがないので
振り返りはこのあたりにしておき、今年もがんばっていきましょう。
幸いにも前年2017年は、ブログの投稿が少なかっただけであって
活動はしており、水面下で色々と充実しておりました。
新ブログで是非とも第三次活動期を起こしていきたいですね。

新ブログもよろしくね ぜひ来てね! 待ってるよ><
ほらもう一回リンク貼るから:
http://fermiumbay13.hatenablog.com/

またこんど!!

開く コメント(2)

XOR交換アルゴリズム

プログラミングで値の交換をするとき、ちょっと困ることがあります。
例えば、変数Aと変数Bがあったとして、Aの値をBに、Bの値をAに、それぞれ交換することを考えます。
しかしプログラムでは値のコピーはできても、値の交換を直接行うことができません。
A=1234、B=5678を交換しようとして、AにBの値をコピーしてしまうと
A=5678、B=5678となってしまい、もともとのAの値であった1234が消えてしまいます。
これでは交換できませんね。そのため普通は下の図のように、もう一つ変数を用意する必要があります。

イメージ 1

一時変数tempにAの値をコピーすることで、Aの値を退避させておきます。
それからBの値をAにコピーして、最後にtempの値をBにコピーします。これで交換ができます。

このように、変数の交換はちょっと手間なのです。
現実でもそうですよね。両手がふさがっているときは、
一旦どちらかをどこかに置いて片手を空けてから交換を行います。それと同じことです。

イメージ 2

ところが、整数のデータに限ってはこのtempがなくても交換できる
XOR交換アルゴリズムというものを使うことができます。
XORという演算を使えば、不思議なことが起こってAとBが交換されるのです。

XOR交換アルゴリズム

XOR(排他的論理和)とは、次のような2進数の演算です。

イメージ 3

例えば、12 XOR 15 = 3 になります。
それぞれ2進数に直すと、12は1100、15は1111、となり、これを筆算のように縦に並べます。
これを足し算の筆算のように各桁足し算していくのですが、普通の足し算とは異なって
1+1=0となるように計算します。
上の例では0+1=1となっていますが、1+1=0となるので、上の桁が落ちていって
0011が答えとなります。0011は10進数に直すと3ですから、3が答えになります。

そして、このXORを使って、次のような計算を順番に行っていきます。

A XOR B の値をAに代入
A XOR B の値をBに代入
A XOR B の値をAに代入

A XOR B をひたすら計算しながら代入していくだけですね。A=12, B=15の例で実際にやってみます。

12 XOR 15 = 3 をAに代入 … A=3, B=15
3 XOR 15 = 12 をBに代入 … A=3, B=12
3 XOR 12 = 15 をAに代入 … A=15, B=12

なんと、AとBの値が入れ替わっていますね!
このように、XORを使うとtempを使わずに値の交換が出来てしまうのです。

イメージ 4

回路図のイメージは上図のようになります。
途中にある3つの素子がXOR演算を表していて、左の二入力に対するXORの結果が右に出ます。

イメージ 5

上はA=1234、B=5678の例です。確かにAとBが交換されていますね。

交換の仕組み

XORを使うと何で値の交換が出来るのか確認してみます。
XOR演算には、次のような性質があります。

 結合法則が成り立つ … (A XOR B) XOR C = A XOR (B XOR C)
 交換法則が成り立つ … A XOR B = B XOR A
 自分自身との演算結果が0(単位元)になる … A XOR A = 0

これら3つの性質のおかげで、XOR交換アルゴリズムが実現します。
手順ごとに格納される値を確認していきます。
AとBの値がどんどん変わっていきますので、最初の値をそれぞれA1, B1とします。

A1 XOR B1 = A2とする
A2 XOR B1 = B2とする
A2 XOR B2 = A3とする

B2=A1, A3=B1になって値が入れ替わっている、という手順でした。
それぞれ求めていきます。

B2 = A2 XOR B1 = (A1 XOR B1) XOR B1
= A1 XOR (B1 XOR B1) … 結合法則
= A1 XOR 0 … 自分自身が逆元
= A1 … 0は単位元

A3 = A2 XOR B2 = (A1 XOR B1) XOR A1
= (B1 XOR A1) XOR A1 … 交換法則
= B1 XOR (A1 XOR A1) … 結合法則
= B1 XOR 0 … 自分自身が逆元
= B1 … 0は単位元

以上のように、確かに B2=A1, A3=B1 が成り立っています。
これがXORを使って値交換が出来る仕組みです。
逆に言えば、最初に挙げた3つの法則を持っている演算なら同様にして交換アルゴリズムに使えるのです。

他の演算を使った例

結合法則、交換法則が成り立ち、さらに自分自身と演算すると単位元になる、
という3つの法則を持った演算なら、XORでなくてもこの交換アルゴリズムは使えます。
あんまりそういう演算の例がないのですが、例えばこんなものがあります。

√a×√b=√(ab) を計算し、ルートの外に係数で出せるものを出して整理して、k√cとなるとき
a ☆ b = c と表す演算子☆

この演算子☆は、上記の3つの法則が成り立ちます。
ただし、a, b, cの素因数にもともと偶数乗の素因数が入ってしまっていると
何もしなくてもルートの外に出てしまうので、そういう値には適用できません。
実用性はないでしょう……単なる例です。

A ☆ B の値をAに代入
A ☆ B の値をBに代入
A ☆ B の値をAに代入

A=1234, B=5678 でやってみましょう。
√1234も√5678も、これ以上ルートの中身が整理できないので、このアルゴリズムが適用できます。

√1234×√5678=2√1751663 より A=1751663, B=5678
√1751663×√5678=2839√1234 より A=1751663, B=1234
√1751663×√1234=617√5678 より A=5678, B=1234

確かに入れ替わりましたね!

割と自分自身が逆元という性質を満たす演算を探すのが難しいですが、
見つけることができればこのように交換アルゴリズムを考えることができます。
いろいろ探してみて、ぜひ遊んでみましょう^^!


余談ですが、XORのグラフは下図のようになります。
X座標、Y座標に対する点の明るさを X XOR Y の大きさにしています。(明るいほど大きな値)
キレイなフラクタル図形になるのですね! 2進数の演算をグラフにすると割と幾何学模様が現れて面白いです。

イメージ 6

開く コメント(0)

論理回路のシミュレーションをプログラミングで行うための支援ライブラリを作りました。
https://github.com/fermiumbay/LogicSimulator

論理計算を行うだけであれば、単に計算式を記述して答えを出させれば済みますが、
このライブラリは素子を登録してそれぞれ接続し、回路を作ることが出来るのが特徴です。
計算式に基づいて出力値が出るのではなく、出力値を得たい素子の値からたどって計算を行います。
素子を接続して実装することから、順序回路のような循環している回路も作成できます。

本ライブラリはC++用です。(C++11以降)

導入

上のリンクからLogicParts.hとLogicParts.cppをダウンロードし、
cppファイルをコンパイルするソースに入れてください。
使用するときはLogicParts.hをインクルードします。

イメージ 1

例えば上のような回路を実装する場合は次のように記述します。

#include <iostream>
using namespace std;

#include "LogicParts.h"
using namespace LogicParts;

int main() {
    auto A = Terminal();    // 端子Aの定義
    auto B = Terminal();    // 端子Bの定義
    auto C = And(Or(A, B), Nand(A, B));    // 端子Cに論理回路を接続

    A->set(0);    // 端子Aに入力値0をセット
    B->set(1);    // 端子Bに入力値1をセット

    cout << C->get() << endl;    // 端子Cの値を出力
}

最初に各端子を定義して論理回路を作ります。
変数の型は面倒なのでautoで宣言していますが、BaseParts*でもOKです。
後は端子にset関数で入力値をセットして、出力値を得たい端子のget関数を呼べばOKです。
上の例はXor回路なので、A=Bのとき0、A≠Bのとき1が返ります。

半加算器

イメージ 2

上図は半加算器HAの例です。出力が2つありますが、同様にして回路を作れます。

#include <iostream>
using namespace std;

#include "LogicParts.h"
using namespace LogicParts;

int main() {
    auto A = Terminal();    // 端子Aの定義
    auto B = Terminal();    // 端子Bの定義
    auto C = And(A, B);    // 端子CにAnd素子を接続
    auto S = Xor(A, B);    // 端子SにXor素子を接続

    A->set(0);    // 端子Aに入力値0をセット
    B->set(1);    // 端子Bに入力値1をセット

    cout << C->get() << endl;    // 端子Cの値を出力
    cout << S->get() << endl;    // 端子Sの値を出力
}

このHAの部分だけを一つの部品として、
次のように関数を作っておくと便利です。

#include <iostream>
using namespace std;

#include "LogicParts.h"
using namespace LogicParts;

// 半加算器(A, B) = (C, S)
vector<BaseParts*> HA(BaseParts* A, BaseParts* B) {
    auto C = And(A, B);    // 端子CにAnd素子を接続
    auto S = Xor(A, B);    // 端子SにXor素子を接続
    return { C, S };	// 出力端子の配列を返す
}

int main() {
    auto A = Terminal();    // 端子Aの定義
    auto B = Terminal();    // 端子Bの定義
    auto D = HA(A, B);    // 端子DにA, Bを接続したHAを接続
    auto C = D[0];    // A, Bを接続したHAの出力C
    auto S = D[1];    // A, Bを接続したHAの出力S

    A->set(0);    // 端子Aに入力値0をセット
    B->set(1);    // 端子Bに入力値1をセット

    cout << C->get() << endl;    // 端子Cの値を出力
    cout << S->get() << endl;    // 端子Sの値を出力
}

全加算器

イメージ 3

HAを接続して全加算器FAを作ります。

#include <iostream>
using namespace std;

#include "LogicParts.h"
using namespace LogicParts;

// 半加算器(A, B) = (C, S)
vector<BaseParts*> HA(BaseParts* A, BaseParts* B) {
    auto C = And(A, B);    // 端子CにAnd素子を接続
    auto S = Xor(A, B);    // 端子SにXor素子を接続
    return{ C, S };	// 出力端子の配列を返す
}

// 全加算器(A, B, prevC) = (C, S)
vector<BaseParts*> FA(BaseParts* A, BaseParts* B, BaseParts* prevC) {
    auto D = HA(A, B);    // HAの出力を端子群Dとして定義
    auto E = HA(D[1], prevC);    // HAの出力を端子群Eとして定義
    auto C = Or(D[0], E[0]);    // HAの出力とOr素子を接続して端子Cに接続
    auto S = E[1];    // HAの出力を端子Sに接続
    return{ C, S };	// 出力端子の配列を返す
}

int main() {
    auto A = Terminal();    // 端子Aの定義
    auto B = Terminal();    // 端子Bの定義
    auto prevC = Terminal();    // 端子prevCの定義
    auto C = FA(A, B, prevC)[0];    // A, Bを接続したFAの出力C
    auto S = FA(A, B, prevC)[1];    // A, Bを接続したFAの出力S

    A->set(1);    // 端子Aに入力値1をセット
    B->set(1);    // 端子Bに入力値1をセット
    prevC->set(1);    // 端子prevCに入力値1をセット

    cout << C->get() << endl;    // 端子Cの値を出力
    cout << S->get() << endl;    // 端子Sの値を出力
}

一旦部品を作ってしまえば取り扱いが楽になります。

RSフリップフロップ

イメージ 4

入力端子を循環させれば順序回路も作れます。

#include <iostream>
using namespace std;

#include "LogicParts.h"
using namespace LogicParts;

// RSフリップフロップ
vector<BaseParts*> RS_FF(BaseParts* S, BaseParts* R) {
	auto Q = Nand(Not(S), 0);    // 端子Q
	auto notQ = Nand(Not(R), Q);    // 端子notQ
	Q->input[1] = notQ;    // 端子Qの入力端子の一つにnotQをセット

	return{ Q, notQ };	// 出力端子の配列を返す
}

int main() {
	auto S = Terminal();    // 端子Sの定義
	auto R = Terminal();    // 端子Rの定義
	auto Q = RS_FF(S, R)[0];    // 出力QをA, Bを接続したHAの出力C

	S->set(0); R->set(0); cout << Q->get() << endl;    // 保持
	S->set(1); R->set(0); cout << Q->get() << endl;    // Q=1にセット
	S->set(0); R->set(0); cout << Q->get() << endl;    // 保持
	S->set(0); R->set(1); cout << Q->get() << endl;    // Q=0にセット
	S->set(0); R->set(0); cout << Q->get() << endl;    // 保持
}

notQが未定義の状態でQ = Nand(Not(S), notQ)とは出来ませんから、
上記のように、一旦notQの部分は0(未接続)としておいて、
notQを作ってからQの入力端子にnotQをセットする、という方法で接続しています。


うまいように設計してやれば、大規模な論理回路も作れそうですね!

開く コメント(0)

RPGツクール2000ではプログラミング言語を使えないので、
計算式を入力して直接計算するということが出来ません。
難しい計算を入れようと思うと、変数を一個一個定義して
それらの四則演算を駆使する必要があります。

1+2×3 みたいな式であれば、優先度の高い掛け算の方を先に計算して
◆変数1番 = 2(2を代入)
◆変数1番 × 3(3倍する)
◆変数1番 + 1(1足す)
みたいにしてやれば、1個の変数で足ります。

しかし、2×3+4×5 のような式を計算する際は変数1個では足りません。
一時的に計算用の変数を用意しておいて、それを途中計算で使うことになります。
◆変数1番 = 2
◆変数1番 × 3
◆変数2番 = 4
◆変数2番 × 5
◆変数1番 + 変数2番

一般に、計算式が複雑になればなるほど一時変数は多く必要になります。
では、最低何個あれば足りるのか、というのを計算式から判断できるでしょうか。

使用変数の個数計算アルゴリズム

イメージ 1

まず、上のように計算式をツリー構造に置き換えます。
一つ一つの丸のことをノードと呼びます。
2+3×5だったら3×5を先に計算するので、3と5を×の木で結び、
その結果と2を足すので、それぞれを+の木で結びます。
計算するときは、下から順にまとめていけばいいですね。

上の式なら次のように1つの変数があれば計算できます。
◆変数1番 = 3
◆変数1番 × 5
◆変数1番 + 2
3×5の結果を使い、それに2を足せばOKです。

イメージ 2

計算によって各ノードに至るまでに必要な使用変数の個数を下に数字で書いています。
ただの数値は基本変数を使わないので0としていますが、
初めの3×5の計算を行うために、3か5のどちらかを一旦変数に入れないといけません。
ここでは3を入れるものとし、3に変数を一つ使っています。
3×5の計算結果を変数1番に入れればよいので、×の使用変数は1となっています。
さらに、それに足した結果をそのまま変数1番に入れますから、
+の使用変数はそのまま1となります。

イメージ 3

複雑な式になっても同じです。
ただ、引き算や割り算のように交換法則が成り立たない演算の場合は
左の数の方を必ず変数に入れなければなりません。
それに注意しながら使用変数の個数を振っていくと上図のようになります。
◆変数1番 = 1
◆変数1番 ÷ 5
◆変数2番 = 1
◆変数2番 − 変数1番
◆変数2番 = 8
◆変数2番 ÷ 変数1番
1÷5ではまず変数1番に1を入れておき、そこから5を割り算。
次に1からその結果を引く必要がありますが、変数1個では無理なので
変数2番を用意して、そこに1を入れておき、変数2番から変数1番を引けばOKです。
(A−B=−(B−A)でいいじゃんというツッコミは禁止です^^;)
これを繰り返し、変数2個で計算できるということが分かります。

では、子ノードの値から親ノードの値を求めるにはどうすれば良いでしょうか。

そのノードに振られている値は、言わば計算がそこに至るまでに
使用した変数の最大個数を表します。
例えば上の式では「−」の部分で2となっていますが、
−の計算を終えた直後はもう変数1番しか使っていないので、変数2番が使えます。
8をわざわざ変数3番に入れなくても、使っていない変数2番に入れれば済みます。
だから、最後の「÷」は1+2=3個ではなく、
それまでの最大個数であった2個がそのまま÷に振られます。

演算を行う際には、各演算に用いるノードで使用変数が多かった部分を先に計算して
計算時に変数1個としておくことで、使用変数の節約が出来るようになります。

イメージ 4

上図でいうと、使用変数が0個で済む2の方ではなくて、
使用変数が1個必要な3×5の方を先に計算すると最大個数が少なくて済みます。

イメージ 5

上図のように使用変数が1個必要なもの同士を使って演算する場合は、
変数1番に左の×の結果を、変数2番に右の×の結果を入れて足し算する必要があるので、
変数は2個必要になります。

以上のことから、使用変数の個数について次の法則が言えます。

【四則演算における親ノードの使用変数個数】
2つの子ノードの使用変数個数がそれぞれa, bとすると、
・a≠bのときmax{a, b}(a, bのうち大きい方)
・a=bのときa+1

使用変数個数がお互い同じときしか個数が増えないということになります。
さっきの例がその法則に従って得られるか確認してみてください。


下のイベント命令は、変数1番に角度を入れると
sinの値を計算して、変数2番にその100倍の値を入れるものです。

◆変数の操作:[0003:一時]代入,変数[0001]の値
◆変数の操作:[0003:一時]乗算,変数[0001]の値
◆変数の操作:[0003:一時]乗算,64
◆変数の操作:[0003:一時]除算,2025
◆変数の操作:[0002:結果]代入,変数[0003]の値
◆変数の操作:[0002:結果]乗算,-20
◆変数の操作:[0002:結果]加算,12000
◆変数の操作:[0003:一時]乗算,変数[0003]の値
◆変数の操作:[0003:一時]除算,100
◆変数の操作:[0002:結果]加算,変数[0003]の値
◆変数の操作:[0002:結果]乗算,変数[0001]の値
◆変数の操作:[0002:結果]除算,6750
◆変数の操作:[0002:結果]乗算,変数[0004]の値
◆
http://www.geocities.jp/orreiclan/content/report/tkool2000math/sin.html

一時変数を含めて変数を3個使っていますが、本当に3個必要なのか確認しましょう。
この計算過程を下図のようなツリー構造にします。

イメージ 6

たどっていくと、確かに3になっていることが分かりますね。

このように、何らかの計算アルゴリズムを作ったときに
その必要な使用変数の個数を求める際に便利だと思います。
ツクール2000では使えますが、最近のツクールだとあまり使わないかもしれませんね。

開く コメント(0)

全162ページ

[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

[ 次のページ ]


.


プライバシー -  利用規約 -  メディアステートメント -  ガイドライン -  順守事項 -  ご意見・ご要望 -  ヘルプ・お問い合わせ

Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.

みんなの更新記事