Поиск подмножества чисел, которое даст вам максимальную сумму
Как найти подмножество чисел от 2 до 1000, которое даст вам максимальную сумму при условии, что любые два числа из подмножества не разделяют общие простые коэффициенты (например, 1000 и 500 разделяют простой фактор 2)?
один (возможно, более простой) вариант вышеуказанного вопроса: какое наибольшее число в подмножестве? Мы знаем, что 997 является простым числом, и легко исключить 1000 и 998, поэтому возникает вопрос, Является ли 999 в подмножестве?
2 ответов
создайте граф с узлами {2, ..., 1000} и ребра, когда узлы имеют gcd > 1. Решение этой проблемы такое же, как и поиск проблема независимого набора максимального веса, что NP-трудно, за исключением некоторых особых случаев. Этот случай графика не похож на пространственный случай из списка на странице Википедии или даже на этом список.
обновление
как предположил Джеймс, можно уменьшить количество узлов в этом графике. Допустим эта подпись числа N с простым разложением p1^k1*...*pn^kn
- кортеж (p1, ..., pn)
.
первое сокращение-удалить узлы, когда есть узлы с большим значением и той же сигнатурой. Это уменьшает график до 607 узлов.
следующее сокращение-удалить узел N
с подписью (p1, ..., pn)
если есть узлы с сигнатурами, то это разложение (p1, ..., pn)
и сумма >= N
. Что снижает графа узлов 277.
из этих узлов 73 изолированных узлов (праймы > 500.)
Я не знаю ответа на этот вопрос, он кажется мне нетривиальным. Вот несколько мыслей.
сумма состоит из переменного числа слагаемых, скажем0 + s1 + ... sk, где sЯ - целое число в интервале [2, 1000]. Теперь каждого sЯ имеет факторизацию первичной мощности sЯ=(p1e1)*(p2e2) ... где еЯ ≥ 1.
условие, что "любые два числа из подмножества не имеют общих простых факторов" эквивалентно утверждению, что sЯ попарно относительно простые, т. е. gcd(sЯ, sj)=1 для i ≠ j. Также эквивалентно, когда одно слагаемое sЯ содержит простое p, что означает, что никакое другое слагаемое не может содержать это простое число.
Итак, как вы расположите числа в слагаемых? Одно простое правило сразу бросается в глаза. Все простые числа в [500, 1000] могут появляться только в сумме как отдельные слагаемые. Если они умножаются на что-либо еще, даже на наименьшее простое 2, произведение будет слишком большим. Таким образом, остается задача организации меньших простых чисел. И я не знаю, как это сделать. Для полноты я предоставлю следующую короткую программу python, которая показывает один из способов.
def sieve_prime_set(n):
# sieve[i] = set(p1, p2, ...pn) for each prime p_i that divides i.
sieve = [set() for i in range(n + 1)]
primes = []
next_prime = 1
while True:
# find the next prime
for i in range(next_prime + 1, len(sieve)):
if not sieve[i]:
next_prime = i
break
else:
break
primes.append(next_prime)
# sieve out by this prime
for kp in range(next_prime, n + 1, next_prime):
sieve[kp].add(next_prime)
return sieve, primes
def max_sum_strategy1(sieve):
last = len(sieve) - 1
summands = [last]
max_sum = last
prime_set = sieve[last]
while last >= 2:
last -= 1
if not sieve[last] & prime_set:
max_sum += last
prime_set |= sieve[last]
summands.append(last)
return max_sum, summands, prime_set
def max_sum_strategy2(primes, n):
return sum(p ** int(log(n, p)) for p in primes)
if __name__ == '__main__':
sieve, primes = sieve_prime_set(1000)
max_sum, _, _ = max_sum_strategy1(sieve)
print(max_sum)
print(max_sum_strategy2(primes, 1000))
выход
84972
81447
показывая, что "Стратегия 1" превосходный.
улучшенный, но не обязательно оптимальный. Например, включение 1000 кажется хорошим, но это заставляет нас исключать каждое другое четное слагаемое и каждое слагаемое, делимое на 5. Если мы оставим 1000, но вместо этого включим 998, мы сможем использовать другое слагаемое, которое включает 5 в его простую факторизацию. Но включение 998 заставляет исключить другие слагаемые. Таким образом, максимизация суммы не является тривиальной.