2024,江端さんの忘備録

今回の地震の第1報で、私の中に最初に出てきた記憶が「スキップとローファー」でした。

The first memory that came to my mind at the first report of this earthquake was "Skips and Loafers."

今回の被災地には、私の親戚も思い当たる友人もいないのですが、それと同等、あるいはそれ以上に、コミックの登場人物を現在被災している方々に重ねて、思いを馳せる ――

I have no relatives or friends in the disaster area; however, I come to overlap the characters in the comic and the people who are currently suffering from the disaster.

これは、不謹慎なことではないと、私は思う(そう信じる)。

This is not inappropriate, I think (and believe).

『自分が何をしなければならないか、ようやく気がついた時、それは、非常に小さくて基本的なものであった』

2024,江端さんの忘備録

世界的に有名なアルゴリズムの改良版を考えていました。

Last night, I contemplated an improved version of the world-famous algorithm, which I believe is the most popular and effective.

しかし、先行研究を調べても、私の考えと同じん内容の論文が出てこなくて、不思議に思っていました。

However, I wondered why I could not find any papers describing the same ideas as mine when I checked the previous studies.

―― もしかして、私が世界初?

"Perhaps I am the first in the world?"

もしそうなら、『これで、1本(の論文)稼げた!』てなことを考えていました。

If so, "Now I've earned one (thesis)!" I thought to myself.

-----

まいったなぁ。

Oh, man.

これから、『江端法』なんて名前が付くアルゴリズムが世界で使われるようになるのかなぁ。

I wonder if algorithms with names like the "Ebata Method" will be used.

自己紹介の時に、「あの『江端法』の江端です」なんて、言わなくちゃならないのかなぁ。

I wonder if I have to say, "I am Ebata of that 'Ebata Method'" when I introduce myself.

偉そうに聞こえないように、言い方をちょっと工夫しなければ。

I have to be a little creative in how I say it so that I don't sound like a pompous ass.

などと考えながら、コーディングをしていたのですが、

I was coding, thinking about things such as the above.

『あれ? コスト値が状態に対して変動的であったとしても、従来法がそのまま適用できるんじゃないか?』

'Huh? Even if cost values were variable for the state, wouldn't the conventional method still apply?'

と気がついたのは、朝の5時でした。

I realized that it was 5:00 in the morning.

-----

1時間を稼ぐのに、ゼーゼー言っている最中に、この「頭脳をフル回転させながら、失なった無意味な数時間」は ――

While heaving to earn an hour, these "meaningless hours lost while racking your brains at full speed"--

死ぬほど痛い。

Hurts to death for me.

 

時間のない中での、こういう一日は ―― 本当に痛い。

 

2024,江端さんの技術メモ

運行情報(ダイヤグラム)を反映した最短時間で到着する計算方法は、通常のダイクストラ法を拡張して実行することができます。以下は、ダイヤ情報を考慮する最短到着時間を計算する一般的なアプローチです:

  1. グラフの作成:
    • ダイヤグラムに基づいて、駅間の接続を表すグラフを作成します。各エッジ(駅間の接続)には、所要時間が含まれます。
    • グラフのノードは駅を表し、エッジの重みは駅間の移動にかかる時間です。
    • 通常のダイクストラ法と同様に、出発駅を始点としてグラフを探索します。
  2. ノードの拡張と更新:
    • 通常のダイクストラ法と同様に、出発駅から各駅への最短到着時間を記録するデータ構造を使用します。初期状態では、出発駅の最短到着時間を0に設定し、他の駅は無限大(無効値)とします。
    • プライオリティキューを使用して、最短到着時間が最小の駅を選択します。
  3. ダイヤ情報の適用:
    • 選択した駅から出発するエッジを調べ、ダイヤ情報を考慮して最短到着時間を計算します。
    • ダイヤ情報には、駅への到着時間や運行間隔などが含まれます。現在の到着時間とダイヤ情報を使用して、次の駅への最短到着時間を計算します。
    • 新しい到着時間が現在の最短到着時間よりも短い場合、その駅の最短到着時間を更新します。
  4. プライオリティキューから次の最短到着時間の駅を選択し、ステップ3を繰り返します。目的の駅に到達した場合、計算を終了します。
  5. 最短到着時間を使用して、目的の駅への最短経路を復元します。

