-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
You are given an undirected weighted graph of n nodes (0-indexed), represented by an edge list where edges[i] = [a, b] is an undirected edge connecting the nodes a and b with a probability of success of traversing that edge succProb[i]. Given two nodes start and end, find the path with the maximum probability of success to go from start to end and return its success probability. If there is no path from start to end, return 0. Your answer will be accepted if it differs from the correct answer by at most 1e-5. Example 1: Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2 Output: 0.25000 Explanation: There are two paths from start to end, one having a probability of success = 0.2 and the other has 0.5 * 0.5 = 0.25. Example 2: Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 2 Output: 0.30000 Example 3: Input: n = 3, edges = [[0,1]], succProb = [0.5], start = 0, end = 2 Output: 0.00000 Explanation: There is no path between 0 and 2. Constraints: 2 <= n <= 10^4 0 <= start, end < n start != end 0 <= a, b < n a != b 0 <= succProb.length == edges.length <= 2*10^4 0 <= succProb[i] <= 1 There is at most one edge between every two nodes.
- Loading branch information
1 parent
0834392
commit b70073f
Showing
3 changed files
with
128 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package _1514 | ||
|
||
import ( | ||
"container/heap" | ||
) | ||
|
||
func maxProbability(n int, edges [][]int, succProb []float64, start_node int, end_node int) float64 { | ||
// 2 dim array with map | ||
graph := make([]map[int]float64, n) | ||
for i := range graph { | ||
graph[i] = make(map[int]float64) | ||
} | ||
//maxHeap as priority queue | ||
maxHeap := make(PriorityQueue, 0) | ||
//init graph | ||
maxHeap.Push(&Item{value: start_node, priority: 1}) | ||
|
||
seen := make([]bool, n) | ||
|
||
for i := range edges { | ||
u := edges[i][0] | ||
v := edges[i][1] | ||
prob := succProb[i] | ||
//graph = append(graph, map[int]float64{v: prob}) | ||
//graph = append(graph, map[int]float64{u: prob}) | ||
graph[u][v] = prob | ||
graph[v][u] = prob | ||
|
||
} | ||
|
||
for maxHeap.Len() > 0 { | ||
item := heap.Pop(&maxHeap).(*Item) | ||
prob := item.priority | ||
u := item.value | ||
|
||
if u == end_node { | ||
return prob | ||
} | ||
|
||
if seen[u] { | ||
continue | ||
} | ||
|
||
seen[u] = true | ||
|
||
for nextNode, edgeProb := range graph[u] { | ||
if seen[nextNode] { | ||
continue | ||
} | ||
heap.Push(&maxHeap, &Item{value: nextNode, priority: prob * edgeProb}) | ||
} | ||
} | ||
|
||
return 0.0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package _1514 | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func Test_maxProbability(t *testing.T) { | ||
type args struct { | ||
n int | ||
edges [][]int | ||
succProb []float64 | ||
start_node int | ||
end_node int | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want float64 | ||
}{ | ||
{ | ||
name: "test case 1", | ||
args: args{ | ||
n: 3, | ||
edges: [][]int{{0, 1}, {1, 2}, {0, 2}}, | ||
succProb: []float64{0.5, 0.5, 0.2}, | ||
start_node: 0, | ||
end_node: 2, | ||
}, | ||
want: 0.25, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := maxProbability(tt.args.n, tt.args.edges, tt.args.succProb, tt.args.start_node, tt.args.end_node); got != tt.want { | ||
t.Errorf("maxProbability() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package _1514 | ||
|
||
// An Item is something we manage in a priority queue. | ||
type Item struct { | ||
value int | ||
priority float64 | ||
} | ||
|
||
// A PriorityQueue implements heap.Interface and holds Items. | ||
type PriorityQueue []*Item | ||
|
||
func (pq PriorityQueue) Len() int { return len(pq) } | ||
|
||
func (pq PriorityQueue) Less(i, j int) bool { | ||
// We want Pop to give us the highest, not lowest, priority so we use greater than here. | ||
return pq[i].priority > pq[j].priority | ||
} | ||
|
||
func (pq PriorityQueue) Swap(i, j int) { | ||
pq[i], pq[j] = pq[j], pq[i] | ||
} | ||
|
||
func (pq *PriorityQueue) Push(x interface{}) { | ||
item := x.(*Item) | ||
*pq = append(*pq, item) | ||
} | ||
|
||
func (pq *PriorityQueue) Pop() interface{} { | ||
old := *pq | ||
n := len(old) | ||
item := old[n-1] | ||
*pq = old[0 : n-1] | ||
return item | ||
} |