我正在尝试编写一种算法,让我迭代n维空间内的所有所需点,以找到函数f(x)的最小值,其中x是大小为n的向量。
显然,搜索二维或三维空间相当简单,您可以这样做:
for(int i = 0; i < x; i++) {
for(int j = 0; j < y; j++) {
//and so on for however many dimensions you want
不幸的是,对于我的问题,空间的维度并没有固定(我正在为统计程序中的许多函数编写一个通用的最小查找器),因此我必须为每个我想要的n值编写循环使用 - 最终可能会相当大。
我一直试图了解如何使用递归来解决这个问题但却看不到解决方案 - 虽然我确信那里有一个。
解决方案不一定是递归的,但它必须是通用的和有效的(嵌套循环中最内层的行将被称为非常多......)。
我代表要搜索的音量的方式是二维数组:
double[][] space = new double[2][4];
这将表示4d空间,其中每个维度的最小和最大界限分别位于阵列的位置0或1。例如:
dim 0 1 2 3
min(0):-10 5 10 -0.5
max(1): 10 55 99 0.2
有什么想法吗?
答案 0 :(得分:5)
以下是一般概念:
interface Callback {
void visit(int[] p); // n-dimensional point
}
// bounds[] - each number the limits iteration on i'th axis from 0 to bounds[i]
// current - current dimension
// callback - point
void visit(int[] bounds, int currentDimension, int[] p, Callback c) {
for (int i = 0; i < bounds[currentDimension]; i++) {
p[currentDimension] = i;
if (currentDimension == p.length - 1) c.visit(p);
else visit(bounds, currentDimension + 1, p, c);
}
}
/// now visiting
visit(new int[] {10, 10, 10}, 0, new int[3], new Callback() {
public void visit(int[] p) {
System.out.println(Arrays.toString(p));
}
});
答案 1 :(得分:2)
我坚持使用reucrsion,并使用Object
作为参数,使用额外参数dim
,并在相关数组的深度为1时投射它[in我的例子是int[]
]
public static int getMin(Object arr, int dim) {
int min = Integer.MAX_VALUE;
//stop clause, it is 1-dimensional array - finding a min is trivial
if (dim == 1) {
for (int x : ((int[])arr)) {
min = Math.min(min,x);
}
//else: find min among all elements in an array of one less dimenstion.
} else {
for (Object o : ((Object[])arr)) {
min = Math.min(min,getMin(o,dim-1));
}
}
return min;
}
示例:
public static void main(String[] args) {
int[][][] arr = { { {5,4},{2}, {35} } , { {2, 1} , {0} } , 0
};
System.out.println(getMin(arr, 3));
}
将产生:
Object
这种方法的优点是不需要对数组进行任何处理 - 您只需按原样发送它,并将维度作为参数发送。
缺点 - 是[un]安全类型,因为我们动态地将{{1}}转换为数组。
答案 2 :(得分:1)
另一种选择是从0迭代到x * y * z * ...就像在二进制和十进制表示之间转换数字时那样。这是一个非递归解决方案,因此您不会遇到性能问题。
ndims = n;
spacesize = product(vector_sizes)
int coords[n];
for (i = 0; i < spacesize; i++) {
k = i;
for (j = 0; j < ndims; j++ ) {
coords[j] = k % vector_sizes[j];
k /= vector_sizes[j];
}
// do something with this element / these coords
}
答案 3 :(得分:1)
n维数组可以展平为一维数组。你需要的是对这些事情进行数学计算:
这就是我要做的事情:
int[]
。因此,5x7x13x4 4维数组的大小表示为4元素数组“{5,7,13,4}”。3 + 2*5 + 6*5*7 + 0*5*7*13 == 223
。要访问该4维索引,请访问平面数组中的索引223。答案 4 :(得分:0)
不仅仅是功能:
Function loopDimension(int dimensionNumber)
If there is no more dimension, stop;
for(loop through this dimension){
loopDimension(dimensionNumber + 1);
}
答案 5 :(得分:0)
这将运行值列表列表(整数)并选择每个列表的最小值:
import java.util.*;
/**
MultiDimMin
@author Stefan Wagner
@date Fr 6. Apr 00:37:22 CEST 2012
*/
public class MultiDimMin
{
public static void main (String args[])
{
List <List <Integer>> values = new ArrayList <List <Integer>> ();
Random r = new Random ();
for (int i = 0; i < 5; ++i)
{
List<Integer> vals = new ArrayList <Integer> ();
for (int j = 0; j < 25; ++j)
{
vals.add (100 - r.nextInt (200));
}
values.add (vals);
}
showAll (values);
List<Integer> res = multiDimMin (values);
show (res);
}
public static int minof (List <Integer> in)
{
int res = in.get (0);
for (int v : in)
if (res > v) res = v;
return res;
}
public static List<Integer> multiDimMin (List <List <Integer>> in)
{
List<Integer> mins = new ArrayList <Integer> ();
for (List<Integer> li : in)
mins.add (minof (li));
return mins;
}
public static void showAll (List< List <Integer>> lili)
{
for (List <Integer> li : lili) {
show (li);
System.out.println ();
}
}
public static void show (List <Integer> li)
{
for (Integer i: li) {
System.out.print (" " + i);
}
System.out.println ();
}
}