2022/10,江端さんの忘備録

モノを作る技術、というのは、一種の保険であると考えており、私は、(会社の仕事はサボっても)、流行りの技術のキャッチアップだけは怠らないように努めてきました。

I believe that the art of making things is a kind of insurance policy, and I have always tried to keep up with the latest trends in technology (even if I skip company work).

で、今、これを見て、心底驚愕しています。

And now, I am truly astonished to read this.

―― 何か怖いものを見た

"I watched something scary"

という感じです。

It is like that.

-----

もっともメーカーでなくても、「技術」は必要ですが、その技術は、人間の存在を前提とする技術 ―― コミュニケーションとか、人たらしとか、セールストークとか、カリスマとか ―― がメインになるのではないか、と思うのです。

I think that even if you are not a engineer, you still need "technology," but that technology should be mainly based on the existence of human beings--communication, charisma, sales talk, charisma, and so on.

その認識自体、すでに見誤っているのでしょうか?

Is that perception itself already misguided?

例えば、私の場合、明日会社を放り出されても、『パソコンがあれば、なんとかなるだろう』という漠然(ばくぜん)とした期待があります。

For example, in my case, I have a vague expectation that even if I am thrown out of the company tomorrow, I will be able to get by with a computer.

大抵の装置であれば、マニュアル読めば動かすことができるだろう、とも思っています。

I also believe that if I read the manual, I will be able to run most machines.

これが、人間の存在を前提としない「モノを作る技術」であり「一種の保険」と思っているものです。

This is what I consider a "technology of making things" and "a kind of insurance" that does not presuppose human existence.

-----

近年は、都市設計とか、地域サービスとか、地域復興とか、モノ作りの興味が変化していっているのは知っていますが ―― だとしても、

I know that in recent years, urban design, community service, and community revitalization have been popular -- however, I think, that

『その設計した何かは、ハードウェアと、プログラムと、データベースと、スマホなしでは動き出さんぞ』

"Something you've designed doesn't start working without hardware, program, database, and smartphone."

とは、思うのです。

2022/10,江端さんの忘備録

コンピュータのリソース不足を補う為に、Windows7のままで放置してあったPCを、昨日にWindows10に移行して、docker環境を作り込んでいました。

To compensate for the lack of computer resources, I had migrated my PC, which had been left in Windows 7, to Windows 10 yesterday to create a docker environment.

嫁さんの中では、『私が自分のプログラムの為だけにローカルに作った実験用の小規模データベース』は、データベースに含まれていないようです ――

dockerのイメージだけを、リモートに送り込む等、夜遅くまで、色々試していたのですが、データベース丸ごとをイメージにするのは難しく、docker export/import/save/load 全部を試した挙げく、

I was up late at night trying various methods, such as sending docker images to a remote location, but it was difficult to create an image of the entire database, and after trying docker export/import/save/load everything,

―― コンテンツ本体を、手動でUSBメモリにコピーして、現在、DB再構築の真っ最中

"Manually copied the content itself to a USB memory stick, currently in the middle of rebuilding the DB"

という体らくです。まあ、一人で作っているプログラムなので構わないのですが。

Well, I don't mind, since it is a program that I am making alone.

私としては、管理するPCは、あまり増やしたくないのですが、仕方ありません。

As for me, I don't want to add too many PCs to be managed, however I have no choice.

データベースの過負荷でシミュレーションが止ってしまうのを、放置し続ける訳にもいきませんから。

I cannot leave the simulator stopped due to database overload.

-----

私、100円のアイスクリームと、200円のアイスクリームを購入で、余裕で3分間は悩むことができます。

I need three minutes to annoy to choose between getting 100 yen or 200 yen icecream.

しかし、30万円のゲーミングPCを、自分のシミュレータを動かす為に購入することに関しては、あまり悩みません。

However, I wouldn't worry too much about buying a $300,000 gaming PC to run my simulator.

なにしろ、苦学生していたころ、定価85万円のパソコンを、「現金」で購入していたくらいです。

When I was a struggling student, I had purchased a computer with a list price of 850,000 yen with cash.

-----

『高スペックな計算機を追い求める』ことは、エンジニアにとっての「呪い」のようなものです。

The "pursuit of high-specification computer" is like a "curse" for engineers.

これまで何度も書いていますが、当時85万円のPCは、現在の5000円のボードコンピュータに勝てません(というか、その当時の、スパコンにも勝てません)

As I have written many times in the past, an 850,000 yen PC (a supercomputer too) at that time cannot beat even a 5,000 yen board computer today.

常識のあるエンジニア&研究員は、「スペック」に踊らされてはならないのです。

Engineers & researchers with common sense should not dance around the "spec.".

この本の題目(内容)は、私の生き方とは相容れませんが、

Although the subject (content) of this book is incompatible with my way of life

『置かれた環境で、計算しなさい』

"Do the math in your environment"

と読み替えるのであれば、正しい示唆だと思います。

If it is to be read this way, I think it is a correct suggestion.

2017,江端さんの技術メモ

/* 
   gcc -g ql_test.cpp -o ql_test
 
   強化学習(Q-Learning)を理解する為に、中学→高校→大学の学歴を使ってみた
 
*/
 
#include <stdio.h>
#include <stdlib.h>
 
typedef enum period{
  BIRTH = 0, JUNIOR_HIGH = 1, HIGH = 2, COLLEGE = 3, SUPER_COLLEGE = 4
}PERIOD;
 
typedef struct state{
  struct state* future_state[2]; // 未来へのパス(取り敢えず2つほど)
  PERIOD period;
  int q;
}STATE;
 
 
STATE* change_state(STATE* p_state)
{
  if ((double)rand()/RAND_MAX < 0.3){  // ε:0.3
	if ((double)rand()/RAND_MAX < 0.5){ // 半々
	  return p_state->future_state[0];
	}
	else{
	  return p_state->future_state[1];
	}
  }
  else {
	if (p_state->future_state[0]->q > p_state->future_state[1]->q){
	  return p_state->future_state[0];
	}
	else{
	  return p_state->future_state[1];
	}
  }
}
	
void  q_renewal(STATE* p_state)
{
  int dummy_q;
 
  if (p_state->period  == SUPER_COLLEGE){
	p_state->q += 0.1 * (1000- p_state->q); // α:0.1 報酬の源泉:年収1000万円
  }
  else if (p_state->period !=  COLLEGE){
	if (p_state->future_state[0]->q > p_state->future_state[1]->q){
	  dummy_q = p_state->future_state[0]->q;
	}
	else {
	  dummy_q = p_state->future_state[1]->q;
	}
	p_state->q += 0.1 * (0.9 * dummy_q - p_state->q); // α:0.1 γ:0.9
  }
 
  return;
}
	
void q_display(STATE* p_state)
{
  for (int i =0; i < 15 ; i++){
	printf("%d,", p_state->q);
	p_state++;
  }
  printf("\n");
  return;
}
 
 
 
int main()
{
  srand(13);
 
 
  // 初期設定
  //STATE* state;
  STATE state[15];
 
  state[0].period = BIRTH;
  state[0].future_state[0] = &(state[1]);
  state[0].future_state[1] = &(state[2]);
 
  state[1].period = JUNIOR_HIGH;
  state[1].future_state[0] = &(state[3]);
  state[1].future_state[1] = &(state[4]);
 
  state[2].period = JUNIOR_HIGH;
  state[2].future_state[0] = &(state[5]);
  state[2].future_state[1] = &(state[6]);
 
  state[3].period = HIGH;
  state[3].future_state[0] = &(state[7]);
  state[3].future_state[1] = &(state[8]);
 
  state[4].period = HIGH;
  state[4].future_state[0] = &(state[9]);
  state[4].future_state[1] = &(state[10]);
 
  state[5].period = HIGH;
  state[5].future_state[0] = &(state[11]);
  state[5].future_state[1] = &(state[12]);
 
  state[6].period = HIGH;
  state[6].future_state[0] = &(state[13]);
  state[6].future_state[1] = &(state[14]);
 
  state[7].period = COLLEGE;
  state[8].period = COLLEGE;
  state[9].period = COLLEGE;
  state[10].period = SUPER_COLLEGE;
  state[11].period = COLLEGE;
  state[12].period = COLLEGE;
  state[13].period = COLLEGE;
  state[14].period = COLLEGE;
  
  for (int i = 0; i < 15; i++){
	state[i].q = (int)rand() % 100;
  }
 
  printf("誕生,A中学,B中学,C高校,D高校,E高校,F高校,G大学,H大学,I大学,J大学,K大学,L大学,M大学,N大学\n");

  STATE* s = state;
  //q_display(s);
  q_display(state);
 
  for (int i = 0; i < 1000; i++){  // 300:学習回数
	STATE* s = state; // 初期値に戻しているだけ
	
	do{ 
	  s = change_state(s);
	  q_renewal(s);
	}while( (s->period != COLLEGE) && (s->period != SUPER_COLLEGE));

	q_display(state);

  }
 
  printf("\n[after]\n");
  //q_display(s);
  q_display(state);
 
}

2017,江端さんの技術メモ