このアプローチを使用すると、ダイヤ情報を反映した最短到着時間を計算できます。ダイヤ情報は、駅への到着時間や運行間隔を正確に取得し、計算に組み込む必要があります。また、プライオリティキューの実装や適切なデータ構造の設計も重要です。

2024,江端さんの技術メモ

/* 
   簡易バスダイヤ作成プログラム    c:\users\ebata\dummy1.go

   (1)バス路線があり、5つの停留所("A0", "A1", "A2", "A3", "A4", "A5")があります。
   (2)このバスは始点から運行を開始し、路線の終点でで一定時間停車した後、再び逆方向に運行を開始します。
   (3)バスは朝6時に出発して、5分単位で次の停留所で停止し、終端で10分間停止します。
   (4)これを3往復するものとします。

*/



package main

import (
	"fmt"
	"strings" // strings パッケージをインポート
	"time"
)

// バスのダイヤグラム
type BusSchedule struct {
	Route             []string             // 停留所のリスト
	DepartureTime     time.Time            // 出発時刻
	ArrivalTimeStops  map[string][]string // 各停留所の到着時刻
	ArrivalTimeRounds int                  // 往復回数
}

// バスのダイヤグラムを生成する関数
func GenerateBusSchedule(route []string, departureTime time.Time, numRoundTrips int) *BusSchedule {
	schedule := &BusSchedule{
		Route:             route,
		DepartureTime:     departureTime,
		ArrivalTimeStops:  make(map[string][]string),
		ArrivalTimeRounds: numRoundTrips,
	}

	currentTime := departureTime
	reverse := false // 逆向き運行を切り替えるフラグ

	for round := 0; round < numRoundTrips; round++ {
		routeOrder := make([]string, 0, len(route)*2-1)

		if reverse {
			// 逆向き運行の場合、終点から始点に戻る
			for i := len(route) - 1; i >= 0; i-- {
				stop := route[i]
				arrivalTime := currentTime.Format("15:04")
				schedule.ArrivalTimeStops[stop] = append(schedule.ArrivalTimeStops[stop], arrivalTime)
				routeOrder = append(routeOrder, fmt.Sprintf("%s(%d): %s", stop, len(schedule.ArrivalTimeStops[stop]), arrivalTime))
				if i > 0 {
					currentTime = currentTime.Add(5 * time.Minute)
				}
			}
			reverse = false
		} else {
			// 正向き運行の場合、始点から終点に向かう
			for i := 0; i < len(route); i++ {
				stop := route[i]
				arrivalTime := currentTime.Format("15:04")
				schedule.ArrivalTimeStops[stop] = append(schedule.ArrivalTimeStops[stop], arrivalTime)
				routeOrder = append(routeOrder, fmt.Sprintf("%s(%d): %s", stop, len(schedule.ArrivalTimeStops[stop]), arrivalTime))
				if i < len(route)-1 {
					currentTime = currentTime.Add(5 * time.Minute)
				}
			}
			reverse = true
		}

		fmt.Println(strings.Join(routeOrder, "->"))
		currentTime = currentTime.Add(10 * time.Minute) // 終点での停止時間
	}

	return schedule
}

func main() {
	route := []string{"A0", "A1", "A2", "A3", "A4", "A5"}
	departureTime := time.Date(2024, 1, 6, 6, 0, 0, 0, time.UTC)
	numRoundTrips := 3

	schedule := GenerateBusSchedule(route, departureTime, numRoundTrips)

	// routeOrder を表示
	fmt.Println("routeOrder:")
	for _, stop := range schedule.Route {
		fmt.Printf("%s:\n", stop)
		for i, arrivalTime := range schedule.ArrivalTimeStops[stop] {
			fmt.Printf("  通過%d: %s\n", i+1, arrivalTime)
		}
	}
}

出力結果

