creating k -itemsets from 2-itemsets - java

I have written the following code to generate k-elements itemsets from 2-element sets. The two elements sets are passed to candidateItemsetGen as clist1 and clist2.
public static void candidateItemsetGen(ArrayList<Integer> clist1, ArrayList<Integer> clist2)
{
for(int i = 0; i < clist1.size(); i++)
{
for(int j = i+1; j < clist2.size(); j++)
{
for(int k = 0; k < clist1.size()-2; k++)
{
int r = clist1.get(k).compareTo(clist2.get(k));
if(r == 0 && clist1.get(k)-1 == clist2.get(k)-1)
{
** candidateItemset.add(clist1.get(i), clist1.get(clist1.size()-1), clist2.get(clist2.size()-1));
}
}
}
}
// return candidateItemset;
}
The condition to create k-itemsets is that clist1(i) == clist2(i), where i = 1,...,k-2 and clist1(k-2) != clist2(k-2). But there is error in the code where i have put **. How can i fix this? The logic is that this function generates candidateItemsets which will be used again as an input to generate other candidate Itemsets.

The add method in ArrayList takes a maximum of two arguments and you are passing in three. If you wish to add all three items, call add(Integer i) three times.
Also, if you want to return candidateItemsets from the function you must declare an ArrayList<Integer> return value and create the list:
public static ArrayList<Integer> candidateItemsetGen(ArrayList<Integer> clist1, ArrayList<Integer> clist2) {
ArrayList<Integer> candidateItemset = new ArrayList<Integer>();
for (int i = 0; i < clist1.size(); i++) {
for (int j = i + 1; j < clist2.size(); j++) {
for (int k = 0; k < clist1.size() - 2; k++) {
int r = clist1.get(k).compareTo(clist2.get(k));
if(r == 0 && clist1.get(k) - 1 == clist2.get(k) - 1) {
candidateItemset.add(clist1.get(i));
candidateItemset.add(clist1.get(clist1.size() - 1));
candidateItemset.add(clist2.get(clist2.size() - 1));
}
}
}
}
return candidateItemset;
}
If you want to add all three as a group of related values, store them together in a separate data structure and add that to candidateItemset (of correct type).

You could optimize that code further if you consider that each list of itemsets are sorted according to the lexical order.
For example, let's say that
clist1 = AB, AD, AF, AG, BC, FG
clist2 = BD, FE, FG, FH, FI
With your code, you will compare AB with all the itemsets of clist2.
But you could optimize that, by stoping right after BD because B is larger than A in AB according to the lexical order. Therefore, no itemsets after BD in Clist2 will match with AB.
If you want to see the code of an optimized implementation of Apriori, you can check my open source data mining library named SPMF

Related

JAVA code for the possible number of combinations of a 6-digit code between ranges of two integers

Conditions of the 6-digit code:
None of the digits are 0
Each digit of the combination is different
The 6-digit number is divisible by each one of the digits
Input:
Two integers, L and H
L is the limit on the smallest number on the range
H is the limit on the largest number on the range
Output:
C, which defines the number of possible combinations where L<=c<=H
I thought I could use arrays as the condition check, then realized I couldn't use it to find the number of possible combinations. Tried using loops, but couldn't figure it out, all I got for the pseudocode is the input, then a condition if L is less or equal to H. Then I sort of ran to a brick wall.
Here's the code.
''''''''
public static void main(String[] args) {
Scanner FF = new Scanner(System.in);
List<Integer> result = new ArrayList<>();
int l = FF.nextInt();
int h = FF.nextInt();
for (int i = l; i <= h; i++) {
result.add(i);
}
for (int i=l; i<=h; i++){
if (result.get(i) == result.get(i)){
result.remove(i);
}
int temp = result.get(i);
while (result.get(i)>0){
int k = result.get(i)%10;
if (temp % k != 0){
result.remove(i);
}
}
if (String.valueOf(result.get(i)).contains("0")){
result.remove(i);
}
}
System.out.println(result);
}
}
You can create a stream of integers, here 111111 to 1000000 and then filter out everything what doesnot meet your conditions.
public class SixDigitCode {
public static void main(String[] args) {
IntStream.iterate(111111, i -> i < 1000000, i -> i + 1)
.filter(containsZero.negate())
.filter(digitDifferent)
.filter(divideByDigits)
.forEach(System.out::println);
}
static IntPredicate containsZero = i -> Integer.toString(i).contains("0");
static IntPredicate digitDifferent = i -> Integer.toString(i).chars().boxed().collect(Collectors.toSet()).size() == 6;
static IntPredicate divideByDigits = i -> Integer.toString(i).chars().boxed()
.filter( x -> i%Character.getNumericValue(x) ==0)
.count() ==6;
}
There are multiple ways to solve this problem.
Let's start with an easy, but inefficient one:
boolean isOk(int number){
String numberStr = Integer.toString(number);
if(numberStr.contains("0"))
return false;
for(int i = 0; i < numberStr.length(); i++){
for(int j = i + 1; j < numberStr.length(); j++){
if(numberStr.charAt(i) == numberStr.charAt(j))
return false;
}
}
return true;
}
...
int count = 0;
for(int i = L; i <= H; i++){
if(isOk(i))
count ++;
}
Note: this code is by no means optimal, but I think it is a straight forward easy to understand solution.
However, I cannot test it right now, so it may contain minor issues.