/*
  gcc -g second_job.cpp -o second_job
 

  考え方
  
  (1)8時間労働、8時間睡眠、8時間余暇を基本として考える。
  (2)8時間余暇の中には、通勤時間1.5時間 食事時間1.5時間が含まれるものとする
  (3)とすれば、残りの余暇5時間をどのような使い方をするのかが問題となる。
  
  (4)十分な余暇は、基本的に正業のパフォーマンスを上げるものであるとする。
  (4)余暇を使った副業は、収入になるものとする

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct person {
  double first_business_hour;
  double sleep_hour;
  double commute_time;
  double meal_time;

  double max_remain_time;
  double second_business_hour;
  double final_remain_time;

  double fb_fee;
  double sb_fee;
  
  double fatigue_func;
  double cost;

  struct person *prev;  /* 前の構造体を示すポインタ */
  struct person *next;  /* 次の構造体を示すポインタ */
} PERSON;


double min(double a, double b)
{
  if (a > b)
	return b;
  else
	return a;
}

double diff(double a, double b)
{
  if (a > b)
	return a - b;
  else
	return 0;
}


double fatigue_func(double time)
{
  if (time < 1.0){
	return 0.5;
  }
  else if ((time >= 1.0) && (time < 3.0)){
	return (1.0 - 0.5)/(3.0 - 1.0) * (time - 1.0) + 0.5;
  }
  else {
	return 1.0;
  }
}

const double First_Business_hourly_fees = 2000;
const double First_Business_extra_fees = First_Business_hourly_fees * 1.25;
const double Second_Business_hourly_fees = 1000;


int main()
{
  srand(13);

  PERSON* first_p_person= (PERSON*)malloc(sizeof(PERSON));
  PERSON* last_p_person= (PERSON*)malloc(sizeof(PERSON));

  PERSON*  p_prev_person = first_p_person;

  for (int i = 0; i < 100; i++){
	
	PERSON* p_person= (PERSON*)malloc(sizeof(PERSON));
	memset(p_person, 0, sizeof(PERSON));


	//////// ポインタの貼り替え //////////
	p_prev_person->next = p_person;
	p_person->next = last_p_person;
	p_person->prev = p_prev_person;
	p_prev_person = p_person;
	//////////////////////////////////////

	p_person->first_business_hour = 8.0 + 2.0 * (double)rand()/RAND_MAX;    // 8~10時間

	p_person->first_business_hour = 8.0;    // 8~10時間

	p_person->sleep_hour = 7.0 + 1.0 * (1.0 - 2.0 * (double)rand()/RAND_MAX); // 6~8時間
	p_person->commute_time = 1.0 + 0.5 * (1.0 - 2.0 * (double)rand()/RAND_MAX); // 0.5~1.5時間
	p_person->meal_time = 1.0 + 0.5 * (1.0 - 2.0 * (double)rand()/RAND_MAX);  // 0.5~1.5時間
	
	p_person->max_remain_time = 
	  24.0 - 
	  p_person->first_business_hour -
	  p_person->sleep_hour - 
	  p_person->commute_time - 
	  p_person->meal_time;    // 最悪でも3時間の、最良で9時間の余暇時間ができる

#if 1
	p_person->second_business_hour = p_person->max_remain_time * (double)rand()/RAND_MAX; //余暇の時間を適当に振る
#else
	p_person->second_business_hour = 0;
#endif

	p_person->final_remain_time = p_person->max_remain_time - p_person->second_business_hour;
	
	p_person->fb_fee = 
	  min(p_person->first_business_hour, 8.0) * First_Business_hourly_fees +
	  diff(p_person->first_business_hour, 8.0) * First_Business_extra_fees;
	
	p_person->sb_fee = p_person->second_business_hour * Second_Business_hourly_fees;
	p_person->fatigue_func = fatigue_func(p_person->final_remain_time);

	p_person->cost =	
	  p_person->fb_fee * p_person->fatigue_func + p_person->sb_fee;
  
	//printf("%d:cost = %f\n", i, p_person->cost);

  }


  double total_cost = 0.0;
  
  PERSON* p_person = first_p_person->next;

  printf("本業時間,睡眠時間,通勤時間,食事時間,余暇時間,副業時間,残余暇時間,RATIO,収入\n");

  while(p_person->next != last_p_person){
	total_cost += p_person->cost;
	
	printf("%f,%f,%f,%f,%f,%f,%f,%f,%f\n",
		   p_person->first_business_hour,
		   p_person->sleep_hour,
		   p_person->commute_time,
		   p_person->meal_time,
		   p_person->max_remain_time,
		   p_person->second_business_hour,
		   p_person->final_remain_time,
		   p_person->fatigue_func,
		   p_person->cost
		   );
	
	p_person = p_person->next;

  }
  
  printf("total cost = %f\n", total_cost);  


}

2017,江端さんの技術メモ

/*
  gcc -g hiseiki3.cpp -o hiseiki3
*/

/*
  まず「基本形」を崩す

  非正規社員投入の方針は、
  (1)潜在的な市場が増加中なら投入
  (2)赤字に転じたら、直ちに非正規社員を全員解雇
  という極めて単純なもの
  
  に、

  非正規社員を保護する
  最低3年間は解雇できないもの、としてみる


*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h> 



typedef struct person{
  int age;  // 20歳~60歳 のいずれか
  int position;  // 1:正規社員 0:非正規社員
  double productivity;  // 生産力 正規社員の場合 

  ///////////
  struct person *prev;  /* 前の構造体を示すポインタ */
  struct person *next;  /* 次の構造体を示すポインタ */ 

} PERSON;


typedef struct company{
  int payroll;
  double productivity;  // 会社としての生産力の合計   
} COMPANY;


PERSON *p_first_person, *p_last_person;   //社員リスト(あえてグローバルで保持)

// 社員用リストの先頭と終端を作成するルーチン
/*
  リストの先頭と終端をはグローバルでも良いのであるが、
  一応、メインルーチンの方で、陽に定義できるように、
  ここでは、返り値としている
*/

double min(double a, double b){
    if (b > a) 
        return a;
    else 
        return b;
};

double juglar_cycles(int year)
{
  // 10年で変動するsin周期
  // ベースとするのは2017年とする(単なる仮説)
  
  int x = (year -7) % 10;
  double y = sin( (double)x /10.0 * 2 * 3.141592654);

  return y;
}
  

void init_person_list(PERSON **p_first_person, PERSON **p_last_person)
{
  PERSON *p_top_person = (PERSON *)malloc(sizeof(PERSON));
  if(p_top_person == NULL) {
	printf("メモリが確保できません\n");
	exit(EXIT_FAILURE);
  }
  memset(p_top_person, 0, sizeof(PERSON)); // ゼロクリア


  PERSON *p_tail_person = (PERSON *)malloc(sizeof(PERSON));
  if(p_tail_person == NULL) {
	printf("メモリが確保できません\n");
	exit(EXIT_FAILURE);
  }
  memset(p_tail_person, 0, sizeof(PERSON)); // ゼロクリア

  *p_first_person = p_top_person;
  *p_last_person = p_tail_person;

  (*p_first_person)->prev = NULL;
  (*p_last_person)->next = NULL;
  (*p_first_person)->next = (*p_last_person);
  (*p_last_person)->prev = (*p_first_person);

  return;
}

// 社員オブジェクトを生成して、社員用リストに追加するルーチン
void add_person(PERSON *p_ref_person)
{

  PERSON *new_p_person = (PERSON *)malloc(sizeof(PERSON));
  if(new_p_person == NULL) {
	printf("メモリが確保できません\n");
	exit(EXIT_FAILURE);
  }
  memset(new_p_person, 0, sizeof(PERSON)); // ゼロクリア
  memcpy(new_p_person, p_ref_person, sizeof(PERSON)); // 引数の動的メモリの内容コピー
 
  // personの追加属性記述ここから
 


  // personの追加属性記述ここまで

  PERSON *p_person = p_last_person->prev;

  p_person->next = new_p_person;
  new_p_person->prev = p_person;

  p_last_person->prev = new_p_person;
  new_p_person->next = p_last_person;

  return;
}

void delete_person(PERSON *p_person)  
{
  // ポインタを貼り替えて
  p_person->prev->next = p_person->next;
  p_person->next->prev = p_person->prev;
  
  // そのメモリを解放する
  free(p_person);

  return;

}


