Answer the question
In order to leave comments, you need to log in
Java. How to optimize the work of the program?
I want to start by saying that I am a beginner, my code is far from ideal and most likely it needs to be edited or redone.
So, the task is this: The program must display all permutations of the multiset without repetition, the multiset must be entered from the keyboard.
The code itself is shown below. I must say right away that it works, while very correctly.
The essence of the problem is this: the program works only up to the input of 10 numbers, it does not want to go further. Since 10! - this is already 4 million combinations. The arraylist is apparently full, resulting in an Exeption OutOfMemoryError. What to do ? How to be? I will be glad for any help.
I forgot to mention the theory itself. A multiset is a set of numbers.
A = {1^2 ,2^3 ,3^3 ,4^2 ,5^1};
Here the degree is the number of repetitions. Those. this is a cartoon. could be represented as:
A = {1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5};
Based on such numbers, you need to build permutations without repetitions.
My program:
1. I get such a set into the Arraylist
2. I recursively make permutations 3. I
filter out the extra ones using the Hashset 4. I
write to a file. Because in the console, all permutations do not fit.
import java.io.*;
import java.util.*;
import static java.util.Collections.swap;
public class Main {
private static ArrayList <String> rec_filter = new ArrayList<>();
private static String fileName = "new_file.txt";
private static ArrayList<String> in = new ArrayList<String>();
public static ArrayList<Integer> return_Arrlist() throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
ArrayList<Integer> list = new ArrayList<Integer>();
while (true) {
String s = bufferedReader.readLine();
if (s.equals("")) break;
int num = Integer.parseInt(s);
System.out.print(num + "^");
String tmp_step = bufferedReader.readLine();
int stepin = Integer.parseInt(tmp_step);
in.add(num + "^" + tmp_step);
while (stepin > 0) {
list.add(num);
stepin--;
}
}
System.out.println("Введена мультимножина: " +"\n А = " +in);
return list;
}
public static void permute(ArrayList<Integer> list, int start) throws IOException {
for (int j = start; j <= list.size() - 1; j++) {
swap(list, start, j);
//System.out.println(list);
permute(list, start + 1);
swap(list, start, j);
}
rec_filter.add(list.toString());
}
public static void main(String[] args) throws IOException {
permute(return_Arrlist(), 0);
int count = 0;
List <String> list = rec_filter;
Set <String> set = new HashSet<>(list);
rec_filter.removeAll(rec_filter);
list.removeAll(list);
in.removeAll(in);
long startTime = System.currentTimeMillis();
File file = new File(fileName);
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(file, true));
for (Iterator iter = set.iterator(); iter.hasNext();) {
count++;
//System.out.println(count+") "+ iter.next());
writer.write(count+") "+ iter.next()+"\n");
}
writer.close();
}
catch (Exception ex){
ex.printStackTrace();
}
String s = "----------------------------------------\n";
System.out.printf("%s",s);
System.out.println("Всього можливих комбінацій: " +count);
System.out.printf("%s",s);
long timeSpent = System.currentTimeMillis() - startTime;
System.out.println("програма виконувадась " + (timeSpent*10e-6) + " секунд");
}
}
Answer the question
In order to leave comments, you need to log in
Firstly, you do not need to store all the permutations in the computer's memory. They can be dumped to disk immediately after generation. But not a fact.
Secondly, perhaps you need Narayna's algorithm.
Thirdly, ArrayList is not needed everywhere. In many situations, you can get by with a fixed length array. For example, to store the current permutation.
Fourthly - if you have so many permutations generated - there is a chance that they will not even fit into the hashset. I think you should think about sorting and filtering in external memory.
Fifthly, are there any restrictions on the memory used and the total operating time?
Sixth - if you use Narayna's algorithm - you can save memory for storing the result in some cases. Hint - look at a multiset like {1^10, 2^1} with 11 non-unique and 2 unique permutations and guess how many of those permutations will be stored in the HashSet.
PS: Do you have Ukrainian or Belarusian output language? The word "multi-multiple" is worth remembering. Also, you don't need to use printf where println(s) is sufficient. And here's where printf would come in handy - you use println. Compare with your code.
String s = "----------------------------------------";
System.out.println(s);
System.out.printf("Всього можливих комбінацій: %d ",count);
System.out.println(s);
long timeSpent = System.currentTimeMillis() - startTime;
System.out.printf("програма виконувадась %f секунд", (timeSpent*10e-6));
as a result, an Exception OutOfMemoryError is thrown. What to do ? How to be?
As far as I understand, you eat up the most memory list<string>
and set<string>
due to the fact that millions of lines are stored in your memory.
I think it's better not to do it list<string>
from sets, but to do it hashcode()
from one set string
and then add this resulting from hashcode () integer
to set<integer>
and if added, then save the string to disk - such a solution should eat several times less memory
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question