周期境界条件を用いたプログラム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
とうや

周期境界条件を用いたプログラム

#1

投稿記事 by とうや » 16年前

いつもお世話になっています。
今回はC言語について質問させていただきます。

~~~~~~~プログラムについて~~~~~~~~
■渋滞のプログラムを作成中です。
概要として…
0=何もない
1=車がある
と思ってください。
例として…
『0010101110010』
とあった場合です。
※右端と左端は連続したものと考えてください

「条件」
●1(車)は前に移動する
●1は前に0の場合前に進むことが出来る
●1は前に1があった場合その場にとどまる
です。
これを複数回繰り返しています。
例題を動かすと・・・
例→『0010101110010』
次→『0001011101001』
次→『1000111010100』
のように動いていきます。
(*プログラム参照)

今回はこのプログラムを作成し、このプログラムを元に次のプログラムを作成しようと考えていたところ
どのようにすればよいか分からなくなったため質問しました。

~~~~~~作りたいプログラム~~~~~
先ほどの●の条件に加え
●1がある確率で0になる
●0がある確率で1になる
としたいと思っています。
rand time 関数などを使えばよいのかな?と思って作成していたのですが
上手くいきませんでした。
アドバイス・意見よろしくお願いします。

conio

Re:周期境界条件を用いたプログラム

#2

投稿記事 by conio » 16年前

srand関数と、rand関数を使えばいいと思います。
-------------------------------------
srand(time(NULL));

if(rand() % 5 == 4)
x = (x + 1) % 2
-------------------------------------

xに1を足して2で割れば、
xが0の場合は、xは1に、
xが1の場合は、xは0になります。

あとはこの処理が実行される確率を決めてあげればいいと思います。(ここでは約5分の1)
こんな感じで、どうでしょう?

とうや

Re:周期境界条件を用いたプログラム

#3

投稿記事 by とうや » 16年前

ありがとうございます!
しかし、その部分をプログラムのどの部位に入れたら良いか分からず迷っています。
アドバイスよろしくお願いします。

組木紙織

Re:周期境界条件を用いたプログラム

#4

投稿記事 by 組木紙織 » 16年前

今、プログラムを解析中です。
Windows環境でコンパイルするとエラーが出ますね。
ちょっとそれで引っかかりました。
別すれも言及がありましたが、C99で作っていますね。
それも引っかかってしまいました。


根本的な問題なので聞きたいのですが、

条件と例の動きが一致していないように思います。
本当にその条件、その動き方でいいのでしょうか?
再検討を願います。

組木紙織

Re:周期境界条件を用いたプログラム

#5

投稿記事 by 組木紙織 » 16年前

一通りプログラム読んでみました。

このまま変更かけるよりは、
最初から全部作り直したほうが速そうです。
まずは、設計をきちんとすべきですね。


気づいていないかもしれない問題点があります。
添付してもらったプログラムはそれぞれの車の総移動距離を最後に出しますよね。
途中で消えた車と、途中で入ってきた車はどうするのですか?

とうや

Re:周期境界条件を用いたプログラム

#6

投稿記事 by とうや » 16年前

解析ありがとうございます
環境としてUnix(Linux)環境で作成しています
PC自体譲り受けたものですので詳しいことが分かりません。
調べてみたいと思います。
C99、C95、C90などの区別も詳しくは分かっていないのですが・・・

Windows環境でプログラムを作ったことがないので、Windowsでの動作確認は行っていません。
まことに申し訳ございません。

私のPC上の動作確認では・・・
gnuplot上で円系に●が動く形になっています。

例1
n   ○●○●○●●● (右と左は繋がっている)
n+1  ●○●○●●●○
n+2  ○●○●●●○●
n+3  ●○●●●○●○
n+4  ○●●●○●○●
のような形が円状になっています。
動作中の1コマを添付しました。

条件としては、
●1は前に移動する
●1は前に0の場合前に進むことが出来る
●1は前に1があった場合その場にとどまる
が基本なことに変わりはありません。
ただ、●がある確率で○に・・・
   ○がある確率で●に・・・
変わるようなプログラムを作成したいと思っています。
それはランダムな●、○にしたいと思っています
確率が0の場合は例1のような形から変更はなしといって形です。
確率が100の場合は反転するという形に
(反転後次の時間に移動、移動後に反転は現段階ではどちらでもよいと思っています)


現在UPしているプログラムをそのまま使わずに
もっと良い方法があればアドバイス下さると助かります。
親切な質問ありがとうございます。
分からないことがあれば色々聞いてください。精一杯お答えしようと思います。

どうや

Re:周期境界条件を用いたプログラム

#7

投稿記事 by どうや » 16年前

問題点の指摘ありがとうございます。
総移動距離のことは気づいていませんでした。
今回では、移動距離よりも、どれくらい込み合うかのプログラムを作ろうと思っています。

どれくらいの確率で車が入ってくれば渋滞するのか
どれくらいの確率で車が出れば全く渋滞しなくなるのか

その境目を調べてみたいと思っています。

アドバイスありがとうございます

組木紙織

Re:周期境界条件を用いたプログラム

#8

投稿記事 by 組木紙織 » 16年前

>条件と例の動きが一致していないように思います。
>本当にその条件、その動き方でいいのでしょうか?
>再検討を願います。