int main()
{

  double potential = juglar_cycles(2017) * 1500.0 + 7500.0;
  double border = 7000.0; // 利益のボーダー(固定と考える)

  COMPANY company;
  company.productivity = 7437.500000; // 生産力初期値
  
   // 社員格納用リストの作成
  init_person_list(&p_first_person, &p_last_person); 
  
  //20歳から59歳までの正規社員、各世代100人づつ、合計4000人を作成する
  
  /////// PERSONを作成する ///////
  for (int age = 20; age < 60; age ++){
	for (int i = 0; i < 100; i++){
	  
	  PERSON person;
	  
	  person.age = age;
	  person.position = 1;  // 1:正規社員 0:非正規社員
	  person.productivity = 1.25 + (2.50 -1.25) / 40.0 * ((double)age -20.0); //20歳 1.25 60歳 2.50まで線形変化
	  
	  add_person(&person);
	}
  }
  /////// PERSONを作成する ///////  
 
  double sum_profit = 0;
  
  for ( int year = 2017; year < 2040; year++){
	
	//// 年齢を1歳加算し、定年
	// ===== PERSON ループを回す========
	PERSON* p_person = p_first_person->next;  
	while (p_person != p_last_person){
	  
	  p_person->age += 1;

	  if (p_person->position == 1){ // 正規社員であれば、生産力は年齢とともに高くなる(という仮説)
		p_person->productivity = 1.25 + (2.50 -1.25) / 40.0 * ((double)(p_person->age) -20.0); //20歳 1.25 60歳 2.50まで線形変化
	  }
	  else if (p_person->position == 0){ // 非正規社員であれば、生産力は年齢と関係なく高くならない(という仮説)
		p_person->productivity = 1.0;
	  }
	  
	  if (p_person->age >= 60){ // 60歳になったら定年(正規社員だろうが、非正規社員だろうが) 
		delete_person(p_person);
	  }
	  p_person = p_person->next;
	}
	// ===== PERSON ループを回す(ここまで)========
	
	//// 100人の20歳の新入社員を入社する
	for (int i = 0; i < 100; i++){
	  /////// PERSONを作成する ///////
	  PERSON person;
	  
	  person.age = 20;
	  person.position = 1;  // 1:正規社員 0:非正規社員
	  person.productivity = 1.25 + (2.50 -1.25) / 40.0 * ((double)person.age -20.0); //20歳 1.25 60歳 2.50まで線形変化
	  
	  add_person(&person);
	}

#if 1
	// 昨年の景気ラインと昨年の生産力を比較して、景気ライン > 昨年の生産力 となっていたら、非正規社員を必要分だけ投入する
	int add_person_number;

	if (potential > company.productivity){
	  add_person_number = (int)(potential - company.productivity);
	}
	
	// printf("potential = %f, company.productivity = %f, add_person_number=%d\n",potential, company.productivity, add_person_number);

	for (int i=0; i < add_person_number; i++){
	  PERSON person;

	  person.age = 20; // 若い奴を突っ込むことにする
	  person.position = 0;  // 1:正規社員 0:非正規社員
	  person.productivity = 1.0; // 生産力は"1.0"で固定、かつ年齢とともに成長しない)

	  add_person(&person);
	}

	// 昨年の景気ラインと利益のボーダを比較して 、景気ライン < 利益のボーダ となっていたら、非正規社員を全て即時に解雇する
	
	if (potential - border < 0.0){
	  // ===== PERSON ループを回す========
	  p_person = p_first_person->next;
	  while (p_person != p_last_person){
		
		if (p_person->position == 0){ // 非正規社員
		  if (p_person->age > 25){
			delete_person(p_person);
		  }
		}
		
		p_person = p_person->next;
	  }
	  // ===== PERSON ループを回す(ここまで)========
	}

#endif //0

	potential = juglar_cycles(year) * 1500.0 + 7500.0; // 景気ライン(ジャグラーサイクル)の更新


	/////////// ここから生産力算出ループ

	company.productivity = 0; // 生産力ゼロリセット
	company.payroll = 0 ; // 従業員数ゼロリセット

	// ===== PERSON ループを回す========
	p_person = p_first_person->next;
	while (p_person != p_last_person){
	  
	  company.payroll += 1 ; // 従業員数一人加算
	  company.productivity += p_person->productivity; // 生産力加算
	  
	  p_person = p_person->next;
	}
	// ===== PERSON ループを回す(ここまで)========
	
	//printf("company.payroll = %d\n",company.payroll); // company.payroll = 4000
	//printf("company.productivity = %f\n",company.productivity); // company.productivity = 7437.500000
	
	
	double profit = min(company.productivity, potential) - border;
	sum_profit += profit; 
	
	//printf("year = %d company.productivity = %f potential = %f profit = %f sum_profit=%f payroll=%d\n",year,company.productivity, potential, profit,sum_profit,company.payroll);
	printf("%d,%f,%f,%f,%f,%d\n",year,company.productivity, potential, profit,sum_profit,company.payroll);

	
  } //  for ( int year = 2017; year < 2040; year++){
  
  return 0;
}

2019,江端さんの技術メモ

/*
  g++ -g specific_skill2.cpp -o specific_skill2
*/

/*

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h> 



typedef struct person{
  int age;
  int type1_lifetime;  // 1号の残り時間
  int retirement_age; // 65歳で引退

  ///////////
  struct person *prev;  /* 前の構造体を示すポインタ */
  struct person *next;  /* 次の構造体を示すポインタ */ 

} PERSON;


int int_max(int a, int b)
{
  if (a < b) 
	return b;
  else 
	return a;
}



PERSON *p_first_person, *p_last_person;  

void init_person_list(PERSON **p_first_person, PERSON **p_last_person)
{
  PERSON *p_top_person = (PERSON *)malloc(sizeof(PERSON));
  if(p_top_person == NULL) {
	printf("メモリが確保できません\n");
	exit(EXIT_FAILURE);
  }
  memset(p_top_person, 0, sizeof(PERSON)); // ゼロクリア


  PERSON *p_tail_person = (PERSON *)malloc(sizeof(PERSON));
  if(p_tail_person == NULL) {
	printf("メモリが確保できません\n");
	exit(EXIT_FAILURE);
  }
  memset(p_tail_person, 0, sizeof(PERSON)); // ゼロクリア

  *p_first_person = p_top_person;
  *p_last_person = p_tail_person;

  (*p_first_person)->prev = NULL;
  (*p_last_person)->next = NULL;
  (*p_first_person)->next = (*p_last_person);
  (*p_last_person)->prev = (*p_first_person);

  return;
}

void add_person(PERSON *p_ref_person)
{

  PERSON *new_p_person = (PERSON *)malloc(sizeof(PERSON));
  if(new_p_person == NULL) {
	printf("メモリが確保できません\n");
	exit(EXIT_FAILURE);
  }
  memset(new_p_person, 0, sizeof(PERSON)); // ゼロクリア
  memcpy(new_p_person, p_ref_person, sizeof(PERSON)); // 引数の動的メモリの内容コピー
 
  // personの追加属性記述ここから
 
  // personの追加属性記述ここまで

  PERSON *p_person = p_last_person->prev;

  p_person->next = new_p_person;
  new_p_person->prev = p_person;

  p_last_person->prev = new_p_person;
  new_p_person->next = p_last_person;

  return;
}

void delete_person(PERSON *p_person)  
{
  // ポインタを貼り替えて
  p_person->prev->next = p_person->next;
  p_person->next->prev = p_person->prev;
  
  // そのメモリを解放する
  free(p_person);

  return;

}

int type1(int k){
  int number = 40000 + 4000 * (k - 2019);
  if (number > 60000){
	number = 60000;
  }
  return number;
}

// 2.1.1 C言語のrand関数を用いた方法
double Uniform( void ){
    return ((double)rand()+1.0)/((double)RAND_MAX+2.0);
}

// 3.3. 正規分布・ガウス分布 (Normal Distribution)
double rand_normal( double mu, double sigma ){
  double z=sqrt( -2.0*log(Uniform()) ) * sin( 2.0*M_PI*Uniform() );
  return mu + sigma*z;
} 


int main()
{
  srand(13);

  // 社員格納用リストの作成
  init_person_list(&p_first_person, &p_last_person); 

  int pass1_number;

  for (int i = 2019; i < 2080; i++){
  // for (int i = 2019; i < 2200; i++){
	// 1号試験パス者の生成
	pass1_number = type1(i);

	for (int k = 0; k < pass1_number; k++){
	  PERSON person;
	  person.age = int_max((int)rand_normal(26.0, 3.5), 18); // 18歳以下は応募できない
	  // printf("person.age = %d\n",person.age);
	  person.type1_lifetime = 5;
	  person.retirement_age = 65;
	  
	  add_person(&person);
	} // for (int k = 0, k < type1(k); k++)
	// 1号試験パス者の生成(ここまで)

    // ===== PERSON ループを回す========
    PERSON* p_person = p_first_person->next;  
    while (p_person != p_last_person){
	  
	  // 1号 強制帰国
	  if (p_person->type1_lifetime == 0){  // 5年を使い果した
		if (Uniform() <= 0.4){   // 2号合格率 40%
		  p_person->type1_lifetime = -1;  // 免責フラグ
		}
		else{
		  PERSON* p_person_prev = p_person->prev;
		  delete_person(p_person);
		  p_person = p_person_prev;
		}
	  }
	  
	  if (p_person->age > 65){  // 65歳以上になったら、強制帰国
		PERSON* p_person_prev = p_person->prev;
		delete_person(p_person);
		p_person = p_person_prev;
	  }

	  // 次のループに回る
	  p_person = p_person->next;
	}

    p_person = p_first_person->next;  
    while (p_person != p_last_person){

	  // 1号 強制帰国を迎えるまでのタイムリミットを減らす
	  if (p_person->type1_lifetime != -1){
		p_person->type1_lifetime -= 1;
	  }

	  // 全員の年齢の加算
	  p_person->age += 1;

	  // 次のループに回る
	  p_person = p_person->next;
	}


	int type1_person_count = 0;
	int type2_person_count = 0;
    p_person = p_first_person->next;  
    while (p_person != p_last_person){

	  if (p_person->type1_lifetime != -1)
		type1_person_count += 1;
	  else
		type2_person_count += 1;		

	  p_person = p_person->next;
	}

	//printf("i:%d, type1:%d, type2:%d\n", i, type1_person_count, type2_person_count);
	printf("%d, %d, %d, %d\n", 
		   i, 
		   type1_person_count, 
		   type2_person_count,
		   type1_person_count + type2_person_count);


  }//   for (int i = 2019; i < 2100; i++){

  return 0;
}

