zoukankan      html  css  js  c++  java
  • Minimum Spanning Tree

    Minimum Spanning Tree

    Sample Problem: Agri-Net [Russ Cox, Winter 1999 USACO Open]

    Farmer John is bringing internet connectivity to all farms in the area. He has ordered a high speed connection for his farm and is going to share his connectivity with the other farmers. To minimize cost, he wants to minimize the length of optical fiber to connect his farm to all the other farms.

    Given a list of how much fiber it takes to connect each pair of farms, find the minimum amount of fiber needed to connect them all together. Each farm must connect to some other farm such that a path exists from any farm to any other farm. Some farms might have 1, 2, 3, or more connections to them.

    The Abstraction

    Given: an undirected, connected graph with weighted edges

    spanning tree of a graph is any sub-graph which is a connected tree (i.e., there exists a path between any nodes of the original graph which lies entirely in the sub-graph).

    minimal spanning tree is a spanning tree which has minimal `cost' (where cost is the sum of the weights of the edges in the tree).

    Prim's algorithm to construct a Minimal Spanning Tree

    Given: lists of nodes, edges, and edge costs

    The algorithm (greedily) builds the minimal spanning tree by iteratively adding nodes into a working tree.

    • Start with a tree which contains only one node. Iteratively find the closest node to that one and add the edge between them.
    • Let the distance from each node not in the tree to the tree be the edge (connection) of minimal weight between that node and some node in the tree. If there is no such edge, then assume the distance is infinity (this shouldn't happen).
    • At each step, identify a node (outside the tree) which is closest to the tree and add the minimum weight edge from that node to some node in the tree and incorporate the additional node as a part of the tree.

    For analysis of why this works, consult Chapter 24 of [Cormen, Leiserson, Rivest].

    Here is pseudocode for the algorithm: 

      # distance(j) is distance from tree to node j
      # source(j) is which node of so-far connected MST
      #                      is closest to node j
     1   For all nodes i
     2     distance(i) = infinity        # no connections
     3     intree(i) = False             # no nodes in tree
     4     source(i) = nil 

     5   treesize = 1                    # add node 1 to tree
     6   treecost = 0                   
     7   intree(1) = True
     8   For all neighbors j of node 1   # update distances
     9      distance(j) = weight(1,j)
    10     source(j) = 1 

    11   while (treesize < graphsize)
    12     find node with minimum distance to tree; call it node i
    13     assert (distance(i) != infinity, "Graph Is Not Connected") 

        # add edge source(i),i to MST
    14     treesize = treesize + 1
    15     treecost = treecost + distance(i)
    16     intree(i) = True              # mark node i as in tree 

        # update distance after node i added
    17     for all neighbors j of node i
    18       if (distance(j) > weight(i,j))
    19         distance(j) = weight(i,j)
    20         source(j) = i

    Running time of this formulation is O(N2). You can obtain O(N log N) for sparse graphs, but it normally isn't worth the extra programming time.

    Execution Example

    Consider the following graph with weighted edges: 

    The goal is to find the minimal spanning tree. The algorithm will start at node 1 which connects to nodes 2, 6, and 3 with the weights shown on the edges: 

    Node distance intree source
    1 infinity True nil
    2 30 False 1
    3 20 False 1
    6 25 False 1

    All nodes not shown have infinite distance, intree=False, and source=nil.

    The smallest distance for a node not in the tree is 20, so the listed edge to node 3 is added to the tree: 

    Node distance intree source
    1 infinity True nil
    2 9 False 3
    3 20 True 1
    6 25 False 1
    7 7 False 3

    Note that node 3 is now `in the tree'. Node 2's distance changed to 9 while the source changed to 3.

    The smallest distance is 7, so the edge from node 3 to node 7 (coincidental name!) is connected: 

    Node distance intree source
    1 infinity True nil
    2 9 False 3
    3 20 True 1
    6 10 False 7
    7 7 True 3

    Node 2's distance is 9, the smallest of any node not in the tree. Adding the edge from node 3 to node 2 results in a graph that looks like this: 

    Node distance intree source
    1 infinity True nil
    2 9 True 3
    3 20 True 1
    4 21 False 2
    5 9 False 2
    6 10 False 7
    7 7 True 3

    Add the edge from node 2 to node 5: 

    Node distance intree source
    1 infinity True nil
    2 9 True 3
    3 20 True 1
    4 8 False 5
    5 9 True 2
    6 10 False 7
    7 7 True 3
    8 12 False 5

    Adding the edge from node 5 to node 4 is the next step: 

    Node distance intree source
    1 infinity True nil
    2 9 True 3
    3 20 True 1
    4 8 True 5
    5 9 True 2
    6 10 False 7
    7 7 True 3
    8 12 False 5

    Next up: edge connecting nodes 6 and 7: 

    Node distance intree source
    1 infinity True nil
    2 9 True 3
    3 20 True 1
    4 8 True 5
    5 9 True 2
    6 10 True 7
    7 7 True 3
    8 11 False 6

    Finally, add the edge from node 6 to node 8: 

    Node distance intree source
    1 infinity True nil
    2 9 True 3
    3 20 True 1
    4 8 True 5
    5 9 True 2
    6 10 True 7
    7 7 True 3
    8 11 True 6

    And the minimal spanning tree is easily seen here.

    Dangerous Curve

    Understand that changing any element in a tree requires complete recalculation - incremental recalculation of a spanning tree when changing isolated nodes, for example, is not generally possible.

    Problem Cues

    If the problem mentions wanting an optimal, connected sub-graph, a minimum cost way to connect a system together, or a path between any two parts of the system, it is very likely to be a minimum spanning tree problem.

    Extensions

    If you subject the tree to any other constraints (no two nodes may be very far away or the average distance must be low), this algorithm breaks down and altering the program to handle such constraints is very difficult.

    There is obviously no problem with multiple edges between two nodes (you ignore all but the smallest weight).

    Prim's algorithm does not extend to directed graphs (where you want strong connectedness), either.

    Sample Problems

    Package Routing

    Given: a set of locations of cities and the cost of connecting each pair of cities for a shipping company. Find the cheapest set of pairs of cities such that a package can be routed from any city to any other city.

    Highway Building

    Lower Slobbovia has made the plunge and has decided to connect all their cities with roads. Of course, being cheap, they want to spend as little money as possible. The cost of a highway is linearly proportional to its length. Given the x,y coordinates of the cities in L.S., find the cheapest way to interconnect the cities.

    Bovile Phones (abridged) [USACO Training Camp 1998, Contest 2]

    Given: a collection of stationary cows and haystacks in the field along with a cost function for connecting two (arbitrary) locations. Using only the haystacks and cows, calculate which haystacks one should include in a network to minimize the total cost.

    Analysis: For each possible set of haystacks (i.e., about 2 n sets), calculate the cost of the minimal spanning tree of the haystacks in that set along with all the cows. Find the combination of haystacks that minimizes the cost.

  • 相关阅读:
    替换指定串函数
    实现超级链接
    面向对象的关系数据库设计
    SQL语句的添加、删除、修改多种方法
    InfoWorld2008最佳开源软件大奖
    判断字符是否是汉字
    delphi指针
    项目经理要“三心二意”
    Linq查询Specified cast is not valid异常的常见原因
    SQL SERVER数据库同步示例
  • 原文地址:https://www.cnblogs.com/makeecat/p/3288942.html
Copyright © 2011-2022 走看看