For k collections all of which have length = N, finding common elements with a O((k-1)*N)

I am supposed to write a code which is supposed to find the common elements existing in k collections of N-elements efficiently. All collections are sorted and they may have various sizes, but let's assume same sizes for the sake of simplicity here. Only thing that counts is the comparisons between elements; that should be less than O((k-1)*N).
I have developed the below code, but in case of mentioned scenario the number of comparisons is about (k-1)NN
Appreciate the help in advance.
//Arrays are sorted and the shortest array is chosen as the query automatically
boolean com;
loop1: for (int i = 0; i < QuetyList.length; ++i) {
com = false;
loop2: for (int k = 0; k < OtherLists.length; ++k) {
com = false;
loop3: for (int y = 0; y < OtherLists[k].size(); ++y) {
++comparisons;
if (QueryList[i].compareTo(OtherLists[k][y]) == 0) {
com = true;
break loop3;
}
++comparisons;
if (QueryList[i].compareTo(OtherLists[k][y]) < 0) {
break;
}
}
if (com == false) {
break;
}
}
if (com == true) {
commons.add(QueryList[i]);
}
}
Sample test
Comparable [] QuetyList = {200,200,200,200};
Comparable [] collection2 = {2,10,50,200};
Comparable [] collection3 = {2,10,40,200};
Comparable [][] OtherLists = {collection2,collection3};
This is for a homework. There is a chance you may have crossed sometime in your education. Thanks in advance.
The basic idea is to keep an index on every list you have, and only advance this index when the value at the index is the smallest among all the lists.
I can't see if it's doable for k lists at once, but it's certainly doable 2 lists at a time, each should take N comparisons, which should give you O(k * N) (k-1 runs of N comparison).
Something like:
public Comparable[] common(Comparable[] a, Comparable[] b) {
// List is more flexible, but the toArray at the end is a bit costly. You can probably figure a better way of doing this.
List<Comparable> res = new ArrayList<>();
int indexA = 0;
int indexB = 0;
while (indexA < a.length && indexB < b.length) {
// Exercice for the reader: replace with compareTo calls
if (a[indexA] == b[indexB]) {
// Common item!
res.add(a[indexA]);
indexA++;
indexB++;
} else if (a[indexA] < b[indexB]) {
// item in A is smaller, try the next
indexA++;
} else {
indexB++;
}
}
return res.toArray(new Comparable[0]);
}
From this, you can group your lists 2 by 2 until only one list remains.

How is this C++ function working differently than the equivalent java function?