2017,江端さんの技術メモ

/*
  g++ -g seat.cpp -o seat
*/

/*
  「上司の帰宅が遅れると、社員の帰宅も遅れる」の仮説検証
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// 共通関数
double max(double a){
  return a;
}

double max(double a, double b){
  if (a > b) 
    return a;
  else 
    return b;
};

double max(double a, double b, double c ){
  return max(max(a,b), max(b,c)); 
};

double max(double a, double b, double c, double d ){
  return max(max(a,b,c), d); 
};

double min(double a){
  return a;
}

double min(double a, double b){
  if (b > a) 
    return a;
  else 
    return b;
};

double min(double a, double b, double c ){
  return min(min(a,b), min(b,c)); 
};

double min(double a, double b, double c, double d ){
  return min(min(a,b,c), d); 
};


// ファジィ表現
typedef enum scale {LESSLESS, LESS, ZERO, MORE, MOREMORE} SCALE;

// 前件部メンバーシップ関数(山3つ)クラス
class condition_MF3
{
private:
  double center;
  double width;
  SCALE express;
  
public:
  condition_MF3(double _center, double _witdth, SCALE _express){
    center = _center;
    width = _witdth;
    express = _express;
    
    // 使用できないファジィ表現を使った場合は止める        
    if ((express == LESSLESS) || (express == MOREMORE)){
      printf("wrong expression used \n");
      exit(0);
    }
    
  };
  double func(double _x);
};

double condition_MF3::func(double _x)
{
  // x,yは、メンバーシップ関数上の座標を示す
  double x = _x;
  double y = 0.0; // yの値は、必ず0以上1以下になる
  
  if (express == LESS){
    if (x <= center - width){
      y = 1.0;
    }
    else if (x <= center){
      y = - 1.0 / width * (x - center);
    }
    else{
      y = 0.0;
    }
  }
  else if (express == ZERO){
    if (x <= center - width){
      y = 0.0;
    }
    else if (x <= center){
      y = 1.0 / width * (x - center) + 1.0;
    }
    else if (x <= center + width){
      y = -1.0 / width * (x - center) + 1.0;
    }
    else{
      y = 0.0;
    }
  }
  else if (express == MORE){
    if (x <= center){
      y = 0.0;
    }
    else if (x <= center + width){
      y = 1.0 / width * (x - center);
    }
    else{
      y = 1.0;
    }
  }
  else {
    printf("wrong expression\n");
    exit(1);
  }
  
  return y;
};

// 前件部メンバーシップ関数(山5つ)クラス
class condition_MF5
{
private:
  double center;
  double width;
  SCALE express;
  
public:
  condition_MF5(double _center, double _witdth, SCALE _express){
    center = _center;
    width = _witdth;
    express = _express;
  };
  double func(double _x);
};


double condition_MF5::func(double _x)
{
  // x,yは、メンバーシップ関数上の座標を示す
  double x = _x;
  double y = 0.0; // yの値は、必ず0以上1以下になる
  
  if (express == LESSLESS){
    if (x <= center - 2.0 * width){
      y = 1.0;
    }
    else if (x <= center - width){
      y = - 1.0 / width * (x - (center - 2.0 * width)) + 1.0;
    }
    else{
      y = 0.0;
    }
  }
  else if (express == LESS){
    if (x <= center - 2.0 * width){
      y = 0.0;
    }
    else if (x <= center - width){
      y = 1.0 / width * (x - (center - width)) + 1.0;
    }
    else if (x <= center){
      y = -1.0 / width * (x - (center - width)) + 1.0; 
    }
    else{
      y = 0.0;
    }
  }
  else if (express == ZERO){
    if (x <= center - width){
      y = 0.0;
    }
    else if (x <= center){
      y = 1.0 / width * (x - center) + 1.0;
    }
    else if (x <= center + width){
      y = -1.0 / width * (x - center) + 1.0;
    }
    else{
      y = 0.0;
    }
  }
  else if (express == MORE){
    if (x <= center){
      y = 0.0;
    }
    else if (x <= center + width){
      y = 1.0 / width * (x - (center + width)) + 1.0;
    }
    else if (x <= center + 2.0 * width){
      y = -1.0 / width * (x - (center + width)) + 1.0; 
    }
    else{
      y = 0.0;
    }
  }
  else if (express == MOREMORE){
    if (x <= center + width){
      y = 0.0;
    }
    else if (x <= center + 2.0 * width){
      y = 1.0 / width * (x - (center + 2.0 * width)) + 1.0;
    }
    else{
      y = 1.0;
    }
  }
  
  return y;
};

// 後件部メンバーシップ関数(山3つ)クラス  
class action_MF3
{
private:
  double center;
  double width;
  SCALE express;
  
  double x;
  double y;
  
public:
  action_MF3(double _center, double _witdth, SCALE _express){
    
    y = 0.0; // yの値は、必ず0以上1以下になる
    
    center = _center;
    width = _witdth;
    express = _express;
    
    if (express == LESS){
      x = center - width;
    }
    else if (express == ZERO){
      x = center;
    }
    else if (express == MORE){
      x = center + width;
    }
    else{
      printf("wrong scale expression\n");
      exit(0);
    }
  };

  // Y座標の値を最大値で更新する  
  void func_Max(double b){
    y = max(b, y);
  };
  
  // Y座標の値をリセット(y=0)する
  void func_Reset(){
    y = 0.0;
  };
  
  // X座標を返す
  double func_X(void){
    return x;
  };
  
  // (最大値で更新された、最後の)Y座標を返す
  double func_Y(){
    return y;
  };

};

// 後件部メンバーシップ関数(山5つ)クラス  
class action_MF5
{
private:
  double center;
  double width;
  SCALE express;
  
  double x;
  double y;
  
public:
  action_MF5(double _center, double _witdth, SCALE _express){
    y = 0.0; // yの値は、必ず0以上1以下になる
    
    center = _center;
    width = _witdth;
    express = _express;
    
    if (express == LESSLESS){
      x = center - 2.0 * width;
    }
    else if (express == LESS){
      x = center - width;
    }
    else if (express == ZERO){
      x = center;
    }
    else if (express == MORE){
      x = center + width;
    }
    else if (express == MOREMORE){
      x = center + 2.0 * width;
    }
    else{
      printf("wrong scale expression\n");
      exit(-1); // 強制終了
    }
  };
  
  // Y座標の値を最大値で更新する  
  void func_Max(double b){
    y = max(b, y);
  };
  
  // Y座標の値をリセット(y=0)する
  void func_Reset(){
    y = 0.0;
  };
  
  // X座標を返す
  double func_X(void){
    return x;
  };
  
  // (最大値で更新された、最後の)Y座標を返す
  double func_Y(){
    return y;
  };
  
};

typedef enum post{
  HEAD = 1,  // 部長
  CHIEF = 2, // 課長
  STAFF = 3  // 平社員
} POST;

typedef struct person{
  int absences;  // 0:帰宅、 1:残業
  char name[10];
  int section;
  int number;
  POST post;
  double p_x;
  double p_y;
  double expected_return_time;  // 17.5(17:30)から、21.0(21:00)までの時間)
  double going_home_ratio;
} PERSON;

const int SECTION = 6;
const int MEMBER = 8;
const int ALL_PERSON_COUNTER = 49; // 6つの課、それぞれ8人と部長



PERSON person[] = {

  {1,"部長",-1,-1, HEAD,   0.0,             0.0},

  {1,"社員", 0, 0, STAFF,  3.5 + 0.0 + 0.0, -4.4 + 0.0 + 0.0},
  {1,"社員", 0, 1, STAFF,  3.5 + 0.0 + 1.2, -4.4 + 0.0 + 0.0},
  {1,"社員", 0, 2, STAFF,  3.5 + 0.0 + 2.4, -4.4 + 0.0 + 0.0},
  {1,"社員", 0, 3, STAFF,  3.5 + 0.0 + 3.6, -4.4 + 0.0 + 0.0},
  {1,"課長", 0, 4, CHIEF,  3.5 + 0.0 + 0.0, -4.4 + 0.0 + 2.0},
  {1,"社員", 0, 5, STAFF,  3.5 + 0.0 + 1.2, -4.4 + 0.0 + 2.0},
  {1,"社員", 0, 6, STAFF,  3.5 + 0.0 + 2.4, -4.4 + 0.0 + 2.0},
  {1,"社員", 0, 7, STAFF,  3.5 + 0.0 + 3.6, -4.4 + 0.0 + 2.0},

  {1,"社員", 1, 0, STAFF,  3.5 + 4.8 + 0.0, -4.4 + 0.0 + 0.0},
  {1,"社員", 1, 1, STAFF,  3.5 + 4.8 + 1.2, -4.4 + 0.0 + 0.0},
  {1,"社員", 1, 2, STAFF,  3.5 + 4.8 + 2.4, -4.4 + 0.0 + 0.0},
  {1,"課長", 1, 3, CHIEF,  3.5 + 4.8 + 3.6, -4.4 + 0.0 + 0.0},
  {1,"社員", 1, 4, STAFF,  3.5 + 4.8 + 0.0, -4.4 + 0.0 + 2.0},
  {1,"社員", 1, 5, STAFF,  3.5 + 4.8 + 1.2, -4.4 + 0.0 + 2.0},
  {1,"社員", 1, 6, STAFF,  3.5 + 4.8 + 2.4, -4.4 + 0.0 + 2.0},
  {1,"社員", 1, 7, STAFF,  3.5 + 4.8 + 3.6, -4.4 + 0.0 + 2.0},

  {1,"社員", 2, 0, STAFF,  3.5 + 0.0 + 0.0, -4.4 + 3.4 + 0.0},
  {1,"社員", 2, 1, STAFF,  3.5 + 0.0 + 1.2, -4.4 + 3.4 + 0.0},
  {1,"課長", 2, 2, CHIEF,  3.5 + 0.0 + 2.4, -4.4 + 3.4 + 0.0},
  {1,"社員", 2, 3, STAFF,  3.5 + 0.0 + 3.6, -4.4 + 3.4 + 0.0},
  {1,"社員", 2, 4, STAFF,  3.5 + 0.0 + 0.0, -4.4 + 3.4 + 2.0},
  {1,"社員", 2, 5, STAFF,  3.5 + 0.0 + 1.2, -4.4 + 3.4 + 2.0},
  {1,"社員", 2, 6, STAFF,  3.5 + 0.0 + 2.4, -4.4 + 3.4 + 2.0},
  {1,"社員", 2, 7, STAFF,  3.5 + 0.0 + 3.6, -4.4 + 3.4 + 2.0},

  {1,"社員", 3, 0, STAFF,  3.5 + 4.8 + 0.0, -4.4 + 3.4 + 0.0},
  {1,"社員", 3, 1, STAFF,  3.5 + 4.8 + 1.2, -4.4 + 3.4 + 0.0},
  {1,"社員", 3, 2, STAFF,  3.5 + 4.8 + 2.4, -4.4 + 3.4 + 0.0},
  {1,"社員", 3, 3, STAFF,  3.5 + 4.8 + 3.6, -4.4 + 3.4 + 0.0},
  {1,"社員", 3, 4, STAFF,  3.5 + 4.8 + 0.0, -4.4 + 3.4 + 2.0},
  {1,"社員", 3, 5, STAFF,  3.5 + 4.8 + 1.2, -4.4 + 3.4 + 2.0},
  {1,"課長", 3, 6, CHIEF,  3.5 + 4.8 + 2.4, -4.4 + 3.4 + 2.0},
  {1,"社員", 3, 7, STAFF,  3.5 + 4.8 + 3.6, -4.4 + 3.4 + 2.0},

  {1,"課長", 4, 0, CHIEF,  3.5 + 0.0 + 0.0, -4.4 + 6.8 + 0.0},
  {1,"社員", 4, 1, STAFF,  3.5 + 0.0 + 1.2, -4.4 + 6.8 + 0.0},
  {1,"社員", 4, 2, STAFF,  3.5 + 0.0 + 2.4, -4.4 + 6.8 + 0.0},
  {1,"社員", 4, 3, STAFF,  3.5 + 0.0 + 3.6, -4.4 + 6.8 + 0.0},
  {1,"社員", 4, 4, STAFF,  3.5 + 0.0 + 0.0, -4.4 + 6.8 + 2.0},
  {1,"社員", 4, 5, STAFF,  3.5 + 0.0 + 1.2, -4.4 + 6.8 + 2.0},
  {1,"社員", 4, 6, STAFF,  3.5 + 0.0 + 2.4, -4.4 + 6.8 + 2.0},
  {1,"社員", 4, 7, STAFF,  3.5 + 0.0 + 3.6, -4.4 + 6.8 + 2.0},

  {1,"社員", 5, 0, STAFF,  3.5 + 4.8 + 0.0, -4.4 + 6.8 + 0.0},
  {1,"社員", 5, 1, STAFF,  3.5 + 4.8 + 1.2, -4.4 + 6.8 + 0.0},
  {1,"社員", 5, 2, STAFF,  3.5 + 4.8 + 2.4, -4.4 + 6.8 + 0.0},
  {1,"社員", 5, 3, STAFF,  3.5 + 4.8 + 3.6, -4.4 + 6.8 + 0.0},
  {1,"課長", 5, 4, CHIEF,  3.5 + 4.8 + 0.0, -4.4 + 6.8 + 2.0},
  {1,"社員", 5, 5, STAFF,  3.5 + 4.8 + 1.2, -4.4 + 6.8 + 2.0},
  {1,"社員", 5, 6, STAFF,  3.5 + 4.8 + 2.4, -4.4 + 6.8 + 2.0},
  {1,"社員", 5, 7, STAFF,  3.5 + 4.8 + 3.6, -4.4 + 6.8 + 2.0},
};

double distance(PERSON* person1, PERSON* person2)
{
  double d = 0.0;
  
  d  = pow((person1->p_x - person2->p_x),2.0);
  d += pow((person1->p_y - person2->p_y),2.0);
  d = sqrt(d);

  return d;
}

int main()
{
  PERSON* cheif[SECTION]; 

  // 初期状態 (最初は個人の帰宅時間は、乱数で設定)
  for (int i = 0; i < ALL_PERSON_COUNTER; i++){
	// 各個人の帰宅時間を設定
	person[i].expected_return_time = 17.5 + (21.0 -17.5) * rand()/ (1.0 + RAND_MAX);
	// person[i].expected_return_time = 18.5;

	// 各課の課長を選定(後で探すのが面倒なので)
	if (person[i].post == CHIEF){
	  cheif[person[i].section] = &person[i];
	}
  }

  /*
  for (int i = 0; i < ALL_PERSON_COUNTER; i++){
	printf("%d, expected_return_time = %f\n",i, person[i].expected_return_time);
	printf("%d, expected_return_time = %d\n",i, person[i].absences);
  }
  */

  // 残業時間
  condition_MF3 OverTime_Short(1.0, 2.0, LESS); // 1時間
  condition_MF3 OverTime_Middle(1.0, 2.0, ZERO); // 2時間
  condition_MF3 OverTime_Long(1.0, 2.0, MORE); // 3時間

  // 部長からの距離
  condition_MF3 DistanceFrom_HEAD_Near(7.0, 7.0, LESS); // 7メートル
  condition_MF3 DistanceFrom_HEAD_Middle(7.0, 7.0, ZERO); // 14メートル
  condition_MF3 DistanceFrom_HEAD_Far(7.0, 7.0, MORE); // 21メートル

  // 課長からの距離
  condition_MF3 DistanceFrom_CHIEF_Near(1.5, 1.5, LESS); // 1.5メートル
  condition_MF3 DistanceFrom_CHIEF_Middle(1.5, 1.5, ZERO); // 3.0メートル
  condition_MF3 DistanceFrom_CHIEF_Far(1.5, 1.5, MORE); // 4.5メートル

  // 残っている課の人数
  condition_MF3 Staying_COUNT_Less(2, 2, LESS); // 2人
  condition_MF3 Staying_COUNT_Middle(2, 2, ZERO); // 4人
  condition_MF3 Staying_COUNT_Many(2, 2, MORE); // 6人

  // 帰宅度数
  action_MF3 GoingHome_Hard(0.5, 0.5, LESS);// 帰宅度数 0.0 → 帰宅できない
  action_MF3 GoingHome_Middle(0.5, 0.5, ZERO);// 帰宅度数 0.5 → 帰宅ボーダ
  action_MF3 GoingHome_Easy(0.5, 0.5, MORE);// 帰宅度数 1.0 → 帰宅できる

  double present_time =17.5;

  while (present_time < 24.0){
	present_time += 0.01; // 一番後ろで加算すると忘れそうなので
	printf("present_time = %f\n",  present_time);

	// 部の中の課の全体状況の把握

	if (person[0].expected_return_time < present_time){  // 部長は特別あつかい
	  person[0].absences = 0;
	}

	int staying_count[SECTION] ={}; // 各課(Section)で残っている人数を格納(最初はゼロリセット)
  
	for (int i = 0; i < ALL_PERSON_COUNTER; i++){
	  if (person[i].absences == 1){
		staying_count[person[i].section] += 1;  // (Section)に一人追加
	  }
	}

	printf("time = %f, %d,%d,%d,%d,%d,%d\n", 
		   present_time, 
		   staying_count[0],
		   staying_count[1],
		   staying_count[2],
		   staying_count[3],
		   staying_count[4],
		   staying_count[5]);
	
	for (int i = 1; i < ALL_PERSON_COUNTER; i++){ // person[0]の部長は神様→誰からも影響を受けない(とする)

	  /* 
	 [ルール1]
	 全社員は、予定時間の1時間のまでの帰宅度数0.0
	           1時間から2時間までの帰宅度数0.5 
	           2時間以上の帰宅度数1.0 
	  */

	  double r11 = min(OverTime_Short.func(present_time - person[i].expected_return_time));
	  GoingHome_Hard.func_Max(r11);
	  
	  double r12 = min( OverTime_Middle.func(present_time - person[i].expected_return_time));
	  GoingHome_Middle.func_Max(r12);
	  
	  double r13 = min(OverTime_Long.func(present_time - person[i].expected_return_time));
	  GoingHome_Easy.func_Max(r13);


	  if (person[i].post == CHIEF){ // 課長の場合の付加条件
		/*
		  ルール2
		  部長が残っている場合、部長から5m以内の課長は、帰宅度数0.0
		  5m~10m以内の課長は、帰宅度数0.5
		  10m以上の課長は、帰宅度数1.0
		*/
		
		double dis = distance(&person[0], &person[i]);
		
		double r21 = min((double)(person[0].absences), DistanceFrom_HEAD_Near.func(dis));
		GoingHome_Hard.func_Max(r21);
		
		double r22 = min((double)(person[0].absences), DistanceFrom_HEAD_Middle.func(dis));
		GoingHome_Middle.func_Max(r22);
		
		double r23 = min((double)(person[0].absences), DistanceFrom_HEAD_Far.func(dis));
		GoingHome_Easy.func_Max(r23);
		GoingHome_Middle.func_Max(r23);
	  }
	  


	  if (person[i].post == STAFF){ // (ヒラ)社員の場合の付加条件
		
		/*
		  ルール3
		  課長が残っている場合、課長から1.5m以内のメンバは、帰宅度数0.0
		  課長から3.0m以内のメンバは、帰宅度数0.5
		  課長から4.5m以内のメンバは、帰宅度数0.7
		*/
		
		double dis = distance(cheif[person[i].section], &person[i]);
		
		double r31 = min((double)(cheif[person[i].section]->absences), DistanceFrom_CHIEF_Near.func(dis));
		GoingHome_Hard.func_Max(r31);
		
		double r32 = min((double)(cheif[person[i].section]->absences), DistanceFrom_CHIEF_Middle.func(dis));
		GoingHome_Middle.func_Max(r32);
		
		double r33 = min((double)(cheif[person[i].section]->absences), DistanceFrom_CHIEF_Far.func(dis));
		GoingHome_Easy.func_Max(r33);
		GoingHome_Middle.func_Max(r33);
	  }

#if 0	  

	  /*
		ルール4
		同じ課のメンバのの人数が、6人以上残っている場合は、帰宅度数0.3
                              4人残っている場合は、帰宅度数0.6
                              2人以下の場合は、帰宅度数1.0
	  */

	  int num = staying_count[person[i].section];
	  double r41 = min(Staying_COUNT_Less.func((double)num));
	  GoingHome_Easy.func_Max(r41);
	  
	  double r42 = min(Staying_COUNT_Middle.func((double)num));
	  GoingHome_Middle.func_Max(r42);
	  
	  double r43 = min(Staying_COUNT_Many.func((double)num));
	  GoingHome_Hard.func_Max(r43);

#endif

	  /*
		ルールに振れない場合は、min-max重心法の分母がゼロになり、
		ゼロ割が発生する場合がある為、それを回避する
	  */
	  double denominator =  // 分母
		GoingHome_Easy.func_Y() + 
		GoingHome_Middle.func_Y() +
		GoingHome_Hard.func_Y();

	  double numerator =  // 分子	  
		GoingHome_Easy.func_X() * GoingHome_Easy.func_Y() + 
		GoingHome_Middle.func_X() * GoingHome_Middle.func_Y() +
		GoingHome_Hard.func_X() * GoingHome_Hard.func_Y();

	  // 推論結果 (分母がゼロの場合は、推論結果は前回と同値とする)
	  if ( denominator != 0.0){
		person[i].going_home_ratio =  numerator / denominator ;
	  }      
	  
	  if (person[i].going_home_ratio > 0.5){
		person[i].absences = 0;  // 0:帰宅、 1:残業		
	  }

	  // 後件部メンバーシップ関数のリセット(ループさせる時は必ずリセットする)
	  GoingHome_Easy.func_Reset();
	  GoingHome_Middle.func_Reset();
	  GoingHome_Hard.func_Reset();
	}
  }


  for (int i = 0; i < ALL_PERSON_COUNTER; i++){
	printf("%d, absences = %d\n",i, person[i].absences);
  }



  
  return 0;
}

