简体   繁体   English

算法复杂度和效率,指数运算java

[英]Algorithm Complexity and Efficiency, Exponential operation java

I have a list of strings. 我有一个字符串列表。 I have a set of numbers: 我有一组数字:

{1, 2, 3, 4} {1,2,3,4}

and I need to generate all combinations(?) (strings) to check against my list, Combinations: 并且我需要生成所有组合(?)(字符串)以检查我的列表组合:

(1, 2, 3, 4), (1234), (1, 2, 3, 4), (123, 4), (12, 34), (1, 2, 34), (1, 234), (1, 23, 4), (1, 23), (1, 2, 3), (1 2), ((1 2), (3 4))...etc. (1、2、3、4),(1234),(1、2、3、4),(123、4),(12、34),(1、2、34),(1、234), (1、23、4),(1、23),(1、2、3),(1 2),((1 2),(3 4))...等

This problem grows larger as my set of numbers gets larger. 随着我的数字越来越大,这个问题也越来越大。 Is it right that this is a bad problem to use recursion for? 使用递归是一个不好的问题吗? (that is what I have now) However, aren't the space requirements stricter for an iterative solution, such as the maximum size of lists? (这就是我现在所拥有的)但是,对于迭代解决方案(例如列表的最大大小),空间要求不是更严格吗?

At termination, I need to look at the number of matches, for each result, with my list, and then the number of component parts for each result.. ex. 在终止时,我需要查看每个结果与列表的匹配数,然后是每个结果的组件数。 (1) = 1; (1)= 1; (1, 2) = 2. (1,2)= 2。

My computer was running out of memory (this is an abstraction of a problem with larger objects) 我的计算机内存不足(这是大对象问题的抽象)

EDIT: so my question was in a significantly larger context, such as graphics, comparing pixels in a 700 x 500 matrix... My way cannot be the most efficient way to do this..? 编辑:所以我的问题是在更大的范围内,例如图形,比较700 x 500矩阵中的像素...我的方法不可能是最有效的方法。 I need to know the nested structure of the objects and how many pre-exisiting components that comprise them (that are in my list of strings) 我需要知道对象的嵌套结构以及组成它们的多少个预先存在的组件(在我的字符串列表中)

EDIT2: The full problem is described here . EDIT2: 此处描述完整的问题。

If this is the only way to solve your problem (generating all combinations) then it's going to be slow, it doesn't necessarily have to take up a bunch of memory though. 如果这是解决问题的唯一方法(生成所有组合),那么它将很慢,尽管不一定要占用大量内存。

When doing recursion, you'll want to use tail-recursion to optimize memory usage. 进行递归时,您将需要使用尾递归来优化内存使用。 Or just switch over to an iterative approach. 或者只是切换到迭代方法。

If you need to save the combinations that match, make sure you only save the combination not copies of the objects themselves. 如果需要保存匹配的组合,请确保仅保存组合而不是对象本身的副本。

As a last resort you could always append each matching combination to a file to read in later, then you wouldn't be using much memory at all. 作为最后的选择,您总是可以将每个匹配的组合附加到文件中,以供以后读取,那么您根本就不会使用太多内存。

All these things could help with your memory problems. 所有这些事情可以帮助您解决内存问题。

If you're getting stackoverflow then it is indeed related to using a recursive routine. 如果您正在获得stackoverflow,那么它确实与使用递归例程有关。 This can be alleviated by either increasing the stack depth (see this SO question: What is the maximum depth of the java call stack? ) or using an iterative method. 可以通过增加堆栈深度(请参见此SO问题: java调用堆栈的最大深度是多少 )或使用迭代方法来缓解这种情况。

However, if you simply ran out of memory then you will need to store the solution to disk as you go or figure out a way to store the combinations in a more compact data-structure. 但是,如果您仅用光了内存,那么您将需要在旅途中将解决方案存储到磁盘,或者想出一种以更紧凑的数据结构存储组合的方法。

As a general rule: do not use recursion when iteration is sufficient. 通常的规则是:当迭代足够时,不要使用递归。

Recursion uses a stack, and when that stack is full you have stack overflow. 递归使用一个堆栈,当该堆栈已满时,您将发生堆栈溢出。 If you're performing something with a factorial expansion the stack will seldom be big enough for a recursive solution to be viable. 如果要执行阶乘扩展,则堆栈很少足够大,以至于递归解决方案不可行。

If you can accomplish something by a loop, or a nested loop use that instead. 如果您可以通过循环或嵌套循环来完成某事,请改用它。

Furthermore, if you're simply checking each combination against something, you do not need to store the result of all combinations (which will take up enormous memory), instead compare against each combination then throw that generated combination away. 此外,如果您只是简单地对每个组合进行检查,则不需要存储所有组合的结果(这将占用大量内存),而无需与每个组合进行比较,然后将生成的组合扔掉。

My computer was running out of memory (this is an abstraction of a problem with larger objects) 我的计算机内存不足(这是大对象问题的抽象)

If your program is running out of stack memory, then you will be getting a StackOverflowError . 如果您的程序的堆栈内存不足,那么您将得到一个StackOverflowError If you see that, it indicates that your recursive algorithm is either the wrong approach ... or you have a bug in it. 如果您看到此消息,则表明您的递归算法是错误的方法……或者您有错误。 (Probably the latter. Your maximum depth of recursion should be the base set size N if your algorithm is correct.) (可能是后者。如果算法正确,则最大递归深度应为基本集大小N

If your program is running out of heap memory, then you will be getting an OutOfMemoryError . 如果程序的堆内存不足,则会收到OutOfMemoryError If that is what you see, then the chances are that the problem is that you don't have enough heap memory to hold the set of combinations that you are generating. 如果这是您所看到的,则很可能是问题在于您没有足够的堆内存来容纳要生成的组合集。


I don't think we have enough information to tell you the best way to solve this. 我认为我们没有足够的信息来告诉您解决此问题的最佳方法。 If N is going to be large, then it may be that your entire computational approach is intractable. 如果N将会很大,则可能是您的整个计算方法难以处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM