2022春季 哈工大 硕士算法设计与分析 实验三 近似算法
作者:互联网
贪心思想: 每次选取未覆盖元素最多的子集
线性规划思想: 以0-1线性规划解整数规划,将结果变量的取值大于1/f的对应子集放入C中 可证明C为可行解且近似比为f
import random import matplotlib.pyplot as plt from pulp import * import time Numbers = None X = [] F = [] Count = [100, 1000, 5000] def DataProduct(Numbers): global X, F X = [i for i in range(Numbers)] random.shuffle(X) T = X.copy() S0 = [T[i] for i in range(20)] for i in range(20): T.pop(0) F.append(S0) while len(T) >= 20: Si = [] # Si的length和从X剩余元素中取的length n = random.randint(1, 20) x = random.randint(1, n) # 从X剩余元素中取x放入Si中 for j in range(x): # 随机下标 idx = random.randint(0, len(T) - 1) Si.append(T[idx]) T.pop(idx) # 从前一个集合中选n - x个元素 Si_1 = F[-1] for j in range(n-x): idx = random.randint(0, len(Si_1) - 1) Si.append(Si_1[idx]) F.append(Si) if len(T) > 0: F.append(T) y = len(F) idx = 0 # 自己建立Number - len(F)个集合放入F for i in range(Numbers - len(F)): Si = [X[idx]] idx = idx + 1 F.append(Si) return y def Greedy(X, F): U = set(X) C = [] while len(U) > 0: # S为F中与已覆盖元素没有交集的最大子集 S = [] maxn = 0 for s in F: t = set(s) l = len(U & t) if l > maxn: maxn = l S = s # 从全集中删除S,并覆盖S(将S放入C) U = U - set(S) C.append(S) return C def computer(X, F): prob = LpProblem("line", LpMinimize) # 为F中每个子集建立一个变量,这里只是变量名 names = [str(i) for i in range(len(F))] # 变量字典,定义域[0, 1] x_vars = LpVariable.dicts("x",names,lowBound=0, upBound=1) # 默认F中每个子集权值为1 prob += lpSum([x_vars[i] for i in names]) f = 0 for e in X: # 对X中的每个e判断在F的哪几个子集中,列出相应变量 ve = [x_vars[i] for i in names if e in F[int(i)]] # f是X的元素在集族F中的最大频率 if f < len(ve): f = len(ve) # >= 1保证了至少有一个有e的子集能被选中 prob += lpSum(ve) >= 1 prob.solve() return [v.varValue for v in prob.variables()], f def LinePlan(X, F): C = [] xs, f = computer(X, F) for i, x in enumerate(xs): if x >= 1.0 / f: C.append(F[i]) return C if __name__ == '__main__': greedy = [] lp = [] for Numbers in Count: DataProduct(Numbers) start = time.time() result = Greedy(X, F) end = time.time() greedy.append(end-start) start = time.time() result = LinePlan(X, F) end = time.time() lp.append(end-start) plt.plot(Count, lp, 'r.-', label='LinePlane') plt.plot(Count, greedy, 'y.-', label = 'Greedy') plt.ylabel('Time') plt.xlabel('Pointnums') plt.legend() plt.show()
标签:plt,idx,len,Si,哈工大,2022,time,append,近似算法 来源: https://www.cnblogs.com/WTSRUVF/p/16350519.html