I'm trying to implement a Java version of the following C++ algorithm:
void constructPrintLIS(int arr[], int n)
{
std::vector< std::vector<int> > L(n);
L[0].push_back(arr[0]);
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if ((arr[i] > arr[j]) &&
(L[i].size() < L[j].size() + 1))
{
L[i] = L[j];
cout << true << endl;
}
else
{
cout << false << endl;
}
}
L[i].push_back(arr[i]);
}
std::vector<int> max = L[0];
for (std::vector<int> x : L)
{
if (x.size() > max.size())
{
max = x;
}
}
printLIS(max);
}
Here is the Java version
private static List<Integer> getLongestIncreasingSubsequence(
List<Integer> sequence
)
{
ArrayList<ArrayList<Integer>> cache =
new ArrayList<ArrayList<Integer>>(sequence.size());
// Populate the elements to avoid a NullPointerException
for(int i = 0; i < sequence.size(); i++)
{
cache.add(new ArrayList<Integer>());
}
cache.get(0).add(sequence.get(0));
// start from the first index, since we just handled the 0th
for(int i = 1; i < sequence.size(); i++)
{
// Add element if greater than tail of all existing subsequences
for(int j = 0; j < i; j++)
{
if((sequence.get(i) > sequence.get(j))
&& (cache.get(i).size() < cache.get(j).size() + 1))
{
cache.set(i, cache.get(j));
}
}
cache.get(i).add(sequence.get(i));
}
// Find the longest subsequence stored in the cache and return it
List<Integer> longestIncreasingSubsequence = cache.get(0);
for(List<Integer> subsequence : cache)
{
if(subsequence.size() > longestIncreasingSubsequence.size())
{
longestIncreasingSubsequence = subsequence;
}
}
return longestIncreasingSubsequence;
}
I don't understand what I am doing differently. The C++ algorithm prints the correct result when the test sequence is {9766, 5435, 624, 6880, 2660, 2069, 5547, 7027, 9636, 1487}, with the correct result being 624, 2069, 5547, 7027, 9636. However, the Java version that I have written returns an incorrect result of 624, 6880, 2660, 2069, 5547, 7027, 9636, 1487 and I don't understand why. I have tried tracing it in the debugger, and I can't figure out what is going wrong.
I tried adding a print statement indicating whether the if statement evaluated to true/false each time, and compared it with the C++ program, and it was the same, so that isn't the problem.
I suspect it is something to do with a subtle difference between a vector and an ArrayList, but I don't know.
I suspect the problem is that in Java, the cache contains references to lists, whereas in C++ it contains the lists themselves.
Thus, in C++
L[i] = L[j];
copies the list at index j to index i, whereas in Java
cache.set(i, cache.get(j));
copies a reference. That means, that when you subsequently add items to the one, they are also added to the other.
Maybe use
cache.set(i, new ArrayList<>(cache.get(j)));
so that you create a copy, like in C++.

Sorting an object array using Insert and Selection sorts

