2011|08|
2013|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|05|06|07|08|09|10|11|12|
2016|01|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|

2018-02-21 シュタインズゲートの「タイムリープ」「リーディングシュタイナー」をコーディングするとこんな感じ [長年日記]

/*
  ================================================
  mingw64でfork(),waitpid(), kill()を何とかしたい
  ================================================
 
  ●参照させて頂いたページ
  https://gist.github.com/Cr4sh/126d844c28a7fbfd25c6
  http://7shi.hateblo.jp/entry/2012/06/19/213405
  http://www.fireproject.jp/feature/c-language/process/fork-wait.html
 
  ●コンパイル:
  gcc -c fork.cpp
 
  ●その他
  「mingw64でfork()を何とかしたい」の後に読むと分かりやすいかも
 
 
  ちなみにWindowsのコマンドプロンプトではprintf()の表示がされない(理由不明)ので
 
  > fork2 > dummy.txt
 
  などとして確認すること。
 
*/
 
/*
 * fork.c
 * Experimental fork() on Windows.  Requires NT 6 subsystem or
 * newer.
 *
 * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * This software is provided 'as is' and without any warranty, express or
 * implied.  In no event shall the authors be liable for any damages arising
 * from the use of this software.
 */
 
#define _WIN32_WINNT 0x0600
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winnt.h>
#include <ntdef.h>
#include <stdio.h>
#include <errno.h>
#include <process.h>
 