C:\Users\ebata>go run dummy1.go
A0(1): 06:00->A1(1): 06:05->A2(1): 06:10->A3(1): 06:15->A4(1): 06:20->A5(1): 06:25
A5(2): 06:35->A4(2): 06:40->A3(2): 06:45->A2(2): 06:50->A1(2): 06:55->A0(2): 07:00
A0(3): 07:10->A1(3): 07:15->A2(3): 07:20->A3(3): 07:25->A4(3): 07:30->A5(3): 07:35
routeOrder:
A0:
通過1: 06:00
通過2: 07:00
通過3: 07:10
A1:
通過1: 06:05
通過2: 06:55
通過3: 07:15
A2:
通過1: 06:10
通過2: 06:50
通過3: 07:20
A3:
通過1: 06:15
通過2: 06:45
通過3: 07:25
A4:
通過1: 06:20
通過2: 06:40
通過3: 07:30
A5:
通過1: 06:25
通過2: 06:35
通過3: 07:35

2024,江端さんの忘備録

NHKの『平安時代サミット2024 本当に「平安」だったのか』を見ました。

I watched NHK's "Heian Period Summit 2024: Was it really "Heian"?

いわゆる、今年の大河ドラマの番宣番組ですが、面白かったです。

It's a so-called "promotion program" for this year's history drama, but it was interesting.

今回は3つほど頂きました。

This time, I received three of them.

-----

(1)『平安時代の呪詛と、現代のSNSは同じである』

(1) "Curses in the Heian period and social networking sites today are the same."

至言だよなぁ、と思いました。

I thought, "That's a supreme word.

SNSの誹謗中傷は物理的な攻撃ではないのに、人を殺す力があります。

Social networking slander is not a physical attack, yet it has the power to kill.

これを「呪詛」と言わずに、何と言いましょうか。

What shall we call this without calling it a curse?

やはり、SNSなんぞには手を出さないのが良いのです。

After all, it is better to stay away from social networking sites.

(2)『光源氏が"クズ"なのは、もう共通認識ですよね』

(2) "It is already common knowledge that Hikaru Genji is a scumbag.

うん、もう、これはもう、議論の余地なく、奴はクズです。

Yeah, now, this is no longer debatable, the guy is a scumbag.

源氏物語

(3)『"光源氏"を"推し"と置き換えると、その存在を認めることができます』

(3) "If you replace "Hikaru Genji" with "fave", we can recognize its existence.

私、この"推し"は知っているのですが、上記のフレーズの意味が分からなくて、嫁さんに尋ねました。

I know this "fave," but I don't know what the above phrase means, so I asked my wife.

私:「これは、自分の応援している"推し"のアイドルであるなら、クズでも構わんということ?」

Me: "Does this mean you don't care if he's a bum as long as he's your "fave" that you support?"

嫁さん:「そういうこと。"推し"とは、何をしても許される存在のことだから」

Wife: "Right." A "fave" is someone who is allowed to do whatever he wants."

やっぱり私には良く分かりませんでしたが、『"推し"って怖いものなんだなぁ』ということだけは分かりました。

I still didn't understand it well, but I did understand that "fave" is scary.

-----

私が、今でも疑問に思っていることは、

I am still wondering about the question,

『なんで源氏物語は、検閲、発行禁止を免れたのだろう?』

Why did The Tale of Genji escape censorship and a publication ban?"

ということです。

だって、あの話、皇室への不敬のオンパレードですよ。

Because that story is a parade of disrespect to the imperial family.

当時、不敬罪があったかどうかは知りませんが、基本的に皇族に対する不敬が許される時代だったとは思えません。

I don't know if there was a crime of disrespect at the time, but I don't think it was when disrespect for the royal family was tolerated.

帝(桐壺帝)の妻(藤壺)を妊娠させておいて、この子の後見人になるなんて ―― どんな"托卵"だよ!と突っ込みたくなります。

How could he get the wife (Fujitsubo) of the emperor (Kiritsubo) pregnant and then become the child's guardian? I am tempted to say, "What kind of "mendicancy" is this?

-----

さらに、私が、本当に訳が分からんのが、一条天皇が「源氏物語の愛読者」だった、という点です。

Furthermore, I don't understand that Emperor Ichijo was a "lover of the Tale of Genji."

(一条天皇と藤原氏の関係は、説明が面倒なので割愛(ググって下さい))。

(The explanation of the relationship between Emperor Ichijo and the Fujiwara clan will be cut (please Google)).

