2021/11,江端さんの技術メモ

package main

import (
"fmt"
"time"
)

var ch chan int // チャネルを運ぶためのグローバルチャネル

func bus_func(i int) {
ch = make(chan int) // スレッドの中でチャネルを作っても動かない

ch <- 10
fmt.Println("After", ch)

time.Sleep(3)
}

func main() {

go bus_func(1)

fmt.Println(<-ch)

}

スレッドの中で(というかサブルーチンの中で)チャネルは厳しいのかな?

package main

import (
	"fmt"
	"time"
)

var ch chan int // チャネルを運ぶためのグローバルチャネル

func bus_func(i int) {

	ch <- 10
	fmt.Println("After", ch)

	time.Sleep(3)
}

func main() {

	ch = make(chan int) // メインで作った場合は動く

	go bus_func(1)

	fmt.Println(<-ch)

}

チャネルを定数で確保しない方法ってないかなぁ。

スレッドで、オブジェクトを実体化して、そこで送受信させる。

package main

import (
	"fmt"
	"sync"
	"time"
)

type BUS struct {
	number int
}

func bus_func(i int, wg *sync.WaitGroup, ch1 chan int, ch2 chan int) {
	defer wg.Done()

	t := time.NewTicker(1 * time.Second) // 1秒おきに通知

	bus := BUS{}
	bus.number = i

	pointer_bus := &bus

	fmt.Println(pointer_bus)

	// 待受
	for {
		select {
		case v := <-ch1: // 受信
			if v == -1 { //終了コードの受信
				return // スレッドを自滅させる
			} else {
				fmt.Println(v)
			}
		case <-t.C: // 送信 (1秒まったら、むりやりこっちにくる)
			ch2 <- i + 100
		}
	}

}

//var c = make([]chan int, 3) // 間違い
// var c []chan int  これは実行時にエラーとなる

var c1 [3]chan int // チャネルをグローバル変数で置く方法の、現時点での正解
var c2 [3]chan int // チャネルをグローバル変数で置く方法の、現時点での正解

func main() {
	var wg sync.WaitGroup
	defer wg.Wait()

	//c := make(chan int)

	// バスエージェントの生成 3台
	for i := 0; i < 3; i++ {
		wg.Add(1)

		c1[i] = make(chan int)
		c2[i] = make(chan int)
		go bus_func(i, &wg, c1[i], c2[i])
	}

	// バスエージェントにメッセージを送る

	c1[0] <- 50
	c1[1] <- 30
	c1[2] <- 10

	c1[0] <- 50
	c1[1] <- 30
	c1[2] <- 10

	c1[0] <- 50
	c1[1] <- 30
	c1[2] <- 10

	fmt.Println(<-c2[0])
	fmt.Println(<-c2[1])
	fmt.Println(<-c2[2])

	c1[0] <- -1 // スレッド終了コードの送信
	c1[1] <- -1 // スレッド終了コードの送信
	c1[2] <- -1 // スレッド終了コードの送信

}

2021/11,未分類,江端さんの技術メモ

これまでC/C++言語で作ってきたスケーラブルなエージェントシミュレーションを、golangで作りかえようとしています。

これまでもメイン関数に縛られずに、スレッドを自由に動き回すシミュレータは作ってきたのですが、C/C++のスレッドは、いかんせんメモリサイズが大きく、万の単位のエージェントには耐えられないという問題があります。

そんな感じで、golangに乗り換えしているのですが、色々文法が面倒くさいです。

例えば、スレッドの中で作った構造体と通信を行う方法として、go func() で返り値(return)が欲しいと思っていたのだけど、考えてみれば、スレッド化したfunc()は、それが終了するまでreturn値を返す訳ないと気がつきました。

だから,

go func_xxxx()

は、

go i:= finc_xxxx()

もダメだし

i := go func_xxxx()

もダメということで ―― では、スレッドの中の情報にどうやってアクセスすればいいかが、分かりません。

とすれば、スレッド側で送受信機能を持たせることになるのかなぁ、と思って、以下のようなコードを書いてみました。

package main

import (
	"fmt"
	"sync"
)

type BUS struct {
	number int
}

