I'm trying to write an algorithm that will let me iterate over all desired points within an n-dimensional space to find the minimum of a function f(x) where x is a vector of size n.
Obviously, searching a 2-d or 3-d space is fairly straightforward, you can simply do:
for(int i = 0; i < x; i++) {
for(int j = 0; j < y; j++) {
//and so on for however many dimensions you want
Unfortunately, for my problem, the dimensionality of the space is not fixed (I'm writing a generalised minimum finder for many functions in a statistical program) and so I'd have to write loops for each value of n I want to use - which might ultimately be rather large.
I've been trying to get my head around how I could do this using recursion but can't quite see the solution - although I'm sure there is one there.
The solution doesn't have to be recursive, but it must be general and efficient (the inner most line in that nested loop is going to get called an awful lot...).
The way I'm representing the volume to search is a 2d array of double:
double[][] space = new double[2][4];
This would represent a 4d space with the minimum and maximum bound in each dimension in position 0 or 1 of the array, respectively. Eg:
dim 0 1 2 3
min(0):-10 5 10 -0.5
max(1): 10 55 99 0.2
Any ideas?
Here is the general idea:
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));
}
});
I'd stick with reucrsion, and use Object as a parameter, with an extra parameter of dim, and cast it when you reach a depth of 1 to the relevant array [in my example, it is an 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;
}
example:
public static void main(String[] args) {
int[][][] arr = { { {5,4},{2}, {35} } , { {2, 1} , {0} } , {{1}}};
System.out.println(getMin(arr, 3));
}
will produce:
0
The advantage of this approach is no need for any processing of the array - you just send it as it is, and send the dimension as a parameter.
The downside - is type [un]safety, since we dynamically cast the Object to an array.
Another option is to iterate from 0 to x*y*z*... like you do when converting a number between binary and decimal representations. This is a non-recursive solution, so you won't run into performance issues.
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
}
n-dimensional arrays can be flattened into one-dimensional arrays. What you need is to do the math for these things:
Calculate the size of the unidimensional array needed.
Figure out the formulas needed to translate back from the n-dimensional index to the unidimensional one.
This is what I'd do:
Represent n-dimensional array sizes and indexes as int[]. So, the size of a 5x7x13x4 4-dimensional array represented as the 4-element array `{ 5, 7, 13, 4 }'.
An n-dimensional array is represented as a unidimensional array whose size is the product of the sizes of each of the dimensions. So a 5x7x13x4 array would be represented as a flat array of size 1,820.
An n-dimensional index is translated into a unique index in the flat array by multiplication and addition. So, the index <3, 2, 6, 0> into the 5x7x13x4 array is translated as 3 + 2*5 + 6*5*7 + 0*5*7*13 == 223. To access that 4-dimensional index, access index 223 in the flat array.
You can also translate backwards from flat array indexes to n-dimensional indexes. I'll leave that one as an exercise (but it's basically doing n modulo calculations).
Isn't the function just:
Function loopDimension(int dimensionNumber)
If there is no more dimension, stop;
for(loop through this dimension){
loopDimension(dimensionNumber + 1);
}
This runs through a List of List of values (Integers) and picks the minimum of each List:
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 ();
}
}
Related
Requirement : There's an input List and an input shift no.
The first line contains two space-separated integers that denote :
n, the number of integers, and
d, the number of left rotations to perform.
The second line contains space-separated integers that describe arr[].
Constraints
1 <= n <= 10^5
1 <= d <= n
1 <= arr[i] <= 10^6
Sample Input
5 , 4
1 2 3 4 5
Sample Output
5 1 2 3 4
I have written this code which is working correctly but getting timeout while large operation. So I need to optimize my code to successfully run all the test cases. How to achieve that.
public static List<Integer> rotateLeft(int d, List<Integer> arr) {
int size = arr.size();
while(d>0) {
int temp = arr.get(0);
for(int i = 0; i<size; i++){
if(i != size-1){
arr.set(i,arr.get(i+1));
} else {
arr.set(i,temp);
}
}
d--;
}
return arr;
}
Failing for this input :
n = 73642
d = 60581
And a huge Integer List of size 73642.
Instead of using nested loops, this can be done in one loop. The final index of an element at index i after n shifts, can be calculated as (i + n) % listLength, this index can be used to populate a shifted list. Like this:
import java.util.*;
class HelloWorld {
public static void main(String[] args) {
List<Integer> arr = Arrays.asList(1,2,3,4,5);
System.out.println(rotateLeft(4, arr));
}
public static List<Integer> rotateLeft(int d, List<Integer> arr) {
List<Integer> rotatedList = new ArrayList<>(arr.size());
int i=0;
for(i=0; i< arr.size(); i++) {
int rotatedElementIndex = ((i+d) % arr.size());
rotatedList.add(arr.get(rotatedElementIndex));
}
return rotatedList;
}
}
Never liked hackerrank puzzles. What does "and a huge Integer array" mean? May we create a new list or we need to modify existing one? If we ought to modify existing one why our method is not void?
If we may create new list the optimal solution would be creating new Integer[] array and call System.arraycopy() twice.
In case of inline modifications the solution is:
public static List<Integer> rotateLeft(int d, List<Integer> arr) {
int i = 0, first = arr.get(0);
int n = arr.size();
while (true) {
int source = (i + d) % n;
if (source == 0) {
arr.set(i, first);
break;
}
arr.set(i, arr.get(source));
i = source;
}
return arr;
}
For an in-place solution:
reverse the subarrays arr[0, d) and arr[d, n) in-place. This is done by swapping the elements in symmetric pairs.
reverse the whole array.
E.g., abcdefghijk, d=4
abcd|efghijk -> dcba|kjihgfe -> efghijk|abcd
My goal is to find all possible combinations of items in an ArrayList with a fixed predefined length. For example, if my ArrayList is called arr and contains <1, 2, 3> then the desired output for the predefined size r = 2 will be:
<1,2>
<1,3>
<2,3>
Here is code I found which prints the desired output. My problem is that I need to define a return value type ArrayList which holds the outputs from the method. Besides, my input type is also an ArrayList<Integer>, instead of an Array, which has made it more complicated for me because then I first will need to convert the values to the primitive type int.
import java.io.*;
class Permutation {
/* arr[] ---> Input Array
data[] ---> Temporary array to store current combination
start & end ---> Staring and Ending indexes in arr[]
index ---> Current index in data[]
r ---> Size of a combination to be printed */
static void combinationUtil(int arr[], int data[], int start,
int end, int index, int r)
{
// Current combination is ready to be printed, print it
if (index == r)
{
for (int j=0; j<r; j++)
System.out.print(data[j]+" ");
System.out.println("");
return;
}
// replace index with all possible elements. The condition
// "end-i+1 >= r-index" makes sure that including one element
// at index will make a combination with remaining elements
// at remaining positions
for (int i=start; i<=end && end-i+1 >= r-index; i++)
{
data[index] = arr[i];
combinationUtil(arr, data, i+1, end, index+1, r);
}
}
// The main function that prints all combinations of size r
// in arr[] of size n. This function mainly uses combinationUtil()
static void printCombination(int arr[], int n, int r)
{
// A temporary array to store all combination one by one
int data[]=new int[r];
// Print all combination using temprary array 'data[]'
combinationUtil(arr, data, 0, n-1, 0, r);
}
/*Driver function to check for above function*/
public static void main (String[] args) {
int arr[] = {1, 2, 3, 4, 5};
int r = 3;
int n = arr.length;
printCombination(arr, n, r);
}
}
/* This code is contributed by Devesh Agrawal */
ArrayList is backed up by an array internally so translating the current array based implementation to ArrayList should be reasonable. In arrays you use the [] operator to index an element in the array, and the parallel operations using ArrayList are get and set. Also you might want to read on Autoboxing and Unboxing. A possible implementation using Lists:
static void combinationUtil(List<Integer> list, List<Integer> data, int start, int end, int index, int r) {
// Current combination is ready to be printed, print it
if (index == r) {
for (int j = 0; j < r; j++)
System.out.print(data.get(j) + " ");
System.out.println("");
return;
}
// replace index with all possible elements. The condition
// "end-i+1 >= r-index" makes sure that including one element
// at index will make a combination with remaining elements
// at remaining positions
for (int i = start; i <= end && end - i + 1 >= r - index; i++) {
data.set(index, list.get(i));
combinationUtil(list, data, i + 1, end, index + 1, r);
}
}
// The main function that prints all combinations of size r
// in list of size n. This function mainly uses combinationUtil()
static void printCombination(List<Integer> list, int n, int r) {
// A temporary array to store all combination one by one
List<Integer> data = new ArrayList<>(Collections.nCopies(r, 0));
// Print all combination using temporary array 'data'
combinationUtil(list, data, 0, n - 1, 0, r);
}
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int r = 3;
int n = list.size();
printCombination(list, n, r);
}
I'm struggling with quite interesting assignment and looking for advice.
The case is to find the longest sublist from the given list of pairs. First elements from these pairs should be in ascending order and second ones - in descending.
For example for {{1,3},{3,1},{2,0},{4,4},{5,3},{6,2}} answer is {{4,4},{5,3},{6,2}}
So, how I see this:
Go via array and check condition for two pairs, if condition is true, save value somewhere and increase sublist elements count. Otherwise check if current sublist recording is empty and add the last element to current sublist, then check if this sublist is the longest among others.
And I encountered two major problems - duplicates and absence of the last element.
For this moment I came to this:
public static void findLagrestList() {
int arr[][] = {{1,3},{3,1},{2,0},{4,4},{5,3},{6,2}};
ArrayList<int[]> currentSublist = new ArrayList<>();
ArrayList<int[]> resultSublist = new ArrayList<>();
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr[i].length-1; j++) {
if (arr[i][j] < arr[i + 1][j] && arr[i][j + 1] > arr[i + 1][j + 1]) {
if(!currentSublist.contains(arr[i])){
currentSublist.add(arr[i]);
}
} else {
currentSublist.add(arr[i]);//the last one
if(currentSublist.size()>resultSublist.size()){
resultSublist.clear();
resultSublist.addAll(currentSublist);
currentSublist.clear();
}
break;
}
}
}
System.out.println(resultSublist.size());
printList(resultSublist);
}
private static void printList(ArrayList<int[]> list) {
for (int[] is : list) {
System.out.println();
for (int i : is) {
System.out.print(i + " ");
}
}
}
output:
2
1 3
3 1
Thanks in advance for any clue or hint.
I Wrote for you this algorithm it Does exactly what you want.
1) i create a results ArrayList;
2) initialize variable sum to 0;
3) loop through all values of array[][]; for each array value get the sum of its components
4) if the sum of the components of thhe array value is less or equal to sum then insert the array value in the results array
5) but if the sum of the components of the array value is greater than sum, then check the results array. if its empty then insert the array value. if its not empty check the sum of the components of each value of the results Arraylist with the sum of the components of the value of the soucrce array.Any value with sum less than that of source array component is removed then insert this particular value to the results arraylist.
import java.util.ArrayList;
class lists{
public static void findLagrestList() {
int arr[][] = {{1,3},{3,1},{2,0},{4,4},{5,3},{6,2}};
//ArrayList<int[]> currentSublist = new ArrayList<>();
ArrayList<int[]> resultSublist = new ArrayList<>();
int result_arr[][]={};
int sum =0;
for(int i=0;i<arr.length;i++)
{
int [] inner_arr =arr[i];
int valuesum =arr[i][0]+arr[i][1];
if(valuesum>sum)
{
if(resultSublist.size()>0)
{
for(int k=0;k<resultSublist.size();k++)
{
int [] cvalue = resultSublist.get(k);
int summ=cvalue[0]+cvalue[1];
if(valuesum>summ)
{
resultSublist.remove(k) ;
}
}
resultSublist.add(inner_arr);
}else{
resultSublist.add(inner_arr);
sum = valuesum;
}
}
}
System.out.println(resultSublist.size());
printList(resultSublist);
}
private static void printList(ArrayList<int[]> list) {
for (int[] is : list) {
System.out.println();
for (int i : is) {
System.out.print(i + " ");
}
}
}
public static void main(String [] oo)
{
lists.findLagrestList();
}
}
the output is
3
4 4
5 3
6 2
Okay, a hint first.
For every pair (x, y) for a given x, you're only interested in the one with the greatest y.
For every pair (x, y) for a given y, you're only interested in the one with the smallest x.
Try building maps of respective least/greater values for the x's and y's and see where you get from there (you will need two copies of the pair list, one sorted lexicographically x -> y and one sorted lexicographically y -> x).
I've just been looking at the following piece of code
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(final String[] args) {
final int sizeA = 3;
final int sizeB = 5;
final List<int[]> combos = getAllCombinations(sizeA-1, sizeB);
int counter = 1;
for(final int[] combo : combos) {
System.out.println("Combination " + counter);
System.out.println("--------------");
for(final int value : combo) {
System.out.print(value + " ");
}
System.out.println();
System.out.println();
++counter;
}
}
private static List<int[]> getAllCombinations(final int maxIndex, final int size) {
if(maxIndex >= size)
throw new IllegalArgumentException("The maximum index must be smaller than the array size.");
final List<int[]> result = new ArrayList<int[]>();
if(maxIndex == 0) {
final int[] array = new int[size];
Arrays.fill(array, maxIndex);
result.add(array);
return result;
}
//We'll create one array for every time the maxIndex can occur while allowing
//every other index to appear, then create every variation on that array
//by having every possible head generated recursively
for(int i = 1; i < size - maxIndex + 1; ++i) {
//Generating every possible head for the array
final List<int[]> heads = getAllCombinations(maxIndex - 1, size - i);
//Combining every head with the tail
for(final int[] head : heads) {
final int[] array = new int[size];
System.arraycopy(head, 0, array, 0, head.length);
//Filling the tail of the array with i maxIndex values
for(int j = 1; j <= i; ++j)
array[size - j] = maxIndex;
result.add(array);
}
}
return result;
}
}
I'm wondering, how do I eliminate recursion from this, so that it returns a single random combination, rather than a list of all possible combinations?
Thanks
If I understand your code correctly your task is as follows: give a random combination of numbers '0' .. 'sizeA-1' of length sizeB where
the combination is sorted
each number occurs at least once
i.e. in your example e.g. [0,0,1,2,2].
If you want to have a single combination only I'd suggest another algorithm (pseudo-code):
Randomly choose the step-up positions (e.g. for sequence [0,0,1,1,2] it would be steps (1->2) & (3->4)) - we need sizeA-1 steps randomly chosen at sizeB-1 positions.
Calculate your target combination out of this vector
A quick-and-dirty implementation in java looks like follows
// Generate list 0,1,2,...,sizeB-2 of possible step-positions
List<Integer> steps = new ArrayList<Integer>();
for (int h = 0; h < sizeB-1; h++) {
steps.add(h);
}
// Randomly choose sizeA-1 elements
Collections.shuffle(steps);
steps = steps.subList(0, sizeA - 1);
Collections.sort(steps);
// Build result array
int[] result = new int[sizeB];
for (int h = 0, o = 0; h < sizeB; h++) {
result[h] = o;
if (o < steps.size() && steps.get(o) == h) {
o++;
}
}
Note: this can be optimized further - the first step generates a random permutation and later strips this down to desired size. Therefore it is just for demonstration purpose that the algorithm itself works as desired.
This appears to be homework. Without giving you code, here's an idea. Call getAllCombinations, store the result in a List, and return a value from a random index in that list. As Howard pointed out in his comment to your question, eliminating recursion, and returning a random combination are separate tasks.
I am trying to work out the best way to generate all possible permutations for a sequence which is a fixed number of digits and each digit has a different alphabet.
I have a number of integer arrays and each one can have different length and when generating the permutations only the values of the array can occupy the position in the final results.
A specific example is an int array called conditions with the following data:
conditions1 = {1,2,3,4}
conditions2 = {1,2,3}
conditions3 = {1,2,3}
conditions4 = {1,2}
conditions5 = {1,2}
and I want to create a 5 column table of all the possible permutations - this case 144 (4x3x3x2x2). Column 1 can only use the values from conditions1 and column 2 from conditions2, etc.
output would be :
1,1,1,1,1
1,1,1,1,2
1,1,1,2,1
1,1,1,2,2
1,1,2,1,1
.
.
through to
4,3,3,2,2
It's been too long since since I've done any of this stuff and most of the information I've found relates to permutations with the same alphabet for all fields. I can use that then run a test after removing all the permutations that have columns with invalid values but sounds inefficient.
I'd appreciate any help here.
Z.
Look ma, no recursion needed.
Iterator<int[]> permutations(final int[]... conditions) {
int productLengths = 1;
for (int[] arr : conditions) { productLengths *= arr.length; }
final int nPermutations = productLengths;
return new Iterator<int[]>() {
int index = 0;
public boolean hasNext() { return index < nPermutations; }
public int[] next() {
if (index == nPermutations) { throw new NoSuchElementException(); }
int[] out = new int[conditions.length];
for (int i = out.length, x = index; --i >= 0;) {
int[] arr = conditions[i];
out[i] = arr[x % arr.length];
x /= arr.length;
}
++index;
return out;
}
public void remove() { throw new UnsupportedOperationException(); }
};
}
Wrapping it in an Iterable<int[]> will make it easier to use with a for (... : ...) loop. You can get rid of the array allocation by doing away with the iterator interface and just taking in as argument an array to fill.