2017,江端さんの技術メモ

2/*
  gcc -g birth_digital_native.cpp -o birth_digital_native
*/

/*
  デジタルネイティブ

1992年生まれから人口の100%がディジタルネイティブになったと仮定する。Q:日本のデジタルネイティブの比率は、どう変化していくだろうか
  

*/

#include "stdio.h"

int main(int argc, char* argv[])
{
	double men[101],women[101]; // 年齢別人口 平成22年データ 単位は1000人
	double men_death_rate[101],women_death_rate[101]; // 死亡率 平成22年データ (資料  厚生労働省大臣官房統計情報部人口動態・保健統計課「人口動態統計」)							
	// ファイルデバイスとデータ形式の統一回避する為、データべた書き

	men[ 0]=549   ; men_death_rate[ 0]=2.5/1000.0   ; // 男性0歳人口549千人、死亡率0.25% 2012年生まれ
	men[ 1]=535   ; men_death_rate[ 1]=0.4/1000.0   ; //2011年生まれ
	men[ 2]=535   ; men_death_rate[ 2]=0.2/1000.0   ; //2010年生まれ	
	men[ 3]=550   ; men_death_rate[ 3]=0.2/1000.0   ;	
	men[ 4]=548   ; men_death_rate[ 4]=0.2/1000.0   ;

	men[ 5]=544   ; men_death_rate[ 5]=0.1/1000.0   ;
	men[ 6]=542   ; men_death_rate[ 6]=0.1/1000.0   ;
	men[ 7]=562   ; men_death_rate[ 7]=0.1/1000.0   ;
	men[ 8]=574   ; men_death_rate[ 8]=0.1/1000.0   ;
	men[ 9]=589   ; men_death_rate[ 9]=0.1/1000.0   ; //2003年生まれ	

	men[10]=597   ; men_death_rate[10]=0.1/1000.0   ; //2002年生まれ	
	men[11]=604   ; men_death_rate[11]=0.1/1000.0   ;
	men[12]=604   ; men_death_rate[12]=0.1/1000.0   ;
	men[13]=613   ; men_death_rate[13]=0.1/1000.0   ;
	men[14]=610   ; men_death_rate[14]=0.1/1000.0   ;

	men[15]=607   ; men_death_rate[15]=0.3/1000.0   ;
	men[16]=627   ; men_death_rate[16]=0.3/1000.0   ;
	men[17]=632   ; men_death_rate[17]=0.3/1000.0   ;
	men[18]=621   ; men_death_rate[18]=0.3/1000.0   ; //1990年生まれ (ここまでが、ディタルネイティブ)	
	men[19]=631   ; men_death_rate[19]=0.3/1000.0   ;

	men[20]=623   ; men_death_rate[20]=0.6/1000.0   ; //1992年生まれ	
	men[21]=632   ; men_death_rate[21]=0.6/1000.0   ;
	men[22]=648   ; men_death_rate[22]=0.6/1000.0   ;
	men[23]=668   ; men_death_rate[23]=0.6/1000.0   ;
	men[24]=683   ; men_death_rate[24]=0.6/1000.0   ;

	men[25]=697   ; men_death_rate[25]=0.7/1000.0   ;
	men[26]=723   ; men_death_rate[26]=0.7/1000.0   ;
	men[27]=745   ; men_death_rate[27]=0.7/1000.0   ;
	men[28]=754   ; men_death_rate[28]=0.7/1000.0   ;
	men[29]=754   ; men_death_rate[29]=0.7/1000.0   ;

	men[30]=764   ; men_death_rate[30]=0.8/1000.0   ;
	men[31]=797   ; men_death_rate[31]=0.8/1000.0   ;
	men[32]=818   ; men_death_rate[32]=0.8/1000.0   ;
	men[33]=852   ; men_death_rate[33]=0.8/1000.0   ;
	men[34]=873   ; men_death_rate[34]=0.8/1000.0   ;

	men[35]=917   ; men_death_rate[35]=1.0/1000.0   ;
	men[36]=960   ; men_death_rate[36]=1.0/1000.0   ;
	men[37]=1012  ; men_death_rate[37]=1.0/1000.0   ;
	men[38]=1028  ; men_death_rate[38]=1.0/1000.0   ;
	men[39]=1010  ; men_death_rate[39]=1.0/1000.0   ;

	men[40]=982   ; men_death_rate[40]=1.5/1000.0   ;
	men[41]=954   ; men_death_rate[41]=1.5/1000.0   ;
	men[42]=937   ; men_death_rate[42]=1.5/1000.0   ;
	men[43]=916   ; men_death_rate[43]=1.5/1000.0   ;
	men[44]=915   ; men_death_rate[44]=1.5/1000.0   ;

	men[45]=713   ; men_death_rate[45]=2.4/1000.0   ;
	men[46]=882   ; men_death_rate[46]=2.4/1000.0   ;
	men[47]=826   ; men_death_rate[47]=2.4/1000.0   ;
	men[48]=805   ; men_death_rate[48]=2.4/1000.0   ;
	men[49]=778   ; men_death_rate[49]=2.4/1000.0   ;

	men[50]=765   ; men_death_rate[50]=3.8/1000.0   ;
	men[51]=770   ; men_death_rate[51]=3.8/1000.0   ;
	men[52]=783   ; men_death_rate[52]=3.8/1000.0   ;
	men[53]=761   ; men_death_rate[53]=3.8/1000.0   ;
	men[54]=740   ; men_death_rate[54]=3.8/1000.0   ;

	men[55]=776   ; men_death_rate[55]=6.3/1000.0   ;
	men[56]=803   ; men_death_rate[56]=6.3/1000.0   ;
	men[57]=803   ; men_death_rate[57]=6.3/1000.0   ;
	men[58]=850   ; men_death_rate[58]=6.3/1000.0   ;
	men[59]=896   ; men_death_rate[59]=6.3/1000.0   ;

	men[60]=949   ; men_death_rate[60]=9.3/1000.0   ;
	men[61]=1018  ; men_death_rate[61]=9.3/1000.0   ;
	men[62]=1111  ; men_death_rate[62]=9.3/1000.0   ;
	men[63]=1099  ; men_death_rate[63]=9.3/1000.0   ;
	men[64]=1042  ; men_death_rate[64]=9.3/1000.0   ;

	men[65]=645   ; men_death_rate[65]=14.6/1000.0   ;
	men[66]=684   ; men_death_rate[66]=14.6/1000.0   ;
	men[67]=825   ; men_death_rate[67]=14.6/1000.0   ;
	men[68]=794   ; men_death_rate[68]=14.6/1000.0   ;
	men[69]=809   ; men_death_rate[69]=14.6/1000.0   ;

	men[70]=780   ; men_death_rate[70]=22.7/1000.0   ;
	men[71]=698   ; men_death_rate[71]=22.7/1000.0   ;
	men[72]=599   ; men_death_rate[72]=22.7/1000.0   ;
	men[73]=627   ; men_death_rate[73]=22.7/1000.0   ;
	men[74]=631   ; men_death_rate[74]=22.7/1000.0   ;

	men[75]=616   ; men_death_rate[75]=39.6/1000.0   ;
	men[76]=571   ; men_death_rate[76]=39.6/1000.0   ;
	men[77]=521   ; men_death_rate[77]=39.6/1000.0   ;
	men[78]=501   ; men_death_rate[78]=39.6/1000.0   ;
	men[79]=470   ; men_death_rate[79]=39.6/1000.0   ;

	men[80]=430   ; men_death_rate[80]=70.5/1000.0   ;
	men[81]=385   ; men_death_rate[81]=70.5/1000.0   ;
	men[82]=350   ; men_death_rate[82]=70.5/1000.0   ;
	men[83]=316   ; men_death_rate[83]=70.5/1000.0   ;
	men[84]=281   ; men_death_rate[84]=70.5/1000.0   ;

	men[85]=247   ; men_death_rate[85]=120.3/1000.0   ;
	men[86]=202   ; men_death_rate[86]=120.3/1000.0   ;
	men[87]=158   ; men_death_rate[87]=120.3/1000.0   ;
	men[88]=122   ; men_death_rate[88]=120.3/1000.0   ;
	men[89]=98    ; men_death_rate[89]=120.3/1000.0   ;

	men[90]=78    ; men_death_rate[90]=202.5/1000.0   ;
	men[91]=67    ; men_death_rate[91]=202.5/1000.0   ;
	men[92]=44    ; men_death_rate[92]=202.5/1000.0   ;
	men[93]=36    ; men_death_rate[93]=202.5/1000.0   ;
	men[94]=28    ; men_death_rate[94]=202.5/1000.0   ;

	men[95]=21    ; men_death_rate[95]=318.8/1000.0   ;
	men[96]=15    ; men_death_rate[96]=318.8/1000.0   ;
	men[97]=11    ; men_death_rate[97]=318.8/1000.0   ;
	men[98]=7     ; men_death_rate[98]=318.8/1000.0   ;
	men[99]=5     ; men_death_rate[99]=318.8/1000.0   ;

	women[ 0]=520; women_death_rate[ 0]=2.1/1000.0   ;// 女性0歳人口520千人、死亡率0.21%
	women[ 1]=510; women_death_rate[ 1]=0.4/1000.0   ;
	women[ 2]=511; women_death_rate[ 2]=0.2/1000.0   ;
	women[ 3]=525; women_death_rate[ 3]=0.1/1000.0   ;
	women[ 4]=522; women_death_rate[ 4]=0.1/1000.0   ;

	women[ 5]=518; women_death_rate[ 5]=0.1/1000.0   ;
	women[ 6]=517; women_death_rate[ 6]=0.1/1000.0   ;
	women[ 7]=538; women_death_rate[ 7]=0.1/1000.0   ;
	women[ 8]=545; women_death_rate[ 8]=0.1/1000.0   ;
	women[ 9]=561; women_death_rate[ 9]=0.1/1000.0   ;

	women[10]=568; women_death_rate[10]=0.1/1000.0   ;
	women[11]=573; women_death_rate[11]=0.1/1000.0   ;
	women[12]=576; women_death_rate[12]=0.1/1000.0   ;
	women[13]=585; women_death_rate[13]=0.1/1000.0   ;
	women[14]=583; women_death_rate[14]=0.1/1000.0   ;

	women[15]=578; women_death_rate[15]=0.2/1000.0   ;
	women[16]=595; women_death_rate[16]=0.2/1000.0   ;
	women[17]=597; women_death_rate[17]=0.2/1000.0   ;
	women[18]=589; women_death_rate[18]=0.2/1000.0   ;//1990年生まれ (ここまでが、ディタルネイティブ)	
	women[19]=599; women_death_rate[19]=0.2/1000.0   ;

	women[20]=596; women_death_rate[20]=0.3/1000.0   ;
	women[21]=605; women_death_rate[21]=0.3/1000.0   ;
	women[22]=622; women_death_rate[22]=0.3/1000.0   ;
	women[23]=638; women_death_rate[23]=0.3/1000.0   ;
	women[24]=655; women_death_rate[24]=0.3/1000.0   ;

	women[25]=667; women_death_rate[25]=0.3/1000.0   ;
	women[26]=697; women_death_rate[26]=0.3/1000.0   ;
	women[27]=719; women_death_rate[27]=0.3/1000.0   ;
	women[28]=729; women_death_rate[28]=0.3/1000.0   ;
	women[29]=734; women_death_rate[29]=0.3/1000.0   ;

	women[30]=742; women_death_rate[30]=0.4/1000.0   ;
	women[31]=774; women_death_rate[31]=0.4/1000.0   ;
	women[32]=794; women_death_rate[32]=0.4/1000.0   ;
	women[33]=828; women_death_rate[33]=0.4/1000.0   ;
	women[34]=849; women_death_rate[34]=0.4/1000.0   ;

	women[35]=890; women_death_rate[35]=0.6/1000.0   ;
	women[36]=931; women_death_rate[36]=0.6/1000.0   ;
	women[37]=982; women_death_rate[37]=0.6/1000.0   ;
	women[38]=1001; women_death_rate[38]=0.6/1000.0   ;
	women[39]=981; women_death_rate[39]=0.6/1000.0   ;

	women[40]=958; women_death_rate[40]=0.8/1000.0   ;
	women[41]=931; women_death_rate[41]=0.8/1000.0   ;
	women[42]=920; women_death_rate[42]=0.8/1000.0   ;
	women[43]=902; women_death_rate[43]=0.8/1000.0   ;
	women[44]=898; women_death_rate[44]=0.8/1000.0   ;

	women[45]=705; women_death_rate[45]=1.3/1000.0   ;
	women[46]=872; women_death_rate[46]=1.3/1000.0   ;
	women[47]=815; women_death_rate[47]=1.3/1000.0   ;
	women[48]=798; women_death_rate[48]=1.3/1000.0   ;
	women[49]=772; women_death_rate[49]=1.3/1000.0   ;

	women[50]=760; women_death_rate[50]=1.9/1000.0   ;
	women[51]=768; women_death_rate[51]=1.9/1000.0   ;
	women[52]=783; women_death_rate[52]=1.9/1000.0   ;
	women[53]=765; women_death_rate[53]=1.9/1000.0   ;
	women[54]=744; women_death_rate[54]=1.9/1000.0   ;

	women[55]=783; women_death_rate[55]=2.8/1000.0   ;
	women[56]=810; women_death_rate[56]=2.8/1000.0   ;
	women[57]=813; women_death_rate[57]=2.8/1000.0   ;
	women[58]=868; women_death_rate[58]=2.8/1000.0   ;
	women[59]=918; women_death_rate[59]=2.8/1000.0   ;

	women[60]=975; women_death_rate[60]=3.9/1000.0   ;
	women[61]=1051; women_death_rate[61]=3.9/1000.0   ;
	women[62]=1152; women_death_rate[62]=3.9/1000.0   ;
	women[63]=1146; women_death_rate[63]=3.9/1000.0   ;
	women[64]=1090; women_death_rate[64]=3.9/1000.0   ;

	women[65]=685; women_death_rate[65]=6.0/1000.0   ;
	women[66]=741; women_death_rate[66]=6.0/1000.0   ;
	women[67]=903; women_death_rate[67]=6.0/1000.0   ;
	women[68]=875; women_death_rate[68]=6.0/1000.0   ;
	women[69]=899; women_death_rate[69]=6.0/1000.0   ;

	women[70]=873; women_death_rate[70]=9.8/1000.0   ;
	women[71]=793; women_death_rate[71]=9.8/1000.0   ;
	women[72]=690; women_death_rate[72]=9.8/1000.0   ;
	women[73]=738; women_death_rate[73]=9.8/1000.0   ;
	women[74]=755; women_death_rate[74]=9.8/1000.0   ;

	women[75]=753; women_death_rate[75]=17.9/1000.0   ;
	women[76]=718; women_death_rate[76]=17.9/1000.0   ;
	women[77]=675; women_death_rate[77]=17.9/1000.0   ;
	women[78]=671; women_death_rate[78]=17.9/1000.0   ;
	women[79]=646; women_death_rate[79]=17.9/1000.0   ;

	women[80]=614; women_death_rate[80]=34.3/1000.0   ;
	women[81]=573; women_death_rate[81]=34.3/1000.0   ;
	women[82]=547; women_death_rate[82]=34.3/1000.0   ;
	women[83]=515; women_death_rate[83]=34.3/1000.0   ;
	women[84]=482; women_death_rate[84]=34.3/1000.0   ;

	women[85]=454; women_death_rate[85]=69.1/1000.0   ;
	women[86]=405; women_death_rate[86]=69.1/1000.0   ;
	women[87]=349; women_death_rate[87]=69.1/1000.0   ;
	women[88]=313; women_death_rate[88]=69.1/1000.0   ;
	women[89]=276; women_death_rate[89]=69.1/1000.0   ;

	women[90]=236; women_death_rate[90]=131.2/1000.0   ;
	women[91]=213; women_death_rate[91]=131.2/1000.0   ;
	women[92]=146; women_death_rate[92]=131.2/1000.0   ;
	women[93]=128; women_death_rate[93]=131.2/1000.0   ;
	women[94]=106; women_death_rate[94]=131.2/1000.0   ;

	women[95]=87 ; women_death_rate[95]=238.1/1000.0   ;
	women[96]=63 ; women_death_rate[96]=238.1/1000.0   ;
	women[97]=49 ; women_death_rate[97]=238.1/1000.0   ;
	women[98]=35 ; women_death_rate[98]=238.1/1000.0   ;
	women[99]=25 ; women_death_rate[99]=238.1/1000.0   ;

	for (int year = 2012; year < 2100; year++){ // 2012年から2100年までループ計算
	  
	  double dummy = 0;
	  for(int i = 15; i < 50; i++){  // 特殊出産率の対象 15歳から49歳までの人口加算
		dummy += women[i];
	  }	
	  
	  // 1.4は、特殊出生率 / 35は特殊出生率の対象期間(35年) / 1.05は男性の出生比率
	  double mem_new_birth = dummy * 1.4 / 35.0 * 1.05/(1.05+1.00);
	  double womem_new_birth = dummy * 1.4 / 35.0 * 1.00/(1.05+1.00);	
	  
	  // 1年単位の人口移動 (死亡率も考慮) 
	  for (int k = 99; k >= 0; k--){
		men[k+1] = men[k] * (1.0 - men_death_rate[k]);
		women[k+1] = women[k] * (1.0 - women_death_rate[k]);
		//printf("%d   %f    %f \n", k, men[k], women[k]);					
		
	  }

	  // 新生児の人口を追加
	  men[0] = mem_new_birth;
	  women[0] = womem_new_birth;
	  
	  // 人口総計(年齢99歳まで。100歳以上の人口は無視することにした)
	  double sum_men = 0;
	  double sum_women = 0;
	  
		for (int m = 0; m <= 100; m++){
		  sum_men += men[m];
		  sum_women += women[m];
		}
		
#if 0		
		// ディタルネイティブ人口総計
		double digital_sum_men = 0;
		double digital_sum_women = 0;
		
		int l = year -1990;
		if (l >= 100) l = 100;

		for (int n = 0; n <= l ; n++){
		  digital_sum_men += men[n];
		  digital_sum_women += women[n];
		}
#endif 

#if 0  // ここから江端仮説

		// ディタルネイティブ人口総計
		double digital_sum_men = 0;
		double digital_sum_women = 0;

		// 1970年以後の人は100%デジタルは使えるいう仮説の導入
		
		int l = year -1970;    
		if (l >= 100) l = 100;

		for (int n = 0; n <= l ; n++){
		  digital_sum_men += men[n];
		  digital_sum_women += women[n];
		}

		// 1950-70年にかけてデジタルを使える人は線形に増加した、という仮説の導入
		
		// デジタルネイティブ人口(江端"補正"仮説)
		int p1 = year -1970;  // 例:2020年の時に50歳
		int p2 = year -1950;  // 例:2020年の時に70歳

		for (int i = p1; i < p2 ; i++){  
		  if (i < 100){
			// 例:2020年の時に70歳の人の0%、 60歳の人の50%、50歳の人の100%がデジタルを扱えるとする
			digital_sum_men += men[i] * 1.0 / (double)(p2 - p1) * (double)(p2 - i);
			digital_sum_women += women[i] * 1.0 / (double)(p2 - p1) * (double)(p2 - i);
		  }
		}

#endif 


#if 1
		// 高齢者世代(65歳以上)に特化して計算してみる

		// 人口総計(年齢65歳から99歳まで。100歳以上の人口は無視することにした)
		sum_men = 0;
		sum_women = 0;
		
		for (int m = 65; m <= 100; m++){
		  sum_men += men[m];
		  sum_women += women[m];
		}
		
		// ディタルネイティブ人口総計
		double digital_sum_men = 0;
		double digital_sum_women = 0;

		// 1970年以後の人は100%デジタルは使えるいう仮説の導入
		
		int l = year -1970;    
		if (l >= 100) l = 100;

		for (int n = 65; n <= l ; n++){
		  digital_sum_men += men[n];
		  digital_sum_women += women[n];
		}

		// 1950-70年にかけてデジタルを使える人は線形に増加した、という仮説の導入
		
		// デジタルネイティブ人口(江端"補正"仮説)
		int p1 = year -1970;  // 例:2020年の時に50歳   2017年の時に47歳
		int p2 = year -1950;  // 例:2020年の時に70歳   2017年の時に67歳

		for (int i = p1; i < p2 ; i++){  
		  if ((i >= 65) &&(i < 100)){
			// 例:2020年の時に70歳の人の0%、 60歳の人の50%、50歳の人の100%がデジタルを扱えるとする
			digital_sum_men += men[i] * 1.0 / (double)(p2 - p1) * (double)(p2 - i);
			digital_sum_women += women[i] * 1.0 / (double)(p2 - p1) * (double)(p2 - i);
		  }
		}
#endif

		
		printf("%d,%f,%f,%f\n", year,  sum_men + sum_women, digital_sum_men + digital_sum_women, (digital_sum_men + digital_sum_women)/(sum_men + sum_women) );	
	}
}

