- Article -

PRIMS-GREEDY

分类于 Algorithm 标签 Prims 发表于2024-04-08 21:50

贪心算法

如何理解贪心算法

贪心算法

  1. 针对一组数据,我们给定限制条件和期望值,希望从中选出几个数据,在满足限制条件后,选最大的期望值。
  2. 在对限制值等贡献量情况下,对期望值贡献最大的数据
  3. 从实践的角度来说,大部分能用贪心算法解决的问题,贪心算法的正确性都是显而易见的,也不需要严格的数学推导证明。

实际上,用贪心算法解决问题的思路,不能总给出最优解。

贪心算法实战分析

  1. 分糖果 m个糖果和n个小孩.(m < n )
  1. 钱币找零
  1. 区间覆盖
  1. 霍夫曼编码 (数据压缩)
a(000).....f(101)

Spanning-Tree

Prim's Selection rule


type Graph struct {
	Verxs  int
	Data   []rune
	Weight [][]int
}

func main() {

	inf := math.MaxInt32

	// 构建一张图
	vertices := []rune{'A', 'B', 'C', 'D', 'E', 'F'}

	v_len := len(vertices)

	weight := [][]int{
		{inf, 5, 6, 4, inf, inf},   //A
		{5, inf, 1, 2, inf, inf},   //B
		{6, 1, inf, 2, 5, 3},       //C
		{4, 2, 2, inf, inf, 4},     //D
		{inf, inf, 5, inf, inf, 4}, //E
		{inf, inf, 3, 4, 4, inf},   // F
	}

	graph := NewGraph(v_len)
	// 创建图
	CreateGraph(graph, v_len, vertices, weight)
	fmt.Println("图的邻接矩阵:")
	ShowGraph(graph)

	fmt.Println("最小生成树的顶点以及权值:")
	Prim(graph, 0)
}

func NewGraph(v_len int) *Graph {
	return &Graph{
		Verxs:  v_len,
		Data:   make([]rune, v_len),
		Weight: make([][]int, v_len),
	}
}

func CreateGraph(graph *Graph, v_len int, vetices []rune, weight [][]int) {
	for i := 0; i < v_len; i++ {
		graph.Data[i] = vetices[i]
		graph.Weight[i] = make([]int, v_len)
		copy(graph.Weight[i], weight[i])
	}
	fmt.Println(graph)
}

func ShowGraph(graph *Graph) {
	for _, link := range graph.Weight {
		fmt.Println(link)
	}
}

// 循环 graph.verxs-1 次,每次迭代添加一个顶点到最小生成树中。
func Prim(graph *Graph, v int) {
	// 用于标记顶点是否被访问
	visited := make([]int, graph.Verxs)
	visited[v] = 1

	//
	var h1, h2 int

	minWeight := math.MaxInt32
	// 控制边数 n个顶点 n-1条边
	for k := 0; k < graph.Verxs-1; k++ {
		// 开始迭代 访问过的顶点
		for i := 0; i < graph.Verxs; i++ {
			// 访问未访问过的顶点
			for j := 0; j < graph.Verxs; j++ {
				if visited[i] == 1 && visited[j] == 0 && graph.Weight[i][j] < minWeight {
					minWeight = graph.Weight[i][j]
					// 记录目前权值最小的两个顶点
					h1 = i
					h2 = j
				}
			}
		}
		fmt.Printf("<%c, %c> 权值:%d\n", graph.Data[h1], graph.Data[h2], minWeight)

		visited[h2] = 1
		minWeight = math.MaxInt32

	}
}


实际应用

  1. 通信网络设计:在通信网络中,如何以最小的成本连通所有的节点是一个关键问题。最小生成树可以帮助设计者优化网络结构,降低建设和维护成本。

  2. 线路规划:在城市道路、铁路或管道的规划中,最小生成树可以帮助确定最佳的连接方式,以降低资源和成本的使用。

  3. 集成电路设计:在芯片设计中,最小生成树可以用于布线,以最小化电路的总长度和延迟,从而提高电路的性能和效率。