フィクションとはいえ、自分の家系が、最大級の侮辱を受けている、とは思わなったのでしょうか。

Even though it was fiction, did Emperor Ichijo ever think that his family lineage was being insulted in the greatest possible way?

私、このあたりがどうしても良く分からないので、「源氏物語文学」に詳しい方に解説頂ければ、嬉しいです。

I am unsure I understand this part very well, so I would be glad if someone familiar with "Tale of Genji Literature" could explain it.

-----

ちなみに、上記の私の疑問に応える一つの解釈はあります。

By the way, there is one interpretation that answers my question above. That means,

―― 源氏物語は、あの時代における、異世界ファンタジーであった

"The Tale of Genji was an otherworldly fantasy of its time."

ということです。

または、実世界(α世界線)に類似した、別の世界(β世界線)だった、という、平行世界線解釈です。

Or, it is a parallel worldline interpretation that the real world (alpha worldline) was similar to another world (beta worldline).

ここに、私は、

Here, I would like to propose a new interpretation of

『源氏物語 ≒ シュタインズゲート』

"The Tale of Genji ≒ Steins;Gate."

という、新解釈を提唱したいと思います。

未分類

ノード間のコストが与えられているダイクストラ計算を行うノードのそれぞれに数値が設定されていて、ノードが持っている数値より小さい数値のノードとは繋がることができない、というアルゴリズムをGo言語で作成する

main2.goで、ノードのコストが分からない場合でも対応できるように改良したもの。

package main

import (
	"fmt"
	"math"
)

type Node struct {
	Name  string
	Value float64 // 各ノードに設定された数値 (負数の場合、この数値を無視する)
}

type Edge struct {
	From   *Node
	To     *Node
	Weight float64
}

func main() {
	/*
		// ノードとエッジを初期化
		nodeA := &Node{Name: "A", Value: 5}
		nodeB := &Node{Name: "B", Value: 8}
		nodeC := &Node{Name: "C", Value: 6}
		nodeD := &Node{Name: "D", Value: 2}
		nodeE := &Node{Name: "E", Value: 4}
	*/

	// ノードとエッジを初期化
	nodeA := &Node{Name: "A", Value: 3}
	nodeB := &Node{Name: "B", Value: -1} // 負数の場合無視
	nodeC := &Node{Name: "C", Value: -1} // 負数の場合無視
	nodeD := &Node{Name: "D", Value: 2}
	nodeE := &Node{Name: "E", Value: -1} // 負数の場合無視
	nodeF := &Node{Name: "F", Value: -1} // 負数の場合無視
	nodeG := &Node{Name: "G", Value: 1}

	/*
		edges := []Edge{
			{nodeA, nodeB, 2},
			{nodeA, nodeC, 4},
			{nodeB, nodeC, 1},
			{nodeB, nodeD, 7},
			{nodeC, nodeD, 3},
			{nodeC, nodeE, 5},
			{nodeE, nodeD, 2},
		}
	*/

	edges := []Edge{ // A,B,C,D,E,Fの順で双方向をしてい
		{nodeA, nodeB, 1},
		{nodeB, nodeA, 1},

		{nodeB, nodeC, 1},
		{nodeC, nodeB, 1},

		{nodeC, nodeD, 1},
		{nodeD, nodeC, 1},

		{nodeD, nodeE, 1},
		{nodeE, nodeD, 1},

		{nodeE, nodeF, 1},
		{nodeF, nodeE, 1},

		{nodeF, nodeG, 1},
		{nodeG, nodeF, 1},
	}

	startNode := nodeG
	targetNode := nodeA

	// ダイクストラアルゴリズムを実行
	shortestPath, totalWeight := dijkstra(startNode, targetNode, edges)

	if shortestPath == nil {
		fmt.Println("最短経路が見つかりませんでした。")
	} else {
		fmt.Printf("最短経路: %v\n", getNodeNames(shortestPath))
		fmt.Printf("最短経路の総重み: %.2f\n", totalWeight)
	}

	fmt.Println(nodeA.Value)
	fmt.Println(nodeB.Value)
	fmt.Println(nodeC.Value)
	fmt.Println(nodeD.Value)
	fmt.Println(nodeE.Value)
	fmt.Println(nodeF.Value)
	fmt.Println(nodeG.Value)

}

func dijkstra(startNode, targetNode *Node, edges []Edge) ([]*Node, float64) {
	// ノード間の最短距離を格納するマップを初期化
	shortestDistances := make(map[*Node]float64)
	// 各ノードの前のノードを格納するマップを初期化
	predecessors := make(map[*Node]*Node)

	// 最短距離を無限大で初期化し、開始ノードの最短距離を0に設定
	for _, edge := range edges {
		shortestDistances[edge.From] = math.Inf(1)
		shortestDistances[edge.To] = math.Inf(1)
	}
	shortestDistances[startNode] = 0

	// 訪問済みのノードを格納するセットを初期化
	visitedNodes := make(map[*Node]bool)

	// まだ訪問していないノードが残っている間ループ
	for len(visitedNodes) < len(shortestDistances) {
		// 未訪問のノードの中から最短距離のノードを選択
		currentNode := getClosestUnvisitedNode(shortestDistances, visitedNodes)

		// ノードがない場合やターゲットノードに到達した場合は終了
		if currentNode == nil || currentNode == targetNode {
			break
		}

		for _, edge := range edges {
			if edge.From == currentNode {
				if edge.To.Value < 0 { // -1などの負数が入っていたら、更新してしまう
					edge.To.Value = currentNode.Value // 下のif文を通す為の手続(書き換えても大丈夫かな(今のところ大丈夫そうだけど))
				}
				if edge.To.Value >= currentNode.Value { //
					distance := shortestDistances[currentNode] + edge.Weight
					if distance < shortestDistances[edge.To] {
						shortestDistances[edge.To] = distance
						predecessors[edge.To] = currentNode
					}
				}
			}
		}

		// このノードを訪問済みとしてマーク
		visitedNodes[currentNode] = true
	}

	// 最短経路を復元
	shortestPath := make([]*Node, 0)
	currentNode := targetNode
	for currentNode != nil {
		shortestPath = append([]*Node{currentNode}, shortestPath...)
		currentNode = predecessors[currentNode]
	}

	// 最短経路の総重みを計算
	totalWeight := shortestDistances[targetNode]

	return shortestPath, totalWeight
}

func getClosestUnvisitedNode(distances map[*Node]float64, visitedNodes map[*Node]bool) *Node {
	minDistance := math.Inf(1)
	var closestNode *Node

	for node, distance := range distances {
		if !visitedNodes[node] && distance < minDistance {
			minDistance = distance
			closestNode = node
		}
	}

	return closestNode
}

func getNodeNames(nodes []*Node) []string {
	names := make([]string, len(nodes))
	for i, node := range nodes {
		names[i] = node.Name
	}
	return names
}

2024,江端さんの忘備録

社会人になって、まだ数年も経たないくらいの時に、阪神・淡路大震災が発生し、3日間だけでしたが、ボランティア活動に従事したことがあります。

When I worked for less than a few years, the Great Hanshin-Awaji Earthquake struck, and although I was only there for three days, I volunteered.

あれから、約30年を経過しました今にあっても、「被災人数が劇的に減った」とか、「避難所の効率が劇的に改善した」、という感じを受けません。

Even now, some 30 years later, I do not feel that the number of victims has dramatically decreased or that the efficiency of evacuation centers has significantly improved.

今も、ニュースで、30年前と同様に、寒さを凌ぐためのダンボールや新聞紙の使い方とかが説明されている状況です。

Even now, just as it was 30 years ago, the news is explaining how to use cardboard boxes and newspapers to beat the cold, and so on.

「建物が倒壊しなくなる新しい外装塗」とか、「孤立した避難所にで大量の物資を送り込むロケット」とか、そういう技術は、まだ登場していません。

Technology such as "a new exterior coating that stops buildings from collapsing" or "a rocket that sends large quantities of supplies to isolated evacuation centers" has yet to appear.

-----

人類史上、自然災害に対して、私たちは例外なく「受け身」です。

We have been exceptionally "passive" regarding natural disasters throughout history.

自然災害に日常生活を蹂躙されつくして、そこから復興するしかありません。

We can only recover from a natural disaster that has completely overrun our daily lives.

なんとも、もどかしいです。

It is very frustrating.

現時点で、私は、自然災害の直撃に遭遇することなく生きてきましたが、このような幸運が死ぬまで続く保証はありません。

At this point, I have lived without encountering a direct hit from a natural disaster, but there is no guarantee that such good fortune will last until my death.

-----

これから、私は、体を頭も気力も衰えていき、日常生活も、ままならない状態になる未来が確定しています。

I am sure that my body, head, and energy will deteriorate, and I will be unable to live my daily life.

そんな状態で、自然災害の直撃を喰らったら、生き残れるかどうか。仮に生き残ったとしても、その後に生きていく気力が維持できふのかどうか、まったく自信がありません。

In such a situation, I am unsure if I would survive if I were hit directly by a natural disaster. Even if I stayed, I am skeptical I could maintain the energy to live afterward.

『戦争にも災害にも遭遇することなく、人生を逃げきりたい』と、何かぬ向かって祈ることしかできない我が身が、本当にもどかしいです。

It is frustrating that all I can do is pray to God, saying, "I want to escape my life without encountering war or disaster.

2024,江端さんの技術メモ

このプログラムの目的は、時刻表の乗り換え案内のアルゴリズムを実現する為のテストプログラムです。
「到着時刻より早い時間の電車やバスには乗れない」をダイクストラに組み込むことができるかを調べたものです。

ノードのValueが到着・出発時間を表わすと考えて下さい。

package main

import (
	"fmt"
	"math"
)

type Node struct {
	Name  string
	Value float64 // 各ノードに設定された数値
}

type Edge struct {
	From   *Node
	To     *Node
	Weight float64
}

func main() {
	/*
		// ノードとエッジを初期化
		nodeA := &Node{Name: "A", Value: 5}
		nodeB := &Node{Name: "B", Value: 8}
		nodeC := &Node{Name: "C", Value: 6}
		nodeD := &Node{Name: "D", Value: 2}
		nodeE := &Node{Name: "E", Value: 4}
	*/

	// ノードとエッジを初期化
	nodeA := &Node{Name: "A", Value: 1}
	nodeB := &Node{Name: "B", Value: 1}
	nodeC := &Node{Name: "C", Value: 0}
	nodeD := &Node{Name: "D", Value: 1}
	nodeE := &Node{Name: "E", Value: 1}

	/*
		edges := []Edge{
			{nodeA, nodeB, 2},
			{nodeA, nodeC, 4},
			{nodeB, nodeC, 1},
			{nodeB, nodeD, 7},
			{nodeC, nodeD, 3},
			{nodeC, nodeE, 5},
			{nodeE, nodeD, 2},
		}
	*/

	edges := []Edge{ // "方向性あり"に注意
		{nodeA, nodeB, 1},
		{nodeA, nodeC, 1},
		{nodeB, nodeC, 1},
		{nodeB, nodeD, 1},
		{nodeC, nodeD, 1},
		{nodeC, nodeE, 1},
		{nodeE, nodeD, 1},
		{nodeD, nodeE, 1},
	}

	startNode := nodeA
	targetNode := nodeE

	// ダイクストラアルゴリズムを実行
	shortestPath, totalWeight := dijkstra(startNode, targetNode, edges)

	if shortestPath == nil {
		fmt.Println("最短経路が見つかりませんでした。")
	} else {
		fmt.Printf("最短経路: %v\n", getNodeNames(shortestPath))
		fmt.Printf("最短経路の総重み: %.2f\n", totalWeight)
	}
}