2022/10,江端さんの忘備録

先日リリースされたコラムで、

In my column which is released yesterday, I wrote

―― 私が教祖になるには、まず、私が「天啓」を受けている、というストーリーが必要です

"To become a guru, I must first have a story that I am "enlightened"!"

と書きました。

日常生活においても、過激なダイエット等で、比較的簡単に「天啓」を得ることができることは事実です。

It is true that it is relatively easy to obtain "revelations" in daily life, e.g., through extreme dieting.

それは、私の体を張ったダイエットで、実証済みです。

This has been proven by my own physical diet.

加えて、実際に、私、これまで、何度も神を降ろしています(本当)。

In addition, I have, in fact, brought God down many times (really).

(↑のクリックで記事に飛びます)

(↑click to jump to the article)

つまり、世界三大宗教を含め、経典に記載されている「教祖の天啓」ってやつは、かなり「眉唾(まゆつば)もの」である、ということです。

In other words, the "revelations of founder of religion" in the scriptures, including those of the world's three major religions, are quite 'dubious tale'.

-----

ちなみに、私の宗教勧誘の撃退方法の一つに、

Incidentally, one of my methods of repelling religious solicitations is to

『あなた、神様を見たことがあるの? 私はあるよ。2000年9月11日、米国ユタ州の国立公園の巨大な砂岩のアーチの下で。クリアに見えたよ』