#ifdef __MINGW32__
typedef struct _CLIENT_ID {
  PVOID UniqueProcess;
  PVOID UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
 
typedef struct _SECTION_IMAGE_INFORMATION {
  PVOID EntryPoint;
  ULONG StackZeroBits;
  ULONG StackReserved;
  ULONG StackCommit;
  ULONG ImageSubsystem;
  WORD SubSystemVersionLow;
  WORD SubSystemVersionHigh;
  ULONG Unknown1;
  ULONG ImageCharacteristics;
  ULONG ImageMachineType;
  ULONG Unknown2[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
 
typedef struct _RTL_USER_PROCESS_INFORMATION {
  ULONG Size;
  HANDLE Process;
  HANDLE Thread;
  CLIENT_ID ClientId;
  SECTION_IMAGE_INFORMATION ImageInformation;
} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;
 
#define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED	0x00000001
#define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES		0x00000002
#define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE		0x00000004
 
#define RTL_CLONE_PARENT				0
#define RTL_CLONE_CHILD					297
 
#endif
 
typedef NTSTATUS (*RtlCloneUserProcess_f)
(ULONG ProcessFlags,
 PSECURITY_DESCRIPTOR ProcessSecurityDescriptor /* optional */,
 PSECURITY_DESCRIPTOR ThreadSecurityDescriptor /* optional */,
 HANDLE DebugPort /* optional */,
 PRTL_USER_PROCESS_INFORMATION ProcessInformation);
 
pid_t fork(void)
{
  HMODULE mod;
  RtlCloneUserProcess_f clone_p;
  RTL_USER_PROCESS_INFORMATION process_info;
  NTSTATUS result;
  
  mod = GetModuleHandle("ntdll.dll");
  if (!mod)
	return -ENOSYS;
  
  //clone_p = GetProcAddress(mod, "RtlCloneUserProcess"); // Ebata 
  clone_p = (RtlCloneUserProcess_f)GetProcAddress(mod, "RtlCloneUserProcess");
 
  if (clone_p == NULL)
	return -ENOSYS;
  
  /* lets do this */
  result = clone_p(RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED | RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES, NULL, NULL, NULL, &process_info);
  
  if (result == RTL_CLONE_PARENT)
	{
	  HANDLE me = GetCurrentProcess();
	  pid_t child_pid;
	  
	  child_pid = GetProcessId(process_info.Process);
	  
	  ResumeThread(process_info.Thread);
	  CloseHandle(process_info.Process);
	  CloseHandle(process_info.Thread);
	  
	  return child_pid;
	}
  else if (result == RTL_CLONE_CHILD)
	{
	  /* fix stdio */
	  AllocConsole();
	  return 0;
	}
  else
	return -1;
  
  /* NOTREACHED */
  return -1;
}
 
int kill(pid_t pid, int sig) {
    int ret;
    HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
    ret = TerminateProcess(h, 0) ? 0 : -1;
    CloseHandle(h);
    return ret;
}
 
 
#if 0
int waitpid(pid_t pid, int *stat_loc, int options) {
  int i = 1;
  return   _cwait(stat_loc, pid, WAIT_CHILD);
}
#endif
 
int waitpid(pid_t pid,  DWORD dwMilliseconds)  // Ebata's original waitpid()
{
  HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);	  
  //  WaitForSingleObject(h, INFINITE);
  int ret = WaitForSingleObject(h, dwMilliseconds);
  
  CloseHandle(h);
  
  return ret;
}
 
 
#if 0 // サンプルプログラム
 
int main(void){
  
  pid_t result_pid = fork(); 
  
  if (result_pid == 0){ // 子プロセス
	
	printf("Child process started.\n");
	printf("Wait 10 seconds.\n");
	printf("result_pid = %d child process.\tpid = %d\n",result_pid,getpid());
	fflush(stdout);
 
	Sleep(10000); // 10秒くらいの生存期間
 
	fprintf(stdout,"Child process ended.\n");
	fflush(stdout);
	
  }
  else{ // 親プロセス
 
	printf("Parents process started.\n");
	fflush(stdout);
 
	// 親プロセスの方には、子プロセスのIDが入るので、それを監視する
 
	waitpid(result_pid,  INFINITE);  // 子プロセス(1つのみ)が終了するまで止まる
	//waitpid(result_pid,  100); // 100msのみ停止
 
	fprintf(stdout,"Parent process ended.\n");
	fflush(stdout);
  }
 
  return 0;
}
 
#endif // サンプルプログラム
 
 
==========================================================
 
/*
  シュタインズゲートの「タイムリープ」をコーディングするとこんな感じ
 
  gcc -c fork_test.cpp
  gcc -g fork.cpp fork_test.cpp -o fork_test
*/
 
#include <windows.h>
#include <stdio.h>
#include <process.h>
 
 
extern pid_t fork(void);
extern int waitpid(pid_t pid,  DWORD dwMilliseconds);  // Ebata's original waitpid()
extern int kill(pid_t pid, int sig);
 
int main(void){
 
  pid_t result_pid = -1;  // fork()が吐き出さない値をダミーに入れておく
  int init_i = -1; 
 
  for (int i = 0; i < 100; i++){
	
	if (i == 17){          // iが17になった時に、子プロセスを起動
	  result_pid = fork(); 
	  init_i = i ;
	}
	
	if (result_pid == 0){ // 子プロセス
	  printf("c:\t%d\n", i);
	  fflush(stdout);
	  if (i > init_i + 50){  // 「岡部、50回先の未来に行く」
		exit(0);  // 子プロセスの強制終了
	  }
	}
	else {
	  waitpid(result_pid,  INFINITE);  // 子プロセス(1つのみ)が終了するまで止まる
	  printf("p:%d\n", i);// 「岡部、リーディングシュタイナー発動(記憶を維持したまま、50回前の過去にタイムリープ」
	  fflush(stdout);
	}
  }
}
syntax2html

2018-02-17 シュタインズゲートに登場する「世界線」、使い方間違っているぞ。 [長年日記]

_ 疑問:コンピュータの中で作り出した仮想世界で「流れる時間」(×時間、×時刻)の概念を現わす用語を「世界線」といって良いか。


============
(1)調査結果
============

(その1)

定義:「世界線」は簡単にいえば、物質が「時空」の中を動く経路を線であらわしたもの

具体例:

(1)X軸が時間、Y軸が距離と座標軸を決めて、右上がりの直線のグラフをを書いた時のグラフの線が世界線。
(2)このグラフは、物体の目に見えるままの運動を表していない。
(3)時間と空間を組み合わせた速さを表現している。速さという目に見えない抽象世界を表現している

その他:
ニュートンの古典力学は、時間と空間を個別に考えていた。比して、アインシュタインが提唱した相対性理論では、時間と空間は一体化して「時空」と考えるようになり、時空を移動するという抽象概念として「世界線」という言葉がつくられた


(その2)
定義:4次元時空の中で動く粒子の軌跡(ただし、4次元時空とはミンコフスキー空間)

具体例;
(1)3次元時間(x,y,z)という概念に時間(ct)を取り入れたx,y,z,ct(時間)を4次元空間と呼び、これをミンコフスキー時空という。
(2)空間と時間の各成分の2乗を足すときに、時間の前の係数を-1 にして足すことによって不変量、すなわち長さを求めることができる。計量の各成分の符号が異なるような空間をミンコフスキー空間とよび、また、その計量はミンコフスキー計量という。

その他:
ミンコフスキー空間によって、時間と空間をゴチャにした(アインシュタインの相対性理論の)概念がキレイに整理される(高校レベルの数学で)

=======
(2)結論
=======

●コンピュータの中で作り出した仮想世界に「流れる時間」(×時間、×時刻)の概念を現わる用語を「世界線」と呼ぶのは妥当ではない。

●(迂遠ではあるが)ここは素直に「仮想世界時間」であり、その時間の概念は「仮想世界時間軸」と呼ぶことにする。

==========
(3)その他
==========


■英語にすると、これが長くて、特にパワーポイントの改行がウザい (正直これが辛い。私は論文で略号を使うの嫌いな人)
「世界線」→"world line" 「仮想世界時間軸」→ "Virtual world time axis"

■シュタインズゲートに登場する「世界線」、使い方間違っているぞ。
α世界線 → α世界 / α世界空間 あたりが妥当かと思う。
(「α並列世界」でも、ちょっと変だと思う。並列というからには、世界の時空ベクトルが同一方向を向いているという、暗黙の設定が入るから)

# (提言)岡部は仕方ないとして、紅莉栖は科学者なんだから、岡部に正しい用語の使い方を説明すべきだと思う。
# 少なくとも、相対論に精通している紅莉栖が「世界線」を使っちゃうのば、やっぱりマズいと思う。

2018-02-16 mingw64でfork(),waitpid(), kill()を何とかしたい [長年日記]

/*
  ================================================
  mingw64でfork(),waitpid(), kill()を何とかしたい
  ================================================
 
  ●参照させて頂いたページ
  https://gist.github.com/Cr4sh/126d844c28a7fbfd25c6
  http://7shi.hateblo.jp/entry/2012/06/19/213405
  http://www.fireproject.jp/feature/c-language/process/fork-wait.html
 
  ●コンパイル:
  gcc -g fork2.cpp -o fork2
 
  ●その他
  「mingw64でfork()を何とかしたい」の後に読むと分かりやすいかも
 
 
  ちなみにWindowsのコマンドプロンプトではprintf()の表示がされない(理由不明)ので
 
  > fork2 > dummy.txt
 
  などとして確認すること。
 
*/
 
/*
 * fork.c
 * Experimental fork() on Windows.  Requires NT 6 subsystem or
 * newer.
 *
 * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * This software is provided 'as is' and without any warranty, express or
 * implied.  In no event shall the authors be liable for any damages arising
 * from the use of this software.
 */
 
#define _WIN32_WINNT 0x0600
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winnt.h>
#include <ntdef.h>
#include <stdio.h>
#include <errno.h>
#include <process.h>
 
#define CHILD_NUM 10
#define WNOHANG		1	/* dont hang in wait */ // ここではコンパイル通す為のダミー値
 
#ifdef __MINGW32__
typedef struct _CLIENT_ID {
  PVOID UniqueProcess;
  PVOID UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
 
typedef struct _SECTION_IMAGE_INFORMATION {
  PVOID EntryPoint;
  ULONG StackZeroBits;
  ULONG StackReserved;
  ULONG StackCommit;
  ULONG ImageSubsystem;
  WORD SubSystemVersionLow;
  WORD SubSystemVersionHigh;
  ULONG Unknown1;
  ULONG ImageCharacteristics;
  ULONG ImageMachineType;
  ULONG Unknown2[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
 
typedef struct _RTL_USER_PROCESS_INFORMATION {
  ULONG Size;
  HANDLE Process;
  HANDLE Thread;
  CLIENT_ID ClientId;
  SECTION_IMAGE_INFORMATION ImageInformation;
} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;
 
#define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED	0x00000001
#define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES		0x00000002
#define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE		0x00000004
 
#define RTL_CLONE_PARENT				0
#define RTL_CLONE_CHILD					297
 
#endif
 
typedef NTSTATUS (*RtlCloneUserProcess_f)
(ULONG ProcessFlags,
 PSECURITY_DESCRIPTOR ProcessSecurityDescriptor /* optional */,
 PSECURITY_DESCRIPTOR ThreadSecurityDescriptor /* optional */,
 HANDLE DebugPort /* optional */,
 PRTL_USER_PROCESS_INFORMATION ProcessInformation);
 
pid_t fork(void)
{
  HMODULE mod;
  RtlCloneUserProcess_f clone_p;
  RTL_USER_PROCESS_INFORMATION process_info;
  NTSTATUS result;
  
  mod = GetModuleHandle("ntdll.dll");
  if (!mod)
	return -ENOSYS;
  
  //clone_p = GetProcAddress(mod, "RtlCloneUserProcess"); // Ebata 
  clone_p = (RtlCloneUserProcess_f)GetProcAddress(mod, "RtlCloneUserProcess");
 
  if (clone_p == NULL)
	return -ENOSYS;
  
  /* lets do this */
  result = clone_p(RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED | RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES, NULL, NULL, NULL, &process_info);
  
  if (result == RTL_CLONE_PARENT)
	{
	  HANDLE me = GetCurrentProcess();
	  pid_t child_pid;
	  
	  child_pid = GetProcessId(process_info.Process);
	  
	  ResumeThread(process_info.Thread);
	  CloseHandle(process_info.Process);
	  CloseHandle(process_info.Thread);
	  
	  return child_pid;
	}
  else if (result == RTL_CLONE_CHILD)
	{
	  /* fix stdio */
	  AllocConsole();
	  return 0;
	}
  else
	return -1;
  
  /* NOTREACHED */
  return -1;
}
 
int kill(pid_t pid, int sig) {
    int ret;
    HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
    ret = TerminateProcess(h, 0) ? 0 : -1;
    CloseHandle(h);
    return ret;
}
 
 
#if 0
int waitpid(pid_t pid, int *stat_loc, int options) {
  int i = 1;
  return   _cwait(stat_loc, pid, WAIT_CHILD);
}
#endif
 
int waitpid(pid_t pid,  DWORD dwMilliseconds)  // Ebata's original waitpid()
{
  HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);	  
  //  WaitForSingleObject(h, INFINITE);
  int ret = WaitForSingleObject(h, dwMilliseconds);
  
  CloseHandle(h);
  
  return ret;
}
 
 
int main(void){
  
  pid_t result_pid = fork(); 
  
  if (result_pid == 0){ // 子プロセス
	
	printf("Child process started.\n");
	printf("Wait 10 seconds.\n");
	printf("result_pid = %d child process.\tpid = %d\n",result_pid,getpid());
	fflush(stdout);
 
	Sleep(10000); // 10秒くらいの生存期間
 
	fprintf(stdout,"Child process ended.\n");
	fflush(stdout);
	
  }
  else{ // 親プロセス
 
	printf("Parents process started.\n");
	fflush(stdout);
 
	// 親プロセスの方には、子プロセスのIDが入るので、それを監視する
 
	waitpid(result_pid,  INFINITE);  // 子プロセス(1つのみ)が終了するまで止まる
	//waitpid(result_pid,  100); // 100msのみ停止
 
	fprintf(stdout,"Parent process ended.\n");
	fflush(stdout);
  }
 
  return 0;
}
syntax2html

2018-02-14 mingw64でfork()を何とかしたい [長年日記]

/*
  mingw64でfork()を何とかしたい
 
  gcc -g fork.c -o fork
  (ちゃんと動いているのかどうか不明だけど)
 
  ちなみに、"コマンドプロント"だけだと、"ko"が出てこないので、
  fork > dummy.txt 
  みたいにしないと、稼動確認できないみたい
 
  ちなみにタスクマネージャで見る限り、2つのプロセスは動いているみたい
 
  gcc -g fork.c -o fork
  fork.c:81:7: warning: conflicting types for built-in function 'fork'
  pid_t fork(void)
  ^
  fork.c: In function 'fork':
  fork.c:92:11: warning: assignment from incompatible pointer type
  clone_p = GetProcAddress(mod, "RtlCloneUserProcess");
  
  という警告がでるが、良く分からんので、今は放置
*/
 
/*
 * fork.c
 * Experimental fork() on Windows.  Requires NT 6 subsystem or
 * newer.
 *
 * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * This software is provided 'as is' and without any warranty, express or
 * implied.  In no event shall the authors be liable for any damages arising
 * from the use of this software.
 */
 
#define _WIN32_WINNT 0x0600
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winnt.h>
#include <ntdef.h>
#include <stdio.h>
#include <errno.h>
#include <process.h>
 
#ifdef __MINGW32__
typedef struct _CLIENT_ID {
  PVOID UniqueProcess;
  PVOID UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
 
typedef struct _SECTION_IMAGE_INFORMATION {
  PVOID EntryPoint;
  ULONG StackZeroBits;
  ULONG StackReserved;
  ULONG StackCommit;
  ULONG ImageSubsystem;
  WORD SubSystemVersionLow;
  WORD SubSystemVersionHigh;
  ULONG Unknown1;
  ULONG ImageCharacteristics;
  ULONG ImageMachineType;
  ULONG Unknown2[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
 
typedef struct _RTL_USER_PROCESS_INFORMATION {
  ULONG Size;
  HANDLE Process;
  HANDLE Thread;
  CLIENT_ID ClientId;
  SECTION_IMAGE_INFORMATION ImageInformation;
} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;
 
#define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED	0x00000001
#define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES		0x00000002
#define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE		0x00000004
 
#define RTL_CLONE_PARENT				0
#define RTL_CLONE_CHILD					297
 
#endif
 
typedef NTSTATUS (*RtlCloneUserProcess_f)
(ULONG ProcessFlags,
 PSECURITY_DESCRIPTOR ProcessSecurityDescriptor /* optional */,
 PSECURITY_DESCRIPTOR ThreadSecurityDescriptor /* optional */,
 HANDLE DebugPort /* optional */,
 PRTL_USER_PROCESS_INFORMATION ProcessInformation);
 
pid_t fork(void)
{
  HMODULE mod;
  RtlCloneUserProcess_f clone_p;
  RTL_USER_PROCESS_INFORMATION process_info;
  NTSTATUS result;
  
  mod = GetModuleHandle("ntdll.dll");
  if (!mod)
	return -ENOSYS;
  
  clone_p = GetProcAddress(mod, "RtlCloneUserProcess");
  if (clone_p == NULL)
	return -ENOSYS;
  
  /* lets do this */
  result = clone_p(RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED | RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES, NULL, NULL, NULL, &process_info);
  
  if (result == RTL_CLONE_PARENT)
	{
	  HANDLE me = GetCurrentProcess();
	  pid_t child_pid;
	  
	  child_pid = GetProcessId(process_info.Process);
	  
	  ResumeThread(process_info.Thread);
	  CloseHandle(process_info.Process);
	  CloseHandle(process_info.Thread);
	  
	  return child_pid;
	}
  else if (result == RTL_CLONE_CHILD)
	{
	  /* fix stdio */
	  AllocConsole();
	  return 0;
	}
  else
	return -1;
  
  /* NOTREACHED */
  return -1;
}
 
 
#if 0
// #ifdef __TEST__
int main(int argc, const char *argv[])
{
  pid_t pid = fork();
  
  printf("pid %d\n", pid);  
  
  switch (pid) {
  case 0:
	{
	  printf("parent %d\n", pid);
	  FILE *f = fopen("forktest.dat", "w");
	  fprintf(f, "ok\n");
	  fclose(f);
	  break;
	}
  default:
	printf("child %d\n", pid);
	int i = 0; 
	while (i < 10000){
	  i++;
	}
	break;
  }
}
//#endif
 
#endif
 
#if 1
 
int main(int argc, char *argv[])
{
  int i,pid;
  int pid2;
  int status;
  
  // printf("---Fork test---\n");
  pid = fork(); /*子プロセスの生成。戻り値 0:子プロセス -1:エラー 0以上:親プロセス */
  printf("fork() : pid = %d\n" , pid);
  
  for(i = 0 ; i < 5 ; i++){
	//my_sleep(1); /*一秒待機*/
	Sleep(1000);
	pid2 = getpid();
	printf("%d : %s %d %d\n" , i , pid > 0 ? "Oya:" : "Ko :" , pid2, pid);
	fflush(stdout); // これを省略すると、バラバラに出力されなくなる
  }
  //wait(&status); /*子プロセスが終了するのを待つ→wait()関数がない*/
  return EXIT_SUCCESS;
}
#endif
syntax2html

2018-02-13 DMTCP: Distributed MultiThreaded CheckPointing [長年日記]

_ 途中の状態のプロセスを凍らせてセーブするもの(らしい)

途中の状態のプロセスを凍らせてセーブするもの(らしい)

この説明が詳しい http://dmtcp.sourceforge.net/dmtcp-mug-17.pdf


2018-02-04 副業シミュレーション [長年日記]

/*
  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);  
 
 
}
syntax2html

2018-01-27 複数のカラムからなるprimary keyを作成する [長年日記]

  create table side_list(
    counter int,
    s int, 
    e int, 
    c real,
    PRIMARY KEY (s, e)
  );

2018-01-26 postgreSQLデータベースからの読み出すプログラム [長年日記]

/*
   postgreSQLデータベースからの読み出し テストプログラム
*/
 
/*
  g++ -g read_sql.cpp -o read_sql.exe -I"D:\PostgreSQL\pg96\include" -L"D:\PostgreSQL\pg96\lib" -llibpq
*/
 
 
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include "libpq-fe.h"
 
const char *conninfo = "host=localhost user=postgres password=c-anemone dbname=ca_db";
PGconn *conn;
 
int main()
{
  // データベースとの接続を確立する 
  conn = PQconnectdb(conninfo);
 
  // バックエンドとの接続確立に成功したかを確認する */
  if (PQstatus(conn) != CONNECTION_OK){
	fprintf(stderr, "Connection to database failed: %s",
			PQerrorMessage(conn));
  }
 
  char stringSQL[256] = {0};
	
 
  sprintf(stringSQL, "SELECT * FROM side_list where s = 90;"); // 検索条件
  PGresult *res = PQexec(conn, stringSQL);
 
  // エラーチェック
  if( PQresultStatus( res ) != PGRES_TUPLES_OK ) {
    // error
    printf("error_2");
    exit(-1);
  }  
 
  int res_cnt = PQntuples( res ); // 検索数を得る
 
  for(int loop = 0; loop < res_cnt ; loop++) {
	int a = atoi(PQgetvalue(res, loop, 0));  // 文字列から整数へ
	int b = atoi(PQgetvalue(res, loop, 1));  // 文字列から整数へ
	int c = atoi(PQgetvalue(res, loop, 2));  // 文字列から整数へ
	double d = atof(PQgetvalue(res, loop, 3));  // 文字列から実数へ
 
	printf("a=%d, b=%d, c=%d, d=%f\n", a,b,c,d);
  }
 
  // 値セットが無い場合でも必ず結果をクリアする
  PQclear(res);
 
  
  return 0;
}
syntax2html

2018-01-25 C++プログラムでPostgreSQLに漢字を書き込めるようにする [長年日記]

/*
  「プログラムでは日本語入力ができないのでSQL文を力づくで作成」をなんとか対応したプログラム
 
  245行目の
 
  //////////////  漢字を書き込めるようにする、魔法の一行
  PQsetClientEncoding(conn, "SJIS"); // 左の通り、クライアント側エンコード指定
  // もしくは、SQL文として「PQExec(conn, "SET CLIENT_ENCODING TO 'SJIS'")」でも可
  ////////////// 
  
  に注目
*/
 
/*
  g++ -g station_sql.cpp -o station_sql.exe -I"D:\PostgreSQL\pg96\include" -L"D:\PostgreSQL\pg96\lib" -llibpq
 
*/
 
/*
   C:\Users\yrl-user>psql -h localhost -U postgres	← ログイン
   postgres=# \l	
   postgres=# create database cx_dx;
   
   以下をコピペする
   create table station_info (
          serial_number int,
          station_name varchar(40),
          longitude real,
          latitude real,
          bus_terminal boolean,
          bus_number int
	);
 */
 
/*
 
ca_db=# \dt station_info
              リレーションの一覧
 スキーマ |     名前     |    型    |  所有者
----------+--------------+----------+----------
 public   | station_info | テーブル | postgres
(1 行)
 
 
ca_db=# \d station_info
         テーブル "public.station_info"
      列       |          型           | 修飾語
---------------+-----------------------+--------
 serial_number | integer               |
 station_name  | character varying(40) |
 longitude     | real                  |
 latitude      | real                  |
 bus_terminal  | boolean               |
 bus_number    | integer               |
 
*/
syntax2html
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include "libpq-fe.h"
 
// 車両状態情報(現在地)
typedef struct location{
  // ちなみに X,Y 軸座標は、→に+  ↑に+
  double longitude; // 経度 東経 139.691 X軸  
  double latitude;  // 緯度 北緯 35.698  Y軸 
} LOCATION;
 
// 路線単位の駅番号
typedef struct station_number{
  int line;
  int number;
} STATION_NUMBER,AREA;
 
// 駅の情報を格納する構造体
typedef struct station{
  int serial_number;
  char name[40];
  LOCATION location;
  int intersection;
  STATION_NUMBER station_number[10];
  int person_number; 
  int bus_number; 
  double diff_tokyo;
}STATION;
 
STATION station[] = {
 
  // 中央線  全長約28km 上り14 下り14   2km で 1本というのは悪くない
  {0,"国分寺",{139.480841,35.700123},1,{{0,0}},0,5,-0.01},
  {1,"武蔵小金井",{139.506483,35.701337},1,{{0,1}},0,0,-0.01},
  {2,"東小金井",{139.524837,35.701643},1,{{0,2}},0,0,-0.01},
  {3,"武蔵境",{139.543402,35.702083},1,{{0,3}},0,5,-0.01},
  {4,"三鷹",{139.560325,35.702683},1,{{0,4}},0,0,-0.01},
  {5,"吉祥寺",{139.579765,35.703119},2,{{0,5},{1,0}},0,5,-0.01},
  {6,"西荻窪",{139.599361,35.703842},1,{0,6},0,0,-0.01},
  {7,"荻窪",{139.620109,35.704523},1,{{0,7}},0,5,-0.01},
  {8,"阿佐ヶ谷",{139.635859,35.704872},1,{{0,8}},0,5,-0.01},  
  {9,"高円寺",{139.649664,35.705326},1,{{0,9}},0,0,-0.01},
  {10,"中野",{139.665835,35.705765},1,{{0,10}},0,0,-0.01},
  {11,"新宿",{139.700464,35.689729},4,{{0,11},{2,0},{2,29},{3,23}},0,5,-0.01},
  {12,"四ツ谷",{139.730644,35.686041},1,{{0,12}},0,5,-0.01},
  {13,"御茶ノ水",{139.764955,35.699605},1,{{0,13}},0,0,-0.01},
  {14,"神田",{139.770641,35.691173},1,{{0,14}},0,0,-0.01},
  {15,"東京",{139.766103,35.681391},2,{{0,15},{2,13}},0,5,-0.01},
  // 合計15駅
 
  // 京王井の頭線 全長12.55km 上り6 下り6
 
  //吉祥寺	139.580306	35.702291(既出) {1,0}
  {16,"井の頭公園",{139.583112,35.697304},1,{{1,1}},0,0,-0.01},
  {17,"三鷹台",{139.589298,35.692046},1,{{1,2}},0,0,-0.01},
  {18,"久我山",{139.599308,35.688151},1,{{1,3}},0,5,-0.01},
  {19,"富士見ヶ丘",{139.607072,35.684805},1,{{1,4}},0,0,-0.01},
  {20,"高井戸",{139.615115,35.683253},1,{{1,5}},0,0,-0.01},
  {21,"西永福",{139.634936,35.678918},1,{{1,6}},0,0,-0.01},
  {22,"永福町",{139.6404349,35.6762763},1,{{1,7}},0,5,-0.01},
  {23,"明大前",{139.650352,35.668758},2,{{1,8},{3,18}},0,5,-0.01},
  {24,"東松原",{139.655535,35.662634},1,{{1,9}},0,0,-0.01},
  {25,"新代田",{139.660524,35.662593},1,{{1,10}},0,0,-0.01},
  {26,"下北沢",{139.6649004,35.661563},1,{{1,11}},0,5,-0.01},
  {27,"渋谷",{139.699553,35.6581046},2,{{1,12},{2,3}},0,5,-0.01},
 
  // 山手線 全長34.5km → 上り15 下り15
  //新宿	139.700464	35.689729(既出) {2,0}
  {28,"代々木",{139.702042,35.683061},1,{{2,1}},0,0,-0.01},
  {29,"原宿",{139.702592,35.670646},1,{{2,2}},0,0,-0.01},
  // 渋谷	139.701238	35.658871(既出) {2,3}
  {30,"恵比寿",{139.71007,35.646685},1,{{2,4}},0,0,-0.01},
  {31,"目黒",{139.715775,35.633923},1,{{2,5}},0,0,-0.01},
  {32,"五反田",{139.723822,35.625974},1,{{2,6}},0,0,-0.01},
  {33,"大崎",{139.728439,35.619772},1,{{2,7}},0,0,-0.01},
  {34,"品川",{139.738999,35.62876},1,{{2,8}},0,0,-0.01},
  {35,"田町",{139.747575,35.645736},1,{{2,9}},0,0,-0.01},
  {36,"浜松町",{139.757135,35.655391},1,{{2,10}},0,0,-0.01},
  {37,"新橋",{139.758587,35.666195},1,{{2,11}},0,5,-0.01},	
  {38,"有楽町",{139.763806,35.675441},1,{{2,12}},0,0,-0.01},	
  // 東京	139.766103	35.681391(既出){2,13}
  {39,"神田",{139.770641,35.691173},1,{{2,14}},0,0,-0.01},	
  {40,"秋葉原",{139.773288,35.698619},1,{{2,15}},0,5,-0.01},
  {41,"御徒町",{139.774727,35.707282},1,{{2,16}},0,0,-0.01},
  {42,"上野",{139.777043,35.71379},1,{{2,17}},0,5,-0.01},
  {43,"鶯谷",{139.778015,35.721484},1,{{2,18}},0,0,-0.01},
  {44,"日暮里",{139.771287,35.727908},1,{{2,19}},0,5,-0.01},
  {45,"西日暮里",{139.766857,35.731954},1,{{2,20}},0,0,-0.01},
  {46,"田端",{139.761229,35.737781},1,{{2,21}},0,5,-0.01},
  {47,"駒込",{139.748053,35.736825},1,{{2,22}},0,0,-0.01},
  {48,"巣鴨",{139.739303,35.733445},1,{{2,23}},0,0,-0.01},
  {49,"大塚",{139.728584,35.731412},1,{{2,24}},0,0,-0.01},
  {50,"池袋",{139.711461,35.72913},2,{{2,25},{5,7}},0,5,-0.01},
  {51,"目白",{139.706228,35.720476},1,{{2,26}},0,0,-0.01},
  {52,"高田馬場",{139.703715,35.712677},2,{{2,27},{4,17}},0,5,-0.01},
  {53,"新大久保",{139.700261,35.700875},1,{{2,28}},0,0,-0.01},
  // 新宿 139.700464	35.689729(既出) {2,29}
 
  // 京王線 駅数24  全長15.23km 上り7 下り7
  {54,"府中",{139.4799,35.672245},1,{{3,0}},0,5,-0.01},
  {55,"東府中",{139.495257,35.668766},1,{{3,1}},0,0,-0.01},
  {56,"多磨霊園",{139.502615,35.666197},1,{{3,2}},0,0,-0.01},
  {57,"武蔵野台",{139.511289,35.664159},1,{{3,3}},0,0,-0.01},
  {58,"飛田給",{139.523666,35.660121},1,{{3,4}},0,5,-0.01},
  {59,"西調布",{139.529822,35.657169},1,{{3,5}},0,0,-0.01},
  {60,"調布",{139.543988,35.652181},1,{{3,6}},0,0,-0.01},
  {61,"布田",{139.551557,35.649904},1,{{3,7}},0,0,-0.01},
  {62,"国領",{139.558036,35.650087},1,{{3,8}},0,0,-0.01},
  {63,"柴崎",{139.56658,35.653997},1,{{3,9}},0,0,-0.01},
  {64,"つつじヶ丘",{139.575103,35.657936},1,{{3,10}},0,5,-0.01},
  {65,"仙川",{139.584908,35.662257},1,{{3,11}},0,0,-0.01},
  {66,"千歳烏山",{139.60067,35.667921},1,{{3,12}},0,5,-0.01},
  {67,"芦花公園",{139.608247,35.670479},1,{{3,13}},0,0,-0.01},
  {68,"八幡山",{139.614927,35.669982},1,{{3,14}},0,0,-0.01},
  {69,"上北沢",{139.62329,35.668857},1,{{3,15}},0,0,-0.01},
  {70,"桜上水",{139.63129,35.66768},1,{{3,16}},0,0,-0.01},
  {71,"下高井戸",{139.641372,35.66615},1,{{3,17}},0,0,-0.01},
  // 明大前	139.650352	35.668758(既出){3,18}
  {72,"代田橋",{139.659413,35.671092},1,{{3,19}},0,0,-0.01},
  {73,"笹塚",{139.667251,35.673758},1,{{3,20}},0,5,-0.01},
  {74,"幡ヶ谷",{139.676183,35.677061},1,{{3,21}},0,0,-0.01},
  {75,"初台",{139.686354,35.68123},1,{{3,22}},0,0,-0.01},
  // 新宿	139.699187	35.690163(既出){3,23}
 
  // 西武新宿線 全長20.42km 上り9 下り9 18駅
 
  {76,"小平",{139.488491,35.736963},1,{{4,0}},0,5,-0.01},
  {77,"花小金井",{139.513228,35.726129},1,{{4,1}},0,0,-0.01},
  {78,"田無",{139.539259,35.727307},1,{{4,2}},0,0,-0.01},
  {79,"西武柳沢",{139.552477,35.728621},1,{{4,3}},0,5,-0.01},   // No:79
  {80,"東伏見",{139.563529,35.728761},1,{{4,4}},0,0,-0.01},
  {81,"武蔵関",{139.576417,35.7276},1,{{4,5}},0,0,-0.01},
  {82,"上石神井",{139.592266,35.726189},1,{{4,6}},0,0,-0.01},
  {83,"上井草",{139.602937,35.725326},1,{{4,7}},0,0,-0.01},
  {84,"井荻",{139.615303,35.72469},1,{{4,8}},0,0,-0.01},
  {85,"下井草",{139.624688,35.723852},1,{{4,9}},0,5,-0.01},
  {86,"鷺ノ宮",{139.63892,35.722605},1,{{4,10}},0,0,-0.01},
  {87,"都立家政",{139.644839,35.722313},1,{{4,11}},0,0,-0.01},
  {88,"野方",{139.652733,35.719658},1,{{4,12}},0,0,-0.01},
  {89,"沼袋",{139.663841,35.719458},1,{{4,13}},0,5,-0.01},       // No:89
  {90,"新井薬師前",{139.672582,35.715778},1,{{4,14}},0,0,-0.01}, // No:90
  {91,"中井",{139.686967,35.715106},1,{{4,15}},0,0,-0.01},
  {92,"下落合",{139.695391,35.715846},1,{{4,16}},0,5,-0.01},
  // 高田馬場	139.703715	35.712677(既出){4,17}
 
  // 西武池袋線 全長8.2km  上り4 下り4  8駅
  {93,"富士見台",{139.62969,35.735867},1,{{5,0}},0,5,-0.01},
  {94,"中村橋",{139.637456,35.736767},1,{{5,1}},0,0,-0.01},
  {95,"練馬",{139.654368,35.737893},1,{{5,2}},0,0,-0.01},
  {96,"桜台",{139.662602,35.738797},1,{{5,3}},0,0,-0.01},
  {97,"江古田",{139.672814,35.737557},1,{{5,4}},0,0,-0.01},  //
  {98,"東長崎",{139.683294,35.73003},1,{{5,5}},0,5,-0.01},
  {99,"椎名町",{139.694363,35.726572},1,{{5,6}},0,0,-0.01},
  // 池袋	139.711461	35.72913(既出){5,7}
 
  {-1,"",{0,0},0} // 終了
};
 
const char *conninfo = "host=localhost user=postgres password=x-axexoxe dbname=cx_dx";
PGconn *conn;
 
int main()
{
  // データベースとの接続を確立する 
  conn = PQconnectdb(conninfo);
 
  // 先ずはデータの全消去
  PGresult *res = PQexec(conn, "DELETE FROM station_info;");
  PQclear(res);
  
  // バックエンドとの接続確立に成功したかを確認する */
  if (PQstatus(conn) != CONNECTION_OK){
	fprintf(stderr, "Connection to database failed: %s",
			PQerrorMessage(conn));
  }
 
  //////////////  漢字を書き込めるようにする、魔法の一行
  PQsetClientEncoding(conn, "SJIS"); // 左の通り、クライアント側エンコード指定
  // もしくは、SQL文として「PQExec(conn, "SET CLIENT_ENCODING TO 'SJIS'")」でも可
  ////////////// 
 
  for (int i = 0; i < 100; i++){
	char stringSQL[256] = {0};
	char tfflag[2] = {0};
	
	if (station[i].bus_number > 0){
	  strcpy(tfflag, "t");
	} else {
	  strcpy(tfflag, "f");
	}
	
	sprintf(stringSQL, "INSERT INTO station_info(serial_number,longitude, latitude, bus_number, bus_terminal, station_name) VALUES(%d,%f,%f,%d,'%s','%s');",
			station[i].serial_number,
			station[i].location.longitude,
			station[i].location.latitude,
			station[i].bus_number,
			tfflag,
			station[i].name);
	
#if 0
	printf("%s\n",stringSQL);
#endif
	
	PGresult *res = PQexec(conn, stringSQL);
	if (res == NULL || PQresultStatus(res) != PGRES_COMMAND_OK) {
	  // SQLコマンドが失敗した場合
	  fprintf(stderr, "INSERT COMMAND IS FAILED.",
			  PQerrorMessage(conn));
	}
	
	// 値セットが無い場合でも必ず結果をクリアする
	PQclear(res);
  }
  
  return 0;
}
syntax2html

2018-01-24 PostgreSQLの基本的なコマンド [長年日記]

内容コマンド例
サービスの起動 postgres -D /usr/local/var/postgres
デフォルトのテーブルに接続 psql -d postgres
直接テーブルに接続 psql -d テーブル名
接続解除 \q
データベース一覧の表示 \l
データベースの選択 \c データベース名
テーブルの作成 create table テーブル名 (

counter int primary key,

present_station int,

departure_station int,

present_time time

);

データの書き込み INSERT INTO テーブル名(counter, present_station, departure_station, present_time) VALUES(1, 2, 3, '12:23:34');
データの上書き UPDATE テーブル名 set present_time = '23:34:45' WHERE counter = 1;
テーブル一覧の表示 \dt;
テーブル構造の表示 \d テーブル名;
テーブル内のデータを一覧 select * from テーブル名;
指定したカラムの内容を小さい順に表示 select * from テーブル名 order by カラム;
指定したカラムの内容を大きい順に表示 select * from テーブル名 order by カラム desc;
表示数指定 select * from テーブル名 limit 数;
表示の開始位置指定 select * from テーブル名 offset 数;
カラム内の任意の文字を表示 select distinct カラム名 from テーブル名;
カラム内の合計値 select sum(カラム名) from テーブル名;
カラム内の最大値 select max(カラム名) from テーブル名;
カラム内の最小値 select min(カラム名) from テーブル名;
カラム内の平均値 select avg(カラム名) from テーブル名;
データの更新 update テーブル名 set 更新内容;
全データの削除 delete from テーブル名;
データの削除 delete from テーブル名 where 条件;
テーブルのオーナーの変更 alter table テーブル名 owner to オーナー名;
文字数 select length(カラム名) from テーブル名;
文字列連結 select concat(文字列, 文字列, ...) from テーブル名;
カラムの追加 alter table テーブル名 add カラム名 データ型;
カラムの削除 alter table テーブル名 drop カラム名;
カラム名の変更 alter table テーブル名 rename カラム名 to 新カラム名;
カラムのデータ型を変更する alter table テーブル名 alter カラム名 type データ型;
インデックス追加 create index インデックス名 on テーブル名(カラム名);
インデックス削除 drop index インデックス名;
viewの作成 create view ビュー名 as viewに指定するコマンド;
view一覧の確認 \dv;
viewの使用方法 select * from ビュー名;
viewの削除 drop view ビュー名;
SQL文を外部ファイルに書いて実行する時に使う \i ファイル名