func bus_func(i int, wg *sync.WaitGroup, ch chan int) {
	defer wg.Done()

	bus := BUS{}
	bus.number = i

	pointer_bus := &bus

	fmt.Println(pointer_bus)

	for {
		select {
		case v := <-ch:
			fmt.Println(i, v)
		}
	}

}

func main() {
	var wg sync.WaitGroup
	defer wg.Wait()

	c := make(chan int)

	// バスエージェントの生成 3台
	for i := 0; i < 3; i++ {
		wg.Add(1)

		go bus_func(i, &wg, c)
	}

	// バスエージェントにメッセージを送る

	c <- 50
	c <- 30
	c <- 10

	c <- 50
	c <- 30
	c <- 10

	c <- 50
	c <- 30
	c <- 10

}

ただ、この場合、cチャネルは適当に投げられるので、どのオブジェクトにメッセージに届くか分からないので、もう少し工夫をしてみます。

package main

import (
	"fmt"
	"sync"
)

type BUS struct {
	number int
}

func bus_func(i int, wg *sync.WaitGroup, ch chan int) {
	defer wg.Done()

	bus := BUS{}
	bus.number = i

	pointer_bus := &bus

	fmt.Println(pointer_bus)

	for {
		select {
		case v := <-ch:
			fmt.Println(i, v)
		}
	}

}

//var c = make([]chan int, 3) // 間違い

var c [3]chan int // チャネルをグローバル変数で置く方法の、現時点での正解

// var c []chan int  これは実行時にエラーとなる

func main() {
	var wg sync.WaitGroup
	defer wg.Wait()

	//c := make(chan int)

	// バスエージェントの生成 3台
	for i := 0; i < 3; i++ {
		wg.Add(1)

		c[i] = make(chan int)
		go bus_func(i, &wg, c[i])
	}

	// バスエージェントにメッセージを送る

	c[0] <- 50
	c[1] <- 30
	c[2] <- 10

	c[0] <- 50
	c[1] <- 30
	c[2] <- 10

	c[0] <- 50
	c[1] <- 30
	c[2] <- 10

}

 

2021/11,江端さんの技術メモ

package main

// C:\Users\ebata\goga\3-12

import (
	"fmt"
	"sync"
	"time"
)

type BUS struct {
	number int
}

//var l sync.Mutex
//var c1 chan int

func (bus *BUS) bus_func_recv(lr *sync.Mutex, cr *sync.Cond) {
	// 受信(ブロードキャスト専用)
	fmt.Println("bus.number by recv:", bus.number)
	lr.Lock()
	defer lr.Unlock()
	fmt.Println("before cr.Wait")
	for {
		cr.Wait()          // ロック
		fmt.Println("hi ") // ここで受信処理を行う
	}

}

func (bus *BUS) bus_func_send(lb *sync.Mutex, ch1 chan int) {
	// 送信専用
	fmt.Println("bus.number by send:", bus.number)

	lb.Lock()
	defer lb.Unlock()
	ch1 <- bus.number
}