"Have you ever seen God? I have, on September 11, 2000, under a huge sandstone arch in a national park in Utah, USA. I saw them clear."

『あなた、神様の声を聞いたり、姿を見たりしたことあるの? え? ないの? ないのに"この私"に布教をしているの?』

"Have you ever heard or seen God? What? No? And you're proselytizing to me?"

『ちょっと思い上がってんじゃないのかなぁ』

"I think you are a little presumptuous are't you?"

と、「格の違いを見せつける」というメソッドがあります。

is a method to 'show the difference in class'.

2022/09,江端さんの忘備録

先日、証明写真機(スピード写真)で、写真を取ってきました。

The other day, I took a photo from a photo machine (speed photo).

人生で初めて、『メガネ(老眼鏡)』をかけて写真撮影をしました。

For the first time in my life, I wore "glasses (reading glasses)" to take pictures.

―― メガネをつけると、目付きの悪さが緩和される

"Wearing glasses eases my unpleasant look"

という、事実を発見したからです。

I noticed that.

以前、パスポート更新用にとった写真を見て、ぞっとしました。

I was horrified when I saw the photo for my passport renewal.

もし、私が事故や事件に巻き込まれた時、この写真がニュースに出たら、ニュースの内容を確認されないまま、「加害者」「犯人」であると決めつけられる、と思いました。

I thought that if I were involved in an accident or incident and this photo appeared on the news, I would be assumed to be the "perpetrator" or "culprit" without having the news story confirmed.

-----

「国葬」の日、私は、終日、自宅に閉じ籠って仕事していました。

On the day of the "State Funeral," I spent the entire day confined to my home and worked.

―― 私、結構な頻度で、『職務質問』されるんですけど、良い対策方法ってありますか?