Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 将一个数组分成两半是P还是NP?_Algorithm_Complexity Theory_Dynamic Programming - Fatal编程技术网

Algorithm 将一个数组分成两半是P还是NP?

Algorithm 将一个数组分成两半是P还是NP?,algorithm,complexity-theory,dynamic-programming,Algorithm,Complexity Theory,Dynamic Programming,这是一个关于划分问题的算法面试问题 您将获得一个数组,该数组由 由0到5位数字组成。 编写一个函数,返回数组是否可以分割 分成两半,即 两半相等 这是一个NP问题还是可以用动态规划来解决 “在0到5位数之间”的意思是0到99999,我想 我在外面找到了一个很好的答案,所以。两者都有。这个问题是NP问题,我很确定它可以用动态规划在伪多项式时间内解决 一般问题是NP完全问题,可以用动态规划在伪多项式时间内求解。T 这种对0-5位数的特殊限制可能不是NP完全的。0位数是多少 对于分区问题,通常不要

这是一个关于划分问题的算法面试问题

您将获得一个数组,该数组由 由0到5位数字组成。 编写一个函数,返回数组是否可以分割 分成两半,即 两半相等

这是一个NP问题还是可以用动态规划来解决

“在0到5位数之间”的意思是0到99999,我想



我在外面找到了一个很好的答案,所以。

两者都有。这个问题是NP问题,我很确定它可以用动态规划在伪多项式时间内解决

一般问题是NP完全问题,可以用动态规划在伪多项式时间内求解。T

这种对0-5位数的特殊限制可能不是NP完全的。0位数是多少

对于分区问题,通常不要求分区大小相等,只要求它们的和相等。但是这里你说“分成2个一半”,我不确定“一半”是指数组的一半,还是仅仅指总数的一半


我猜这个差异,如果它是一个差异,可能不会影响DP解决方案的复杂性,但我不确定。我手头上没有任何证据,除了“嗯,是的,看起来你可以用DP做的那种事情,我必须考虑一下。”

这显然是NP-一个解决方案可以在多项式时间内验证

但是,它不是NP完全的,因为元素是有界的(数字范围在0到5位之间)

已知该问题经历“相变”,m/n<1时容易,反之则困难


面试问题不仅仅是为了测试问题解决能力,也是为了测试问题分析能力。因此,这个问题不够具体

我可以选择任意两个元素子集,或者它们必须是一致的部分吗? 在第一种情况下,问题是NP完全的(更多信息,请参见),在第二种情况下,问题当然是微不足道的(面试问题通常以琐碎的编程任务结束)

如果一般问题是NP完全问题,也许我们可以尝试将其专门化?我们对阵列了解多少? 也许我们可以通过一些外部假设来简化问题

我认为这是处理这些问题的方法,这是InterViewer所希望的

更新:对于指定的数字范围,该问题等价于离散背包问题(背包大小限制为整个数组和一组大小为100000的权重之和的一半,也就是说,我们可以在O(n)时间内解决它)
有关背包问题的更多信息,请参见。

没错,如果集合的数目是有界的,则问题的多项式复杂性

您可以使用bin搜索技术

阅读wikipage中的分区问题,然后,在开始时,您会找到一个关于子集和问题的参考,它几乎是等价的。
您应该会发现有意义的阅读,wiki页面也可以

您可以调整此算法以解决分区问题,不需要太多修改

求解和子集NP完全问题的线性算法纯Python实现


我想0到5位数的范围意味着0到99999。两半必须是连续的吗?还是只是一些任意的分区?@Gumbo♦ 我认为这可能是武断的
#!/usr/bin/env python3

__author__ = "O. A. Riveros"
__copyright__ = "Copyright 2014, O. A. Riveros, All right reserved"
__license__ = "MIT"
__email__ = "oscar.riveros@gmail.com"

"""
O. A. Riveros
http://independent.academia.edu/oarr
http://twitter.com/maxtuno
"""

"""
first 100 primes
"""
data = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541]

solution = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]

"""
for custom entertainment
solution = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
"""

target = sum([data[i] for i in range(len(solution)) if solution[i] == 1])

l = len(data)

size = len('{0:b}'.format(sum(data)))

def rotate(l,n):
    return l[n:] + l[:n]

def slice(l, n):
    return list(int(l[i:i+n], 2) for i in range(0, len(l), n))

data_second_order = []
for i in range(l):
    data_second_order += rotate(data, i)

T = 0
for i in range(l):
    T += int(''.join('{0:b}'.format(k).zfill(size) for k in rotate(data_second_order, i)), 2)
    t = slice('{0:b}'.format(T).zfill(size*(l**2)), size)
    if (target in t):
        '''
        for review the results
        print('The target {} found in {} steps from {}.'.format(target, i + 1, t))
        '''
        print('The target {} found in {} steps'.format(target, i + 1))
        break

"""
The target 24133 found in 100 steps
"""