func main() {
	//wg := sync.WaitGroup{}
	l := sync.Mutex{}
	c1 := make(chan int)

	l2 := sync.Mutex{}
	c2 := sync.NewCond(&l2)

	for i := 0; i < 10; i++ {
		bus := BUS{i}
		go bus.bus_func_send(&l, c1)
		go bus.bus_func_recv(&l2, c2)
	}

	time.Sleep(time.Second)

	c2.Broadcast()

	for {
		select {
		case v := <-c1:
			fmt.Println(v)
		//default:
		//	fmt.Println("default")
		case <-time.After(3 * time.Second):

			return
		}
	}

	close(c1)

	//wg.Wait()

	//time.Sleep(3 * time.Second)




package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

type PERSON struct {
	lon_destination float64
	lat_destination float64
	lon_arrival     float64
	lat_arrival     float64
	bus             BUS
}

type BUS struct {
	lon_present float64
	lat_present float64
	//	person      []PERSON
}

func random(min, max float64) float64 {
	rand.Seed(time.Now().UnixNano())
	return rand.Float64()*(max-min) + min
}

func person(i int, wg *sync.WaitGroup) {
	defer wg.Done()
	person := PERSON{}
	// 出発座標、到着座標の入力
	person.lon_destination = random(139.480, 139.460)
	person.lat_destination = random(35.602, 35.586)
	person.lon_arrival = random(139.480, 139.460)
	person.lat_arrival = random(35.602, 35.586)

	fmt.Println(person, i)
}

func bus(i int, wg *sync.WaitGroup) {
	defer wg.Done()
	bus := BUS{}

	fmt.Println(bus, i)
}

func main() {
	var wg sync.WaitGroup
	defer wg.Wait()

	// バスエージェントの生成 3台
	for i := 0; i < 3; i++ {
		wg.Add(1)
		go bus(i, &wg)
	}

	i := 0

	for {

		time.Sleep(3 * time.Second)

		wg.Add(1)
		i++
		go person(i, &wg)
	}

}


package main

// C:\Users\ebata\goga\3-15

import (
	"fmt"
	"sync"
	"time"
)

// BroadCasterは管制システムのイメージに近い だから移動体のオブジェクトには含めない
type BroadCaster struct {
	cond *sync.Cond
	id   int64
	msg  string
}

func (bc *BroadCaster) Send(msg string) {
	bc.cond.L.Lock()
	defer bc.cond.L.Unlock()
	bc.id++
	bc.msg = msg
	bc.cond.Broadcast()
}

func (bc *BroadCaster) Recv(last int64) (int64, string) {
	bc.cond.L.Lock()
	defer bc.cond.L.Unlock()
	for bc.id == last {
		bc.cond.Wait()
	}
	return bc.id, bc.msg
}

// broadcaster_busをグローバルで実体化
var (
	broadcaster_bus = &BroadCaster{
		cond: sync.NewCond(&sync.Mutex{}),
	}
)

// broadcaster_personをグローバルで実体化
var (
	broadcaster_person = &BroadCaster{
		cond: sync.NewCond(&sync.Mutex{}),
	}
)

// 単一通信の構造体
type SingleCaster struct {
	ch   chan int   // 単一通信路
	lock sync.Mutex // 単一通信路のロック
}

// バス用単一通信の実体化
var (
	sc_bus = &SingleCaster{
		lock: sync.Mutex{},
		ch:   make(chan int),
	}
)

// 人間用単一通信の実体化
var (
	sc_person = &SingleCaster{
		lock: sync.Mutex{},
		ch:   make(chan int),
	}
)

// 人間用単一通信の実体化

type CONTROL struct {
	number int // 管制番号
}

func (control *CONTROL) control_start() {

	// バスへの一斉送信
	for i := 0; i < 2; i++ {
		time.Sleep(1 * time.Second)
		broadcaster_bus.Send(fmt.Sprintf("hello, bus world %d", i))
	}

	// 人間への一斉送信
	for i := 0; i < 2; i++ {
		time.Sleep(1 * time.Second)
		broadcaster_person.Send(fmt.Sprintf("hello, person world %d", i))
	}

	for {
		select {
		//		case v := <-c1:
		case v_b := <-sc_bus.ch:
			fmt.Println("catched from bus send", v_b)
		case v_p := <-sc_person.ch:
			fmt.Println("catched from person send", v_p)

		//default:
		//	fmt.Println("default")
		case <-time.After(3 * time.Second):

			return
		}
	}
}

type BUS struct {
	number int // バス車両番号
}

func (bus *BUS) bus_func_recv() {
	last := int64(0)
	for {
		id, msg := broadcaster_bus.Recv(last)
		last = id
		fmt.Println("broadcaset recv:", bus.number, msg)
	}
}

func (bus *BUS) bus_func_send() {
	// 送信専用
	fmt.Println("bus.number by send:", bus.number)

	sc_bus.lock.Lock()
	defer sc_bus.lock.Unlock()
	sc_bus.ch <- bus.number
}

type PERSON struct {
	number int  // 人間番号
	live   bool // 存在フラグ 存在:true 消滅:false
}

func (person *PERSON) person_func_recv() {
	last := int64(0)
	for {
		if person.live {
			return
		}

		id, msg := broadcaster_person.Recv(last)
		last = id
		fmt.Println("broadcaset recv:", person.number, msg)
	}
}

func (person *PERSON) person_func_send() {
	// 送信専用
	fmt.Println("person.number by send:", person.number)

	for {
		sc_person.lock.Lock()
		sc_person.ch <- person.number
		sc_person.lock.Unlock()
		time.Sleep(time.Second)

	}

}

func main() {

	// バス3台
	for i := 0; i < 3; i++ {
		bus := BUS{i}
		go bus.bus_func_send()
		go bus.bus_func_recv()
	}

	// 人間10人
	for i := 0; i < 10; i++ {
		person := PERSON{i, true}
		go person.person_func_send()
		go person.person_func_recv()
	}

	time.Sleep(time.Second)

	control := CONTROL{}
	go control.control_start()

	//close(c1)

	//wg.Wait()

	time.Sleep(10 * time.Second)
}


package main

// C:\Users\ebata\goga\3-17

import (
	"fmt"
	"sync"
	"time"
)

// BroadCasterは管制システムのイメージに近い だから移動体のオブジェクトには含めない
type BroadCaster struct {
	cond *sync.Cond
	id   int64
	msg  string
}

func (bc *BroadCaster) Send(msg string) {
	bc.cond.L.Lock()
	defer bc.cond.L.Unlock()
	bc.id++
	bc.msg = msg
	bc.cond.Broadcast()
}

func (bc *BroadCaster) Recv(last int64) (int64, string) {
	bc.cond.L.Lock()
	defer bc.cond.L.Unlock()
	for bc.id == last {
		bc.cond.Wait()
	}
	return bc.id, bc.msg
}

// broadcaster_busをグローバルで実体化
var (
	broadcaster_bus = &BroadCaster{
		cond: sync.NewCond(&sync.Mutex{}),
	}
)

// broadcaster_personをグローバルで実体化
var (
	broadcaster_person = &BroadCaster{
		cond: sync.NewCond(&sync.Mutex{}),
	}
)

// 単一通信の構造体
type SingleCaster struct {
	ch   chan int   // 単一通信路
	lock sync.Mutex // 単一通信路のロック
}

// バス用単一通信の実体化
var (
	sc_bus = &SingleCaster{
		lock: sync.Mutex{},
		ch:   make(chan int),
	}
)

// 人間用単一通信の実体化
var (
	sc_person = &SingleCaster{
		lock: sync.Mutex{},
		ch:   make(chan int),
	}
)

// 人間用単一通信の実体化

type CONTROL struct {
	number int // 管制番号
}

func control_init(wg *sync.WaitGroup) {
	defer wg.Done()

	// バスへの一斉送信
	for i := 0; i < 2; i++ {
		time.Sleep(1 * time.Second)
		broadcaster_bus.Send(fmt.Sprintf("hello, bus world %d", i))
	}

	// 人間への一斉送信
	for i := 0; i < 2; i++ {
		time.Sleep(1 * time.Second)
		broadcaster_person.Send(fmt.Sprintf("hello, person world %d", i))
	}

	for {
		select {
		//		case v := <-c1:
		case v_b := <-sc_bus.ch:
			fmt.Println("catched from bus send", v_b)
		case v_p := <-sc_person.ch:
			fmt.Println("catched from person send", v_p)

		//default:
		//	fmt.Println("default")
		case <-time.After(3 * time.Second):

			return
		}
	}
}

type BUS struct {
	number      int       // バス車両番号
	person_list []*PERSON // バスに乗っている人
}

func (bus *BUS) bus_func_recv() {
	last := int64(0)
	for {
		id, msg := broadcaster_bus.Recv(last)
		last = id
		fmt.Println("broadcaset recv:", bus.number, msg)
	}
}

func (bus *BUS) bus_func_send() {
	// 送信専用
	fmt.Println("bus.number by send:", bus.number)

	sc_bus.lock.Lock()
	defer sc_bus.lock.Unlock()
	sc_bus.ch <- bus.number
}

func (bus *BUS) add_person_list(person *PERSON) {
	bus.person_list = append(bus.person_list, person)
}

func (bus *BUS) del_person_list(number int) {
	for cnt := range bus.person_list {
		if number == bus.person_list[cnt].number {
			bus.person_list = append(bus.person_list[:number], bus.person_list[number+1:]...)
			return
		}
	}
}

type PERSON struct {
	number int  // 人間番号
	live   bool // 存在フラグ 存在:true 消滅:false
}

func (person *PERSON) person_func_recv() {
	last := int64(0)
	for {
		if person.live {
			return
		}

		id, msg := broadcaster_person.Recv(last)
		last = id
		fmt.Println("broadcaset recv:", person.number, msg)
	}
}

func (person *PERSON) person_func_send() {
	// 送信専用
	fmt.Println("person.number by send:", person.number)

	for {
		sc_person.lock.Lock()
		sc_person.ch <- person.number
		sc_person.lock.Unlock()
		time.Sleep(time.Second)

	}

}

func bus_init(wg *sync.WaitGroup, i int) {
	defer wg.Done()

	bus := BUS{number: i}
	go bus.bus_func_send()
	go bus.bus_func_recv()

}

func person_init(wg *sync.WaitGroup, i int) {
	defer wg.Done()

	person := PERSON{number: i}
	go person.person_func_send()
	go person.person_func_recv()
}

func main() {

	wg := sync.WaitGroup{}

	// バス3台
	for i := 0; i < 3; i++ {
		wg.Add(1)
		go bus_init(&wg, i)
	}

	// 人間10人
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go person_init(&wg, i)
	}

	time.Sleep(time.Second)

	// 管制センタ 1つ
	wg.Add(1)
	go control_init(&wg)

	//close(c1)

	//wg.Wait() //本来はこれだが、強制終了の為に
	time.Sleep(10 * time.Second)

}


