2022年10月1日
/*
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;
}