贪心算法简介(Introduction of Greedy Algorithm)
(pic: https://www.sicas.cn/Students/Info/Content_110622143056742.shtml)
There is a common situation in which a cashier changes money for customers. Suppose the cashier has paper money denominations 100, 50, 20, 10, 5, 1, 0.5, 0.1 yuan, and we need to change 250 yuan for customers using the smallest number of paper money. How does the cashier make change?
Generally, we want to use as many 100 paper money as we can, then we consider smaller denomination which as 50, 20, 10 and so on until get 250. The priority denomination sequence is 100, 50, 20, 10, 5, 0.5, 0.1. For this scenario, 250= 2*100+50.
The strategy used by the cashier to change is to make decision based on what is the locally best choice.
We hope locally best choices to yield globally best result. This greedy strategy is a very important algorithmic technique, that is Greedy Algorithm.
Although this strategy can not 100% guarantee that, a few famous algorithms has already met this expectation.
We will talk about Prim’s algorithm for solving finding minimum spanning tree in weighted graph and Dijkstra’s algorithm for single-source shortest path.
最小生成树(Minimum Spanning Tree)
What is the tree? -A connected graph without cycle.
What is the spanning tree? -There is a graph (V, E). A spanning tree is (V, E’) with E’ ⊆ E.
graph,
spanning tree,
What is the minimum spanning tree? -A spanning tree with the minimum cost.
graph,
minimum spanning tree,
普林姆算法简介(Introduction of Prim’s Algorithm)
Prim’s algorithm provides the solution to find minimum spanning tree of a graph. It construct a sequence of subtrees T, each adding a node together with an edge to a node in previous subtree. In each step, the closest node from outside the subtree is added. A sketch,
As we choose the node with smallest cost for each step, the spanning tree will have smallest cost overall.
普林姆算法伪代码(Pseudocode of Prim’s Algorithm)
function Prim(<V, E>)
for each v ∈ V do
cost[v] ⟵ infinity
prev[v] ⟵ null
pick initial node v0
cost[v0] ⟵ 0
Q ⟵ initPriorityQueue(V) //key is cost value
while Q is non-empty do
u ⟵ ejectMin(Q)
for each (u, w) ∈ E do
if weight(u, w) < cost[w] then
cost[w] ⟵ weight(u, w)
prev[w] ⟵ v
update(Q, w, cost[w])
时间复杂度(Time Complexity)
In this algorithm, we are using adjacency list to represent the graph and min-heap for priority queue to rank weight of edges. Ejection of node with minimum cost has been executed |V|-1 times. Update the cost of edges in min-heap has been executed |E| times. We know the running time of ejection and update of min-heap is O(log|V|). Overall, it is (|V|-1+|E|)O(log|V|). In connected graph, |V|-1≤|E|. Hence, it is O(|E|log|V|).
Java Code
I will update as soon as possible.
写在最后的话(Postscript)
Greedy algorithm is one of important algorithmic design techniques for solving practical problems. I’ll talk about Dijkstra’s algorithm in next article. Welcome questions always and forever.