2021/11,江端さんの技術メモ

うーん、もっとスマートな方法はないかなぁ

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("Start!")
	// boolの型でchannelを作成する
	ch1 := make(chan bool)
	ch2 := make(chan bool)
	ch3 := make(chan bool)

	// goroutineを生成して、サブスレッドで処理する

	go func() {
		time.Sleep(2 * time.Second)
		// chに対してtrueを投げる(送信)
		ch1 <- true
		ch2 <- true
		ch3 <- true
	}()

	go func() {
		fmt.Println("func2 start")
		<-ch1
		fmt.Println("func2 end")
	}()

	go func() {
		fmt.Println("func3 start")
		<-ch2
		fmt.Println("func3 end")
	}()

	//isFin := <-ch // <-chだけでもブロック出来る
	fmt.Println("before	time.Sleep(10 * time.Second)")
	time.Sleep(10 * time.Second)
	fmt.Println("after time.Sleep(10 * time.Second)")

	<-ch3

	// chをクローズする
	close(ch1)
	close(ch2)
	close(ch3)

	// 受信した値をprintする
	//fmt.Println(isFin)
	fmt.Println("Finish!")
}

2021/11,江端さんの技術メモ

国土交通省のPLATEAUのサンプルデータを試していますが、3Dデータの高さ方向が出せずにスタックしています。

できるだけ、勉強しないで、てっとり早く成果を出したいだけなんだけどなぁ。

上記の設定にしてみたら、なんかバベルの棟だったか塔だったか、みたいなものが出てきた。

なんか、色々弄っていましたが、

としたら、

のようなものがでてきたけど、多分、これは正解ではないので、また明日以降に挑戦しよう。

あ、ちなみに、QGISのバージョン上げました。

2021/10,江端さんの技術メモ

これが出題

嫁さんの答え

江端のアルゴリズムによる答え

直感的に、私のアルゴリズムが勝っていると思うんだが・・・。

30人を3台のバスで運行するDARPに拡張したバージョン

多分、そこそこ合っていると思うんだけどなー。DARPは正解が分からない(NP困難)問題だからなー。

以上

2021/10,江端さんの技術メモ

func totalDistance(sliceA []int, prt int) (dis float64, sliceB []int, max_Bus_Count []int) 

という関数を作ったのはいいが、これの呼び出しが上手くできずに、ここ数日作業が滞っていました。

結果としては、正解は以下の通り

var sliceZ  [100][]int // または、sliceZ := [100][]int{}
var totalDis [100]float64  // または、totalDis := [100]float64{}
max_Bus_Count := []int{} // または、var max_Bus_Count []int

totalDis[0], sliceZ[0], max_Bus_Count = totalDistance(sliceZ[0], 1)

