Python算法——求集合的所有子集

二进制法:

①使用两层循环,外层循环为子集个数,对于集合长度为N,子集个数为 2的N次幂,外层循环每循环一次一个子集。内层循环用来判断二进制下标为j的位置数是否为1,如果是1,则输出,如果是0,则不输出。

②以集合[1,2,3]为例,N = len([1,2,3]),外层循环 i 取值范围为[0,7],内层循环⽤于判断i对应⼆进制下标为j的位置是否为1。如果(i>>j)%2为真,那么输出此⼦集。

③当 i =0时,无论 i 对应二进制000右移0位,1位,还是2位,即(i>>j)%2始终为0(假),输出空集。

④当i=1时, i对应二进制001右移0位,即(i>>j)%2为1(真),输出[1]。i对应二进制001右移1位为000,即(>>j)%2为0(假),不追加。i对应二进制001右移2位为000,即(i>>j)%2为0(假),不追加。最终输出[1]。

..............

⑤当i = 3时,i对应二进制011右移0位,即(i>>j)%2为1(真),输出[1]。i对应二进制011右移1位为001
即(i>>j)%2为1(真),追加输出[1,2]。i对应二进制011右移2位为000,即(i>>j)%2为0(假),不追加。最终输出[1,2]。
.............

⑥当i= 6时,i对应二进制110右移0位,即(i>>j)%2为0(假),输出[]。i对应二进制110右移1位为011
即(i>>j)%2为1(真),追加输出[2]。i对应二进制110右移2位为001,即(i>>j)%2为1(真),追加输出[2,3]。最终输出[2,3]。                                                                                                                              
⑦当i=7时,i对应二进制111右移0位,即(>>j)%2为1(真),输出[1]。i对应二进制111右移1位为011,即(i>>j)%2为1(真),追加输出[1,2]。i对应二进制111右移2位为001,即(i>>j)%2为1(真),追加输出[1,2,3]。最终输出[1,2,3]。
 

代码:

def PowerSetsBinary(items):
  N = len(items)
  for i in range(2**N):#[0-8)
    zj = []
    for j in range(N):#[0-3)
      if(i >> j ) % 2 == 1:
        zj.append(items[j])
    print(zj)
a='123'
PowerSetsBinary(a)

或者

def PowerSetsBinary(items):
  N = len(items)
  b=[]
  for i in range(2**N):
    zj =''
    for j in range(N):
      if(i >> j ) % 2 == 1:
        zj=zj+zj.join(items[j])
    b.append(zj)
  print(b)
a='ABCDE'
PowerSetsBinary(a)

### 使用Python实现Kruskal算法解最小生成树 为了通过 Python 实现 Kruskal 算法来寻找图中的最小生成树,可以采用如下方法: 定义类 `Graph` 来表示无向加权图并初始化节点数量以及边列表。每条边由起点、终点及其权重组成。 ```python class Graph: def __init__(self, vertices): self.V = vertices # 节点数目 self.graph = [] # 存储所有的边 (u,v,w),其中 u 和 v 是顶点而 w 表示它们之间的距离 def addEdge(self, u, v, w): self.graph.append([u, v, w]) ``` 接着,在该类内部加入用于执行 Kruskal 的函数 `_find()` 查找集合代表元素;`_union()` 合并两个子集;最后是核心部分——`kruskalMST()`, 它负责按照权重升序排列所有边,并逐一尝试将其添加到正在构建的结果集中直到形成一棵完整的树[^1]。 ```python def _find(self, parent, i): if parent[i] == i: return i return _find(parent, parent[i]) def _union(self, parent, rank, x, y): rootX = _find(parent, x) rootY = _find(parent, y) if rank[rootX] < rank[rootY]: parent[rootX] = rootY elif rank[rootX] > rank[rootY]: parent[rootY] = rootX else : parent[rootY] = rootX rank[rootX] += 1 def kruskalMST(graph): result = [] graph.graph = sorted(graph.graph,key=lambda item:item[2]) parent ,rank= [],[] for node in range(graph.V): parent.append(node) rank.append(0) edges,i,e = graph.graph,0,0 while e<graph.V-1 : u,v,w =edges[i] i+=1 x=_find(parent,u) y=_find(parent,v) if x!=y: e=e+1 result.append([u,v,w]) union(parent,rank,x,y) minimumCost = 0 print ("Edges in the constructed MST") for u, v, weight in result: minimumCost += weight print("%d -- %d == %d" % (u, v, weight)) print("Minimum Spanning Tree",minimumCost) ``` 上述代码实现了基于贪心策略的 Kruskal 算法,能够有效地找到给定连通带权无向图的一棵最小生成树[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唯一ovo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值