I need to create a method to sort an Object Array. I've never done this, but I must revise this for my course. I'm totally lost when it comes to implementing a sorting method. I need to sort using a insertion sort and selection sort.
This is my code I have so far in. All I must do is call the sort() when the user wishes to do so.
package citylisttest;
public class CityList {
private City[] city;
private Integer numberOfCities;
public CityList (Integer cityListSize){
this.city=new City[cityListSize];
this.numberOfCities=0;
}
public void addCity(String city){
this.city[this.numberOfCities]=new City(city);
this.numberOfCities++;
}
public String toString(){
String cityDetails=new String();
if (this.numberOfCities!=0){
cityDetails+=String.format("%-15s\n","CITY");
for(Integer i=0;i<this.numberOfCities;i++) {
cityDetails+=this.city[i]+"\n"; }
}
else
cityDetails+="City list is empty";
return cityDetails;
}
public void sort(){
}
}
First, I would suggest renaming the variable city to cities since it is an array, and it holds more than one city. In addition, also consider encapsulating your data by marking as private your instance variable and creating getters and setters respectively.
Let's say you want to sort them by number of cities in ascending order, then your sort method should have:
for (int i = 0; i < city.length - 1; i++) {
for (int j = i + 1; j < city.length; j++) {
if (city[i].getNumberOfCities() > city[j].getNumberOfCities()) {
City temp_city = city[i];
city[i] = city[j];
city[j] = temp_city;
}
}
}
I hope this helps, but you can implement the Comparable interface or create a Comparator class following this tutorial.
EDIT: If you want to use compareto, to sort city names in ascending order:
for (int i = 0; i < city.length - 1; i++) {
for (int j = i + 1; j < city.length; j++) {
if (city[i].getName().compareTo(city[j].getName()) > 1) {
City temp_city = city[i];
city[i] = city[j];
city[j] = temp_city;
}
}
}
Assumming x, and y are strings, x.compareTo(y) gives you:
a positive number if x > y
zero if x is equal to y
a negative number if x
Documentation about this topic is really common to find in internet, but "let me google that for you".
I would suggest to understand what you want to do. Therefore I would suggest you to take a look at first, what is a sorting algorithm:
https://en.wikipedia.org/wiki/Sorting_algorithm
and then, particularly to the insertion sort algorithm:
https://en.wikipedia.org/wiki/Insertion_sort
or the selection sort:
https://en.wikipedia.org/wiki/Selection_sort
Someone can give you the answer here, but if you do not struggle with the problem, you will not learn about it and you will forget soon about it.
Hope it helps :)
This looks very much like a homework question, as the common practice is not to create your own sort algorithm.
You'll get further by attempting to design your own solution, even if it's naive, than copy/pasting whatever answer you find here.
If you really want to explore the various possible solutions (with java source code) you can follow this applet and tutorial:
https://thomas.baudel.name/Visualisation/VisuTri/
Here are the codes. But before going there I think you should watch these two videos:
insertionSort: https://www.youtube.com/watch?v=DFG-XuyPYUQ&t=142s
selectionsort: https://www.youtube.com/watch?v=f8hXR_Hvybo
public static void insertionSort(Object[] data) {
// i denotes where the partition is
for (int i = 1; i < data.length; i++) {
// the key is to the right of the partition
Object key = data[i];
int j = i - 1; // use j to scan left to insert key
while (j >= 0 && ((Comparable) key).compareTo(data[j]) < 0) {
// shift item right to make room
data[j + 1] = data[j];
j--;
}
// Found the position where key can be inserted
data[j + 1] = key;
}
}
public static void selectionSort(Object[] data) {
for (int i = 0; i < data.length - 1; i++) {
// Find the index of the minimum item, starting at `i'.
int minIndex = i;
for (int j = i + 1; j < data.length; j++) {
if (((Comparable) data[j]).compareTo(data[minIndex]) < 0)
minIndex = j;
// Exchange with the first item (at `i'), but only if different
if (i != minIndex) {
Object tmp = data[i];
data[i] = data[minIndex];
data[minIndex] = tmp;
}
}
}

Resolving method calls from generic object in enhanced for loop

This is more than likely a simple question for someone who is more familiar with Java than I am. Here's the gist of my issue:
I have a function that basically generates the possible combinations of the objects contained within an ArrayList. Being that I have multiple objects that need to use this function, the function is screaming at me to be made generic. The issue I'm encountering, though, is that an enhanced for-loop is unable to resolve method calls from the generic iterator. I understand why this happening, but I'm not familiar enough with Java to know how to resolve this issue. In any case, here is my code:
private <T> ArrayList<T> determineIdealOrderCombination(ArrayList<T> orders, int position){
// Local Variable Declarations
List<ArrayList<T>> subsets = new ArrayList<>();
int k = orders.size()+1; // Add one due to the do-while loop
int theoreticalQuantity;
int indexOfMaxProfit;
double maxProfit;
int[] s; // Here we'll keep indices pointing to elements in input array
double[] profits; // Here we'll keep track of the profit of each combination
// Begin searching for valid combinations
do {
// Setup
k--;
s = new int[k];
profits = new double[k];
// Generate combinations
if ( (k <= orders.size()) && (k > 0) ) {
// Set the first index sequence: 0, 1, 2,...
for (int i = 0; (s[i] = i) < k - 1; i++) ;
subsets.add(getSubset(orders, s));
for (; ; ) {
int i;
// Find position of item that can be incremented
for (i = k - 1; i >= 0 && s[i] == orders.size() - k + i; i--) ;
if (i < 0) {
break;
} else {
s[i]++; // increment this item
for (++i; i < k; i++) { // fill up remaining items
s[i] = s[i - 1] + 1;
}
subsets.add(getSubset(orders, s));
}
}
// All combinations have been evaluated, now throw away invalid combinations that violate the upper limit
// and calculate the valid combinations profits.
for (int i = 0; i < subsets.size(); i++) {
// Calculate the final position
theoreticalQuantity = position;
profits[i] = 0;
for (T t : subsets.get(i)) {
theoreticalQuantity += t.getQuantity(); // <-- THE PROBLEM
profits[i] += calculateProjectedProfit(t.getSecurity(), t.getQuantity(), t.getPrice()); // <-- THE PROBLEM
}
if(theoreticalQuantity > _MAX_POSITION_PER_ASSET){
// Negate profits if final position violates the position limit on an asset
profits[i] = Double.MIN_VALUE;
}
}
}
else{
break;
}
}
while( (subsets.size() == 0) );
// Verify that the subset array is not zero - it should never be zero
if(subsets.size() == 0){
return new ArrayList<>();
}
// Return the most profitable combination, if any.
indexOfMaxProfit = -1;
maxProfit = Double.MIN_VALUE;
for(int i = 0; i < profits.length; i++){
if(profits[i] != Double.MIN_VALUE){
if(profits[i] > maxProfit){
maxProfit = profits[i];
indexOfMaxProfit = i;
}
}
}
if( (maxProfit > 0) && (indexOfMaxProfit != -1) ){
return subsets.get(indexOfMaxProfit);
}
else{
return new ArrayList<>();
}
}
Any help would be appreciated.
This is how you tell the compiler that the incoming objects have the relevant methods:
public interface MyCommonInterface {
public int getQuantity();
}
private <T extends MyCommonInterface> ArrayList<T> determineIdealOrderCombination(ArrayList<T> orders, int position) {
As an additional note, i would read some tutorials on generics before attempting to use them. they are a little tricky to get the hang of initially. however, once you put out a little effort to learn the basics, you should be in a much better place to actually utilize them.

Categories