有两个n长度数组(a和b)由整数组成> 2.
在每个转弯处,我想从每个数组中删除一个整数(a [i]和b [j]),因为它们的某个条件是真的(例如它们不是共同素数). (如果条件不正确,我会尝试删除另一个组合)
毕竟我想找到我可以实现的最大转数(直到没有可能的组合去除哪个符合条件).我们称之为最佳转弯次数.
我试图用搜索算法和使用Python的PriorityQueue来解决这个问题:
def search(n, a, b):
q = queue.PriorityQueue()
encountered = set()
encountered.add((tuple(a), tuple(b)))
q.put((number_of_coprime_combinations(a, b), a, b))
while q:
cost, a, b = q.get()
combs = not_coprime_combinations(a, b)
if not combs:
return n - len(a)
for a, b in combs:
if not (tuple(a), tuple(b)) in encountered:
q.put((number_of_coprime_combinations(a, b), a, b))
encountered.add((tuple(a), tuple(b)))
number_of_coprime_combinations(a,b)返回给定数组a和b的可能的co-prime组合的数量.这用作两个数组的给定状态的成本.
def number_of_coprime_combinations(a, b):
n = 0
for idx_a, x in enumerate(a):
for idx_b, y in enumerate(b):
if is_coprime(x, y):
n += 1
return n
not_coprime_combinations(a,b)返回一个可能的状态列表,其中a和b的非共同组合已被删除:
def not_coprime_combinations(a, b):
l = []
for idx_a, x in enumerate(a):
for idx_b, y in enumerate(b):
if not is_coprime(x, y):
u, v = a[:], b[:]
del(u[idx_a])
del(v[idx_b])
l.append((u, v))
return l
>>> not_coprime_combinations([2,3],[5,6])
[([3], [5]), ([2], [5])]
问题是这个解决方案对于大整数的大数组来说非常低效.所以我想知道这个问题是否有更好的解决方案..
例:
n = 4
a = [2, 5, 6, 7]
b = [4, 9, 10, 12]
可以删除:
(2, 4)
(5, 10)
(6, 9)
这将导致最佳解决方案:
a = [7]
b = [12]
但如果有人会删除:
(6, 12)
(2, 10)
一个人会得到次优的解决方案:
a = [5, 7]
b = [4, 9]
该算法应始终达到最佳匝数(在本例中为3).
解决方法:
据我所知,解决这个问题:
>构造二分图G,使得对于每个Ai和Bj,如果GCD(Ai,Bj)> 1,G中有一条边(Ai,Bj).
>找到G的最大匹配
>匹配的基数是解决方案
我不知道如何更快地解决这个问题.
标签:python,algorithm,python-3-x
来源: https://codeday.me/bug/20190625/1283490.html