Java 是否可以设计一个递归来控制输出结果?

Java 是否可以设计一个递归来控制输出结果?,java,algorithm,recursion,Java,Algorithm,Recursion,更新:我的问题是在概念上理解如何实现它。例如(不像下面的解决方案那样精确),我计算出列表中每个值的最大范围偏差,可能对于5,3,2,它将是4-6,2-4,1-3..我不知道如何处理这个范围,所以我的递归只处理这个。我可以用嵌套for循环来实现这一点,但是递归有点棘手 我的代码有两部分在工作。一个生成值(递归),一个返回分数(我只关心超过某个阈值的解决方案)。两者都可以工作(请参见下面的代码)。问题在于集成它们,因为我意识到我不能简单地引用控制它的方法,因为递归仍然会生成许多结果。我认为我需要修改

更新:我的问题是在概念上理解如何实现它。例如(不像下面的解决方案那样精确),我计算出列表中每个值的最大范围偏差,可能对于5,3,2,它将是4-6,2-4,1-3..我不知道如何处理这个范围,所以我的递归只处理这个。我可以用嵌套for循环来实现这一点,但是递归有点棘手

我的代码有两部分在工作。一个生成值(递归),一个返回分数(我只关心超过某个阈值的解决方案)。两者都可以工作(请参见下面的代码)。问题在于集成它们,因为我意识到我不能简单地引用控制它的方法,因为递归仍然会生成许多结果。我认为我需要修改递归代码,以某种方式合并类似方法(返回分数的方法)的逻辑

递归方法采用一个列表和一个整数,并尝试找出求和中的值相乘以等于求和的所有唯一方法(如果发送值列表5,3,2和目标和
100
。计算公式为
5x+3y+2z=100
,则求解所有可能的x、y和z值。下面的示例代码就是这种情况,如果运行它,您将得到完整的结果集)。我的问题是,我不需要大多数结果,只需要符合某些特征的结果。我创建了一个方法(并计划创建更多)来限制结果,但我不确定如何设计递归方法,以节省时间,而不计算我不需要的结果

下面是一个基于结果的一小部分的示例输出。目前,我获得所有结果,然后过滤并删除特定结果,但这意味着我首先必须创建一个非常大的数据集(其中大部分我不需要)。以下是一个可能的输出(不是完整的输出,因为结果太多,我正在手动执行此操作):

}

我的最终目标是拥有数千个变量,并使用各种类型的方法来控制结果,避免结果变得太大


谢谢!另外,正如前面提到的,我对java非常陌生,我肯定我会犯错误。我欢迎关于如何改进的提示和建议。你可以看到我想要的输出和我当前的代码,但如果更好的话,我非常乐意改变我的整个方法,所以我不觉得你的建议需要在我现有代码的上下文中。

至少,您需要的是一种修剪整个搜索树部分的方法

如果将三元组视为3-空间中的点,目标三元组(计算距离的三元组)位于原点,则“距离”标准定义了一个半径为一定的球体。您可以修剪树的任何部分,根据一个或两个坐标确定该点位于球体之外

假设球体半径(最大距离)为10,那么任何坐标大于10的点都必须位于球体之外,递归搜索树的整个分支都可以被修剪。对于sqrt(x^2+y^2)>10的两个坐标,情况也是如此


请注意,这适用于欧几里德距离。如果更改距离算法,则必须进行调整,并且取决于3空间中距离边界的形状,此方法可能有效,也可能无效。

您似乎想要的是一种修剪搜索树整个部分的方法

如果将三元组视为3-空间中的点,目标三元组(计算距离的三元组)位于原点,则“距离”标准定义了一个半径为一定的球体。您可以修剪树的任何部分,根据一个或两个坐标确定该点位于球体之外

假设球体半径(最大距离)为10,那么任何坐标大于10的点都必须位于球体之外,递归搜索树的整个分支都可以被修剪。对于sqrt(x^2+y^2)>10的两个坐标,情况也是如此

请注意,这适用于欧几里德距离。如果更改距离算法,则必须进行调整,并且取决于3空间中距离边界的形状,此方法可能有效,也可能无效。

编辑

根据我们的评论,这里有一个想法:

将对列表添加到findVariables0函数中,作为范围为两个值的参数-例如

(4,6)
为了表示4-6的范围,让我们将列表称为“ranges”

        for (int i = 0, limit = (int) (remaining/constants[n]); i <= limit; i++) {
            variables[n] = i;
            findVariables0(constants, remaining - i * constants[n], variables, n+1);
        }
并添加一个条件值

&& i < ranges[n].getSecond(); i++) // should be 6
比所有的HashMapstuff都要快,而且仍然需要O1访问时间。我不确定将它们存储在HashMaps中对您有什么好处

祝你好运!希望我能帮上忙。

编辑

根据我们的评论,这里有一个想法:

将对列表添加到findVariables0函数中,作为范围为两个值的参数-例如

(4,6)
为了表示4-6的范围,让我们将列表称为“ranges”

        for (int i = 0, limit = (int) (remaining/constants[n]); i <= limit; i++) {
            variables[n] = i;
            findVariables0(constants, remaining - i * constants[n], variables, n+1);
        }
并添加一个条件值

&& i < ranges[n].getSecond(); i++) // should be 6
比所有的HashMapstuff都要快,而且仍然需要O1访问时间。我不确定将它们存储在HashMaps中对您有什么好处


祝你好运!希望我能帮上忙。

谢谢你,吉姆。我会研究你的答案,我是一个初学者,所以这需要时间,但我不会尝试删除整个部分(我已经可以使用类似的方法和所有结果的for循环来完成).我正试图找出一种方法,在第一时间不浪费cpu时间来生成这些结果。很抱歉,如果这是您真正解释的,那么我将进一步研究您的说法,并尝试将其纳入我上面的代码中..通过“修剪”我的意思是根本不去那个分支,从而节省了工作量。如果你能根据这三个值中的一个,确定一个点永远不会足够接近,不管其他两个值,t
runsum += Math.pow((list1[n] - list2.get[n]),2);