であり、よく分からんのが、":="と "{}"のペアだが、多分、初期値を放り込めるようにしているものだろう(ここでは入れていないが)。

C言語で書くとこんな感じかと。

#include <stdio.h>

int main() {
int sliceZ[100][90];
double totalDis[100];
int max_Bus_Count[3];

int a = totalDistance(sliceZ[0], 1, totalDis[0], max_Bus_Count);
}

int totalDistance(int slizeZ, int *p, double totalDis, int max_Bus_Count) {
return 0;
}

こうやってみると、Goの配列宣言は、配列が動的に記載できる分、分かりにくいと思う。

なんで、C言語の宣言を踏襲してくれなかったかなーと思うのだが、

Array

サイズを指定して宣言するもの。実体的な値。メモリを参照するものではない。

a := [3]int64{1, 2, 3}

故に、

a := [3]int{1, 2, 3}
b := a

とすると、aとbが、別のメモリ領域に展開される

Slice

sliceはarrayへの参照を持つデータ構造

s1 := []int{1,2,3}  # ここで配列の数(例"3")を宣言しないのがミソ 
s2 := s1
s2[1] = 0

こっちは、s1とs2が同じ値になる。

append()で要素数を追加する

2021/10,江端さんの技術メモ

先程、突然、自宅から、全てのWebアクセスができなくなりました。自宅PCの再起動なども試みたのですが、復活しません。

ところが、会社のシステムに繋っているセキュアPC(SPC)に関しては、メールの送信ができました。で、SPCから、kobore.netのIPアドレスを入手して、自宅PCのコマンド画面からpingを打ってみました。

応答あり・・・ということは、DNSが動いていないだけだな、と判断して、取り敢えず、自宅PCのDNSを、強制的に、8.8.8.8 (googleが提供しているDNSサーバ(だったと思う))にしました。

よし。これで、このPCだけは使えるようになりました。
だが、我が家全体のネットワークが使えない状況は続いていますので、とりあえず家族に連絡。

さて、ここでホームルータ(Aterm ATERM-BA73A9 )の設定を見にいってみました。

やはりDNSの表示が出なくなっている。「最新状態に更新」を押しても改善なし。

こういう場面での「再起動」は、事態を悪化させることもあるので、(少なくとも8.8.8.8で動いてはいる)勇気がいるのですが、やってみました。

結果として、DNSが表示されるようになって、自宅ネットワークを再開することができました。

家族に連絡して、完了。

もはや、インターネットなしの生活(仕事、娯楽、その他)は考えられませんので、こういう場面に出会うと、私でも凄く怖いです。

以上

 

2021/10,江端さんの技術メモ

コロナによる死亡率の変動と介護費用のシミュレーション
Simulation of corona-induced mortality variation and cost of care

ダンウロードはここをクリック→第22回生命表_コロナ死亡率シミュレーション

 

2021/10,江端さんの技術メモ

「最短経路アルゴリズムを使って、近道を⾒つける」というのは、カーナビだけでなく、地理情報システム(GIS︓Geographic Information System)の定番ですが ―― 恐しく⾯倒くさいです。

そもそも、地図情報の座標⼊⼒なんぞ真⾯⽬にやっていたら、⼈⽣が終了してしまいます。といって、地図サービスプロバイダを使えば、権利や⽉額費⽤の他、使⽤できる範囲などの契約などでウンザリです。

仮に、それらをパスしたとしても、その膨⼤な地図情報のデータを使って、⾃⼒で、ダイクストラ法やら、ワーシャルフロイド法なんぞのアルゴリズムを実装していたら、⼈⽣が200年くらいあったとしても、⾜りないでしょう。

はっきり⾔いましょう。

―― 地理情報システム(GIS︓Geographic Information System)の⼿作りは⾯倒くさい

逆に⾔えば、簡単に⼿作りできれば、GISの研究やアプリ開発でラクができます。

本書は、「最短距離計算を⾏うダイクストラ法の使い⽅」をユースケースとして、『⼿作りGISの作り⽅と使い⽅』 を⼀通り説明するものです。