func dijkstra(startNode, targetNode *Node, edges []Edge) ([]*Node, float64) {
	// ノード間の最短距離を格納するマップを初期化
	shortestDistances := make(map[*Node]float64)
	// 各ノードの前のノードを格納するマップを初期化
	predecessors := make(map[*Node]*Node)

	// 最短距離を無限大で初期化し、開始ノードの最短距離を0に設定
	for _, edge := range edges {
		shortestDistances[edge.From] = math.Inf(1)
		shortestDistances[edge.To] = math.Inf(1)
	}
	shortestDistances[startNode] = 0

	// 訪問済みのノードを格納するセットを初期化
	visitedNodes := make(map[*Node]bool)

	// まだ訪問していないノードが残っている間ループ
	for len(visitedNodes) < len(shortestDistances) {
		// 未訪問のノードの中から最短距離のノードを選択
		currentNode := getClosestUnvisitedNode(shortestDistances, visitedNodes)

		// ノードがない場合やターゲットノードに到達した場合は終了
		if currentNode == nil || currentNode == targetNode {
			break
		}

		// 隣接ノードの最短距離を更新
		for _, edge := range edges {
			//
			if edge.From == currentNode && edge.To.Value >= currentNode.Value { // ここがポイント
				distance := shortestDistances[currentNode] + edge.Weight
				if distance < shortestDistances[edge.To] {
					shortestDistances[edge.To] = distance
					predecessors[edge.To] = currentNode
				}
			}
		}

		// このノードを訪問済みとしてマーク
		visitedNodes[currentNode] = true
	}

	// 最短経路を復元
	shortestPath := make([]*Node, 0)
	currentNode := targetNode
	for currentNode != nil {
		shortestPath = append([]*Node{currentNode}, shortestPath...)
		currentNode = predecessors[currentNode]
	}

	// 最短経路の総重みを計算
	totalWeight := shortestDistances[targetNode]

	return shortestPath, totalWeight
}

func getClosestUnvisitedNode(distances map[*Node]float64, visitedNodes map[*Node]bool) *Node {
	minDistance := math.Inf(1)
	var closestNode *Node

	for node, distance := range distances {
		if !visitedNodes[node] && distance < minDistance {
			minDistance = distance
			closestNode = node
		}
	}

	return closestNode
}

func getNodeNames(nodes []*Node) []string {
	names := make([]string, len(nodes))
	for i, node := range nodes {
		names[i] = node.Name
	}
	return names
}

2024,江端さんの忘備録

「マンガコミックを読んで、スポーツ選手になった」という人がいるようです ―― バスケットボール選手とかサッカー選手とか。

Some say, "I became an athlete after reading manga comics," as a basketball or soccer player.

「ドラゴン桜」を読んで、東京大学に合格した人の体験談も、いくつかの例が出てきました。

I also found several examples of people who read "Dragon Cherry Blossom" and were accepted to the University of Tokyo.

どの分野でも、トップクラスの世界にいる人のみが、トップクラスの世界から見える景色を見られるのだろうと思います。

I believe that only those in the top-class world in any field can see the view of the top-class world.

しかし、私は、

But I wonder

―― その風景とは、そんなに良い風景なのかな?

"if that landscape is magnificent?"

と、思うことがあります。

-----

高い能力を有する人は、それを必要とする分野で、ゼーゼー言いながらがんばっているし、高くない能力の人(私とか)もまた、その人のできるギリギリの分野で、ゼーゼー言いながらがんばっています。

Those who are highly capable work hard in areas that require it, and those less skilled (like me) work hard in places on the edge.

ノーベル賞を取った人でも、研究の予算確保で走り回っているのを知っていますし、我が国の総理大臣が、日本で一番不幸な役職に見えることもあります。

I know that even Nobel Prize winners are running around securing budgets for their research, and our Prime Minister sometimes appears to be in the most unhappy position in Japan.

権力を持っている人は、その権力を維持する為に、四六時中、注意を支払わなければならず、不正な手段で資金を確保し続けなけれならず、ゼーゼー言っているように見えます。

Those in power must pay attention at all hours to maintain power, keep securing funds through illicit means, and seem to be hash.

-----

私の仮説の域を出ないのですが、『どの風景も、たいして美しくはないんじゃないかな?』と推測しています。

It's a bit of a hypothesis of mine, but I'm guessing that 'none of the landscapes are lovely, are they? I guess.

もちろん、何かを、無事完了できたり、やり遂げた時には、嬉しい気持ちにはなりますが、それは「風景」というようなものではなく、「一瞬のスナップ写真」のように思えます。

Of course, when something is completed or accomplished, we feel happy, but it is not like a "landscape" but rather a "snapshot of a moment in time.

しかも、その「スナップ写真」の数は、あまり多くない ―― 全部集めても「パラパラ動画」にすらならないと思います。

