https://www.adobe.com/jp/acrobat/online/password-protect-pdf.html
円周内の一様乱数
エクセルのコラムはこんな感じ
θ: RAND()*2*3.141592654
r: SQRT(RAND())
X: +B3*COS(A3)
Y: +B3*SIN(A3)
Windows10でウインドウのサイズをマウスで変更できなくなった(端を握れなくなった)の対応をした件
Windows10 マウス ウインドウ サイズ 変更 端 握る
aviutl ではなく avidemux を試してみなさい > 私
映像の切り出しをするだけなら、aviutl(現在立ち上げ不調) ではなく avidemux を試してみなさい > 私
"Mouse without Borders"で、複数PCを1つのマウスとキーボードで使う
ホストのPCでは"No"を選択
"No"を押した後の情報をメモっておく
クライアントPCの方は"yes"を選択する。
ホストの方で示された情報を入力する。
うーん、ラクチン。
「Golangのファイルを分割して使いたい」の方法が上手く動かない
あが
の方法が上手く動かない。
$ tree
.
├── Agent
│ ├── cert.pem
│ ├── go.mod
│ ├── go.sum
│ ├── key.pem
│ └── main.go
├── join
│ ├── cert.pem
│ ├── join.exe
│ ├── join.go
│ └── key.pem
└── ldarp
└── libdarp.go
のAgent/main.go と、join/join.goの中で、ldap/libdarp.goを使いたいんだけど、
import (
"m/ldarp"
)
を、
import (
"m/../ldarp"
)
とか
import (
"m/./../ldarp"
)
とか試したみたんだけど、ダメ。
エラーコードに記載されているように、大人しく、
join.go:13:2: package m/ldarp is not in GOROOT (c:\go\src\m\ldarp)
のところに作れば動くんだろうけど、『負けたような気がする』ので、Agent/main.go と、join/join.goの中に、ldap/libdarp.goを埋めこむことで対応した。
ライブラリの二重管理になるけど、まあいいかな、と。
pgr_dijkstra()で、ダイクストラの順番を壊さずにルートの座標を得る方法(getDijkstraPath())
以前、pgr_dijkstra()で、ダイクストラの順番が壊れる という内容で悩んでいて、最終的に、
utsu_tram_db3=# SELECT seq, source, edge, x1, y1 FROM pgr_dijkstra('SELECT gid as id, source, target, cost, reverse_cost FROM ways', 2, 59, directed:=false) a INNER JOIN ways b ON (a.edge = b.gid) ORDER BY seq;
で、順列を壊さないで、ダイクストラの表示ができる、ということを書きました。
ところが、まだ、これでも問題が発生することが分かりました。
ノード1799からノード3342のルート計算を以下のようにやってみました。
kitaya_db=# SELECT seq, source, target, x1, y1,x2,y2, agg_cost FROM pgr_dijkstra('SELECT gid as id, source, target,
length_m as costcost, reverse_cost FROM ways', 3342, 1799, directed:=false) a INNER JOIN ways b ON (a.edge = b.gid) ORDER BY seq;
まあ、こんな感じで、sourceとx1,x2を追っていって、ラストのtargetとx2,y2を拾えば、いいと分かりましたので、これで大丈夫だろう、と思ってコーディングしていました。
ところが、このノード1799からノード3342を逆転させて、ノード3342からノード1799のルート計算を以下のようにやってみました。
kitaya_db=# SELECT seq, source, target, x1, y1,x2,y2, agg_cost FROM pgr_dijkstra('SELECT gid as id, source, target,
length_m as costcost, reverse_cost FROM ways', 1799, 3342, directed:=false) a INNER JOIN ways b ON (a.edge = b.gid) ORDER BY seq;
と、こんな感じで、sourceが出発点にならずに、targetの方が正しい並びとなってしまっています。つまり、こんな感じ。
で、これがどっちで出てくるのか分からないので、以下のようにしました。
(1)最初のノードがsourceに出てきたら、sourceベースで読み出し、
(2)最初のノードがtargetに出てきたら、targetベースで読み出す
実装はこんな感じにしました。
type LocInfo struct {
Lon float64
Lat float64
Source int
}
// 江端修正版 func getDijkstraPath(dbMap *sql.DB, locInfoStart, locInfoGoal ldarp.LocInfo) ([]ldarp.LocInfo, float64) { log.Println("getDijkstraPath", locInfoStart, locInfoGoal) var path []ldarp.LocInfo // 経路 (返り値の一つ目) var totalDistanceKm float64 rowsDijkstra, errDijkstra := dbMap.Query( "SELECT seq,source, target, x1, y1, x2, y2, agg_cost FROM pgr_dijkstra('SELECT gid as id, source, target, length_m as cost FROM ways', $1::bigint , $2::bigint , directed:=false) a INNER JOIN ways b ON (a.edge = b.gid) ORDER BY seq", locInfoStart.Source, locInfoGoal.Source) if errDijkstra != nil { log.Fatal(errDijkstra) } defer rowsDijkstra.Close() var agg_cost float64 isFirstCheck := true isSourceCheck := true for rowsDijkstra.Next() { var x1, y1, x2, y2 float64 var seq int var target int // まずnodeを読む if err := rowsDijkstra.Scan(&seq, &source, &target, &x1, &y1, &x2, &y2, &agg_cost); err != nil { fmt.Println(err) } // 最初の1回だけ入る if isFirstCheck { if source == locInfoStart.Source { isSourceCheck = true } else { isSourceCheck = false } isFirstCheck = false } var loc ldarp.LocInfo if isSourceCheck { loc.Source = source loc.Lon = x1 loc.Lat = y1 } else { loc.Source = target loc.Lon = x2 loc.Lat = y2 } loc.Source = target path = append(path, loc) } // ラストノードだけは手入力 path = append(path, locInfoGoal) totalDistanceKm = agg_cost / 1000.0 return path, totalDistanceKm }
もっとクールな方法があるかもしれませんが、面倒なので、戦うのはやめました。
バグを発見したので、main()を含めた再修正版をアップしておきまます。
package main
import (
"database/sql"
"fmt"
"log"
"m/src/ldarp"
_ "github.com/lib/pq"
)
func main() {
db, err := sql.Open("postgres",
"user=postgres password=password host=192.168.0.23 port=15432 dbname=tomioka_db_c sslmode=disable")
if err != nil {
log.Fatal("OpenError: ", err)
}
defer db.Close()
var a_Point, b_Point ldarp.LocInfo
a_Point.Source = 20
b_Point.Source = 1
path, dist := getDijkstraPath(db, a_Point, b_Point)
fmt.Println("path:", path)
fmt.Println("dist:", dist)
}
// 江端再修正版
func getDijkstraPath(dbMap *sql.DB, locInfoStart, locInfoGoal ldarp.LocInfo) ([]ldarp.LocInfo, float64) {
log.Println("getDijkstraPath", locInfoStart, locInfoGoal)
var path []ldarp.LocInfo // 経路 (返り値の一つ目)
var totalDistanceKm float64
rowsDijkstra, errDijkstra := dbMap.Query(
"SELECT seq,source, target, x1, y1, x2, y2, agg_cost FROM pgr_dijkstra('SELECT gid as id, source, target, length_m as cost cost, reverse_cost FROM ways', $1::bigint , $2::bigint , directed:=false) a INNER JOIN ways b ON (a.edge = b.gid) ORDER BY seq",
locInfoStart.Source,
locInfoGoal.Source)
if errDijkstra != nil {
log.Fatal(errDijkstra)
}
defer rowsDijkstra.Close()
var agg_cost float64
var loc ldarp.LocInfo
var x1, y1, x2, y2 float64
var seq int
var target int
var source int
isFirstCheck := true
isSourceCheck := true
for rowsDijkstra.Next() {
// まずnodeを読む
if err := rowsDijkstra.Scan(&seq, &source, &target, &x1, &y1, &x2, &y2, &agg_cost); err != nil {
fmt.Println(err)
}
// 最初の1回だけチェックのために入る これについては、https://wp.kobore.net/江端さんの技術メモ/post-7668/を参照のこと
// もし rowsDijkstra.Scanで最初のsource値を読みとり、locInfoStart.Source の値と同じであれば、x1,y1をベースとして、異なる値であれば、x2,y2をベースとする
if isFirstCheck {
if source == locInfoStart.Source {
isSourceCheck = true // x1, y1をベースとする処理になる
} else {
isSourceCheck = false // x2,y2をベースとする処理になる
}
isFirstCheck = false // 最初の1回をチェックすることで、2回目はこのループには入らなくなる
}
//var loc ldarp.LocInfo
if isSourceCheck { // x1, y1をベースとする処理
loc.Source = source
loc.Lon = x1
loc.Lat = y1
} else { // x2,y2をベースとする処理
loc.Source = target
loc.Lon = x2
loc.Lat = y2
}
path = append(path, loc)
}
// ラストノードだけは手入力 (ここは引っくり返す)
if isSourceCheck { // x1, y1をベースとする処理
loc.Source = target
loc.Lon = x2
loc.Lat = y2
} else { // x2,y2をベースとする処理
loc.Source = source
loc.Lon = x1
loc.Lat = y1
}
path = append(path, loc)
totalDistanceKm = agg_cost / 1000.0
return path, totalDistanceKm
}
で、色々問題が出てきたので、各種ケースに対応できるように追加したもの
/*
c:\users\ebata\tomioka3b\src\others\main49.go
このプログラムは、PostgreSQLデータベース内の地理情報を使用して最短経路を計算するためのものです。
このプログラムは、以下の機能を持ちます。
(1)main 関数内で、PostgreSQLデータベースへの接続情報を設定し、sql.Open を使用してデータベースに接続します。
(2)getDijkstraPath 関数は、指定された始点から終点までの最短経路を計算するための関数です。この関数は、Dijkstraアルゴリズムを使用して最短経路を計算します。
(3)LocInfo 構造体は、地理座標とノードの情報を表現します。
(4)main 関数内で getDijkstraPath 関数を呼び出し、最短経路とその距離を計算します。異常ノードや隣接ノード、同一ノード、2つ離れたノードなど、さまざまなケースでの最短経路をテストするために、複数の呼び出しをコメントアウトしています。
(5)getDijkstraPath 関数内では、まず指定された始点と終点に対応する地理座標を取得します。始点と終点が同一の場合は、指定されたノードの地理座標を取得します。
(6)次に、pgr_dijkstra 関数を使用して最短経路を計算し、結果を取得します。結果は、各ノードの地理座標と距離が含まれる配列として返されます。
(7)最後に、最短経路の全体距離を計算し、その結果を返します。
*/
package main
import (
"database/sql"
"fmt"
"log"
"os"
_ "github.com/lib/pq"
)
type LocInfo struct {
Lon float64
Lat float64
Source int
}
func main() {
// PostgreSQLへの接続情報
// Agent_od書き込み用テーブルの初期化
db_agent_od, err := sql.Open("postgres",
"user=postgres password=password host=192.168.0.23 port=15432 dbname=tomioka_db_e sslmode=disable") // トミオカート地図でテスト
if err != nil {
log.Fatal("OpenError: ", err)
}
defer db_agent_od.Close()
route, dis := getDijkstraPath(db_agent_od, LocInfo{Source: 432}, LocInfo{Source: 1070}) // 異常ノード
//route, dis := getDijkstraPath(db_agent_od, LocInfo{Source: 856}, LocInfo{Source: 688}) // 異常ノード
//route, dis := getDijkstraPath(db_agent_od, LocInfo{Source: 723}, LocInfo{Source: 853}) // 隣接ノード
//route, dis := getDijkstraPath(db_agent_od, LocInfo{Source: 536}, LocInfo{Source: 171}) // 隣接ノード
//route, dis := getDijkstraPath(db_agent_od, LocInfo{Source: 536}, LocInfo{Source: 536}) // 同一ノード
//route, dis := getDijkstraPath(db_agent_od, LocInfo{Source: 138}, LocInfo{Source: 139}) // 同一ノード
//route, dis := getDijkstraPath(db_agent_od, LocInfo{Source: 173}, LocInfo{Source: 853}) // 2つ離れたノード
fmt.Println("route", route, "dis", dis)
}
// テスト中
// 1行のみの場合、ヌルになるという問題と、同一ノードに対応するため
func getDijkstraPath(dbMap *sql.DB, locInfoStart, locInfoGoal LocInfo) ([]LocInfo, float64) {
var path []LocInfo // 経路 (返り値の一つ目)
var totalDistanceKm float64
// 例外処理 locInfoStart.source == locInfoGoal.source の場合
if locInfoStart.Source == locInfoGoal.Source {
source := locInfoStart.Source
// SQLクエリの作成
query := fmt.Sprintf(`
SELECT x1, y1
FROM ways
WHERE source = %d;
`, source)
// SQLクエリの実行
var x1, y1 float64
err := dbMap.QueryRow(query).Scan(&x1, &y1)
if err != nil {
log.Fatal(err)
}
var loc LocInfo
loc.Source = source
loc.Lon = x1
loc.Lat = y1
path = append(path, loc)
totalDistanceKm = 0.0
return path, totalDistanceKm
}
query := `
SELECT seq, source, target, x1, y1, x2, y2, agg_cost
FROM pgr_dijkstra(
'SELECT gid as id, source, target, length_m as cost FROM ways',
$1::bigint,
$2::bigint,
directed:=false
) a
INNER JOIN ways b ON (a.edge = b.gid)
ORDER BY seq
`
//log.Println("getDijkstraPath", locInfoStart.Source, locInfoGoal.Source)
rowsDijkstra, errDijkstra := dbMap.Query(query, locInfoStart.Source, locInfoGoal.Source)
if errDijkstra != nil {
log.Fatal(errDijkstra)
os.Exit(1)
}
defer rowsDijkstra.Close()
var agg_cost float64
var loc LocInfo
var x1, y1, x2, y2 float64
var seq int
var target int
var source int
isFirstCheck := true
isSourceCheck := true
count := 0
for rowsDijkstra.Next() {
// まずnodeを読む
if err := rowsDijkstra.Scan(&seq, &source, &target, &x1, &y1, &x2, &y2, &agg_cost); err != nil {
fmt.Println(err)
}
// 最初の1回だけチェックのために入る これについては、https://wp.kobore.net/江端さんの技術メモ/post-7668/を参照のこと
// もし rowsDijkstra.Scanで最初のsource値を読みとり、locInfoStart.Source の値と同じであれば、x1,y1をベースとして、異なる値であれば、x2,y2をベースとする
if isFirstCheck {
if source == locInfoStart.Source {
isSourceCheck = true // x1, y1をベースとする処理になる
} else {
isSourceCheck = false // x2,y2をベースとする処理になる
}
isFirstCheck = false // 最初の1回をチェックすることで、2回目はこのループには入らなくなる
}
//var loc LocInfo
if isSourceCheck { // x1, y1をベースとする処理
loc.Source = source
loc.Lon = x1
loc.Lat = y1
} else { // x2,y2をベースとする処理
loc.Source = target
loc.Lon = x2
loc.Lat = y2
}
path = append(path, loc)
count++
}
// ラストノードだけは手入力 (ここは引っくり返す)
if isSourceCheck { // x1, y1をベースとする処理
loc.Source = target
loc.Lon = x2
loc.Lat = y2
} else { // x2,y2をベースとする処理
loc.Source = source
loc.Lon = x1
loc.Lat = y1
}
fmt.Println("count", count)
if count == 0 { // 1行のみの場合、ヌルになるという問題に対応するため、
loc.Source = locInfoGoal.Source
loc.Lon = locInfoGoal.Lon
loc.Lat = locInfoGoal.Lat
// 入力値の指定
source := locInfoStart.Source
target := locInfoGoal.Source
// SQLクエリの作成
query := fmt.Sprintf(`
SELECT length_m, x1, y1, x2, y2
FROM ways
WHERE source = %d AND target = %d;
`, source, target)
// SQLクエリの実行
var length float64
var x1, y1, x2, y2 float64
err := dbMap.QueryRow(query).Scan(&length, &x1, &y1, &x2, &y2)
if err != nil {
log.Println("First attempt failed. Retrying with swapped source and target.")
// 入れ替えたsourceとtargetの値でクエリを再実行
query = fmt.Sprintf(`
SELECT length_m, x1, y1, x2, y2
FROM ways
WHERE source = %d AND target = %d;
`, target, source)
err = dbMap.QueryRow(query).Scan(&length, &x1, &y1, &x2, &y2)
if err != nil {
log.Fatal(err)
}
}
// 結果の出力
fmt.Printf("length_m: %f\n", length)
fmt.Printf("source: %d\n", source)
fmt.Printf("target: %d\n", target)
fmt.Printf("x1: %f\n", x1)
fmt.Printf("y1: %f\n", y1)
fmt.Printf("x2: %f\n", x2)
fmt.Printf("y2: %f\n", y2)
if source == locInfoGoal.Source {
loc.Lon = x1
loc.Lat = y1
} else {
loc.Lon = x2
loc.Lat = y2
}
agg_cost = length
fmt.Println("loc", loc)
}
path = append(path, loc)
totalDistanceKm = agg_cost / 1000.0
return path, totalDistanceKm
}
神の啓示を描いてみた件
パワポで、バックグランド黒、白い線を複数コピペを繰り返す
SAIで、エラブラシで発光を付ける
線をぼかして、完成
信者獲得&洗脳シミュレーションプログラム
信者獲得&洗脳シミュレーションプログラム
package main
import (
"fmt"
"math/rand"
)
type person struct {
number int // 番号
mental_strength float64 // 勧誘に屈しない強さ
religious_devotion float64 // 信仰力
church int //教会フラグ
}
var p_array []*person // personの配列2
var (
p_num = 0
)
func person_create() *person {
p := new(person)
p.number = p_num
p_num++ // 生成された順番に番号を付けていく
p.mental_strength = rand.Float64() // 勧誘を断わる強さ
p.religious_devotion = 0 // 信仰力最初は"0"
p.church = 0 // 教会フラグ
p_array = append(p_array, p) // 配列に放り込む
return p
}
func (p *person) person_destroy() {
for index, v := range p_array {
if v == p {
p_array = append(p_array[:index], p_array[index+1:]...)
break
}
}
p = nil //これでいいのかな? ガーベージコレクションが消してくれる、と聞いているが
}
type agent struct {
number int // 番号
invitation_power float64 // 勧誘力
}
var a_array []*agent // agentの配列
var (
a_num = 0
)
func agent_create() *agent {
a := new(agent)
a.number = a_num
a_num++ // 生成された順番に番号を付けていく
a.invitation_power = 0.3 + 0.7*rand.Float64() // 勧誘力
a_array = append(a_array, a) // 配列に放り込む
return a
}
func (a *agent) agent_destroy() {
for index, v := range a_array {
if v == a {
a_array = append(a_array[:index], a_array[index+1:]...)
break
}
}
a = nil //これでいいのかな? ガーベージコレクションが消してくれる、と聞いているが
}
func (p *person) meet_agent(a *agent) {
if p.mental_strength < a.invitation_power {
p.religious_devotion += a.invitation_power * 0.1 // エージェントの説得によって信仰心が微増
p.mental_strength -= a.invitation_power * 0.1 // エージェントの説得によって心理障壁が微減
if p.religious_devotion > 1.0 {
p.religious_devotion = 1.0
}
if p.mental_strength < 0.0 {
p.mental_strength = 0.0
}
}
}
func main() {
for i := 0; i < 1000; i++ {
person_create()
}
fmt.Println("======p_array=========")
for _, p := range p_array {
fmt.Println(p.number, ",", p.mental_strength, ",", p.religious_devotion)
}
for i := 0; i < 5; i++ {
agent_create()
}
fmt.Println("======a_array=========")
for _, a := range a_array {
fmt.Println(a.number, ",", a.invitation_power)
}
for i := 0; i < 365; i++ { // 1年間の勧誘
for _, p := range p_array {
//fmt.Println(index, ":", v, v.number, v.mental_strength)
for _, a := range a_array {
if rand.Float64() < 0.001 {
p.meet_agent(a)
}
}
}
}
fmt.Println("=====p_array after 365days==========")
for _, p := range p_array {
fmt.Println(p.number, ",", p.mental_strength, ",", p.religious_devotion)
}
fmt.Println("====count2===========")
count := 0
for _, p := range p_array {
if p.religious_devotion > 0.2 {
p.church = 1 //教会フラグを"1"に変項
count++
fmt.Println(p.religious_devotion)
}
}
fmt.Println(count)
for i := 0; i < 365; i++ { // 2年目の勧誘
for _, p := range p_array {
//fmt.Println(index, ":", v, v.number, v.mental_strength)
for _, a := range a_array {
if p.church == 1 && rand.Float64() < 0.005 {
p.meet_agent(a)
}
}
}
}
fmt.Println("=====p_array after 365days x 2==========")
for _, p := range p_array {
if p.church == 1 {
fmt.Println(p.number, ",", p.mental_strength, ",", p.religious_devotion)
}
}
}
出力結果(エクセルファイル) → cult.xlsx
エージェントをオブジェクト風に作って、配列にいれて、終了したら、エージェントを消滅する。
Go言語でエージェントシミュレータを作るのに必要なパーツを作っています。
エージェントをオブジェクト風に作って、配列にいれて、終了したら、エージェントを消滅する。
package main
import (
"fmt"
"math/rand"
)
type person struct {
number int // 番号
mental_strength float64 // 勧誘に屈しない強さ
}
var p_array []*person // personの配列
func person_create(num int) *person {
p := new(person)
p.number = num
p.mental_strength = rand.Float64() // 勧誘を断わる強さ
p_array = append(p_array, p) // 配列に放り込む
return p
}
func (p *person) person_destroy() {
for index, v := range p_array {
if v == p {
fmt.Println("hit")
p_array = append(p_array[:index], p_array[index+1:]...)
break
}
}
p = nil //これでいいのかな?
}
func main() {
_ = person_create(0)
p1 := person_create(1)
p2 := person_create(2)
_ = person_create(3)
for index, v := range p_array {
fmt.Println(index, ":", v, v.number, v.mental_strength)
}
p2.person_destroy()
for index, v := range p_array {
fmt.Println(index, ":", v, v.number, v.mental_strength)
}
p1.person_destroy()
for index, v := range p_array {
fmt.Println(index, ":", v, v.number, v.mental_strength)
}
}
■出力結果
PS C:\Users\ebata\cult> go run main.go
0 : &{0 0.6046602879796196} 0 0.6046602879796196
1 : &{1 0.9405090880450124} 1 0.9405090880450124
2 : &{2 0.6645600532184904} 2 0.6645600532184904
3 : &{3 0.4377141871869802} 3 0.4377141871869802
hit
0 : &{0 0.6046602879796196} 0 0.6046602879796196
1 : &{1 0.9405090880450124} 1 0.9405090880450124
2 : &{3 0.4377141871869802} 3 0.4377141871869802
hit
0 : &{0 0.6046602879796196} 0 0.6046602879796196
1 : &{3 0.4377141871869802} 3 0.4377141871869802