ここは勘違いがあったので修正です。
元々の条件とプログラムの動作が一致していないので、
その部分は問題がないのでしょうか?
(多分条件文のほうが正しいとは思いますが。)

また、プログラム上での移動方向と例での移動方向が異なっているのも問題はないのでしょうか?

アドバイスとしては、
まずは、設計をして、
確率変動しない場合のコードを作り直してみてください。
(その際自分に必要ない部分は出来るだけ省くこと)

そのときの考え方は
道は一本なんですよね。
なら一次元配列を道に見立てればよいです。
車の位置ですが、一次元配列にそのまま書き込んであげればよいかと。
次に車の動き方ですが、それは添付してあるコードを参考にすればいいです。

#コメントを見る限りでは大学の研究のようなので、回りに聞ける人がいると思うのでそっちのほうが速いと思いますが。

conio

Re:周期境界条件を用いたプログラム

#9

投稿記事 by conio » 16年前

①車は前(右)に進む
②ループして戻ってくる(一番左に戻る)
③前(右)に車があった場合動かない

とりあえず、参考になるかは分かりませんがこの条件だけでプログラムを作ってみました。
突貫作業で作ったのでミスなどあるかもしれません。
-------------------------------------------------------------
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <windows.h>

#define NUM 20


int a[NUM] = {0};

void set(void)/*車を配置する。*/
{
	srand((unsigned)time(NULL));

	for(int i = 0; i < NUM; i++)
		a[ i ] = rand() % 2;
}

void hyouzi(void)/*現在の状態を表示する*/
{
	for(int i = 0; i < NUM; i++)
		printf("%d┃",a[ i ]);
	printf("\n");
}

void idou(void)/*車を右に移動させる*/
{
	for(int i = 0; i < NUM; i++)
		if(a[ i ] != 0 && a[(i + 1) % NUM] == 0){
			a[(i + 1) % NUM] = 1;
			a[ i ] = 0;
			i++;
		}
}

int main(void) 
{ 
	set();

	while(1){
		hyouzi();
		idou();
		Sleep(3000);
	}


return(0);
} 
-------------------------------------------------------------

とうや

Re:周期境界条件を用いたプログラム

#10

投稿記事 by とうや » 16年前

様々なアドバイスありがとうございます!
今から新たしくプログラムを作成しようと思います。

組木紙織

Re:周期境界条件を用いたプログラム

#11

投稿記事 by 組木紙織 » 16年前

C++でサンプルコードを書いてみました。

動作確認にどうぞ。

Justy

Re:周期境界条件を用いたプログラム

#12

投稿記事 by Justy » 16年前

> 組木紙織さん
 最初の方しか見ていないのですが、


>get_rand()

 Unixでコンパイルしたとき、RAND_MAXが 0x7fffffffだったりすると、
get_rand()でおかしなこと(オーバーフロートとか)になりませんか?



>struct grand

 関数オブジェクトを実行するとき毎回 srandが time()を伴って呼ばれていますが、
これって前回実行時とほとんど差がない場合、毎回同じ値を rand()が出力してしまうのでは
ないでしょうか?



>std::random_shuffle(road.begin(),road.end(),grand())

 この行もちょっとおかしいです。grandの一時変数を 非constな参照で渡しています。

組木紙織

Re:周期境界条件を用いたプログラム

#13

投稿記事 by 組木紙織 » 16年前

Justyさん

言われて見ればそうでした。
最近C++を本気で触ってないので、リハビリのためにかいてみましたが、
出直してきます。

non

Re:周期境界条件を用いたプログラム

#14

投稿記事 by non » 16年前

最初の説明では

     →進行方向
例→『0010101110010』
次→『0001011101001』
次→『1000111010100』

でしたが、次の説明では、
     ←進行方向
n    ○●○●○●●● (右と左は繋がっている)
n+1  ●○●○●●●○
n+2  ○●○●●●○●
n+3  ●○●●●○●○
n+4  ○●●●○●○●

となっています。
文章で書かれた条件からすれば、最初の方が正しいのかと思いますが、
下のは、現在のプログラムはこうなっているからまずいという説明だったのでしょうか?


要するに自動車は一斉に動くのか、順番に動くのかです。
自然の状態なら、電車のように同速度で動いて問題ないけど、
車の渋滞のような場合だと、ワンテンポ、スタートが遅れますものね。
さて、どっち?

conioさんのプログラムでは配列の0番からスタートしていますが、最後のNUM-1番目の車は
0番目の位置を見に行きますが、このときすでに0番目の車は1番目に動いているので
まずいと思われます。

non

Re:周期境界条件を用いたプログラム

#15

投稿記事 by non » 16年前

ものすごい勘違いをしてました。
     進行方向→
n    ○●○●○●●● (右と左は繋がっている)
n+1  ●○●○●●●○
n+2  ○●○●●●○●
n+3  ●○●●●○●○
n+4  ○●●●○●○●

進行方向が逆でした。2つの説明はまったく同じでした。大変失礼しました。

とうや

Re:周期境界条件を用いたプログラム

#16

投稿記事 by とうや » 16年前

C++のサンプルコード アドバイスありがとうございます。
C++は触ったことがないので、これを機に勉強(解読)します。

閉鎖

“C言語何でも質問掲示板” へ戻る