Moreover, the number of these "snapshots" is not very large -- I don't think it would even be a "para-para video" if you collected them all.

-----

『残りの人生で、あと何枚写真が撮れるかな?』などと考えながら、今日もいろいろと作業やっています。

I am working on various tasks today, thinking, "How many more pictures will I take in the rest of my life?

「父親の経済力と母親の狂気」+ 「母親の併走」 + 「父親のIT x OT技術のフル稼動」――

2024,江端さんの忘備録

それは、気がつかないような、小さい揺れだったと思いますが、この地震の揺れ方には記憶がありました。

It was a slight, imperceptible tremor, but I remember how this earthquake shook me.

物凄く強い何かが力付くで抑えつけられたような、あの疼くような感じは、2011年のあの時と同じ感じでした。

That tingling sensation, like something powerful held me down, was the same as in 2011.

-----

リビングのテレビをつけたら、アナウンサーが、恐しい声で避難を叫んでいました ―― 息も切れんばかりの勢いで。

I turned on the TV in the living room, and the announcer was yelling evacuation in a horrible voice -- She was out of breath

比して、具体的な被害情報が入ってきません。

In contrast, no concrete damage information has been received.

現時点で、2種類の動画が何度も繰り返されているだけです。

At this point, only two different videos are being repeated repeatedly.

考えてみれば、被災地のインフラは破壊されつくされていれば、当然、地震計からも津波計からも情報が届かない。

If you think about it, if the infrastructure in the affected area is destroyed, naturally, no information can be received from seismographs or tsunami gauges.

だから、当然、SNSでも情報提供すらできない。

So, of course, they can't even provide information on social networking sites.

―― 被害のリアルタイムは、伝わらない。

"Real-time damage is not communicated."

そもそも、キャリア(電話回線)が壊滅状態では、自治体の避難勧告はもちろん、緊急地震速報すら、届かないのはないか?

First, if the carriers (wire/wireless lines) are destroyed, how can local governments' evacuation advisories and even earthquake early warnings be delivered?

停電すればテレビ消える。テレビが消えれば、回りで何が起きているかも分からない。

If the power goes out, the TV goes out. If the TV goes out, you don't know what's happening around you.

(調べてみたら、どうやらその通りらしいです)。

(I looked it up, and that is true).

最後の手段は、人の声による『逃げろー』だけが唯一の情報になる、という現実にあらためて驚いています。

I am again surprised by the reality that the last resort is the only information available, which is "away" by human voice.

江端家では、電池式のラジオを2台常備しています。

The Ebata family keeps two battery-powered radios on hand.

-----

嫌な記憶がよみがえってきます。

It brings back bad memories.

東日本大震災の時、原発は、原子炉スクラムに成功しました。

When the Tohoku earthquake (March 11, 2011), nuclear power plants were successfully "reactor scram."

この結果をもって、日本の原発は世界に対して「安全」を誇れるものになるはずでした。

With this result, Japan's nuclear power plants should have been able to boast of their "safety" to the world.

『日本の原発はこの「スクラム」が自動的に起動し、核分裂反応の停止を実現したのです。これは、地震大国日本における、原子力発電制御の完全勝利となるはずでした』

"The "scram" automatically activated the nuclear power plants in Japan, and the fission reactions were stopped. This might have been a complete victory for nuclear power control in the earthquake-prone country of Japan."

しかし、原発は、スクラムだけでは「完全に停止」しない ―― 原子炉はスクラム後も冷し続けなければならない。

However, a nuclear power plant does not "completely shut down" with a scram alone -- the reactor must continue to cool after the scram.

ところが、地震の津波によって、その冷却装置用の電池が津波で全滅し、冷却のできなくなった原子炉は、メルトダウン、そして、原子炉格納容器の爆発を引き起します。

However, the earthquake's tsunami wiped out the cooling system's batteries, causing the reactor to melt down and the containment vessel to explode.

「まさか、再び『電源の水没』なんてことにはならないよなぁ」と心配しています。

I'm worried we won't have a 'submerged power supply' again."

12月18日放送の「NHKスペシャル 原発危機 メルトダウン ~福島第一原発 あのとき何が」