submap a period of time - java

I'm making a info graph of my emails.
It goes quite well but things are more confusing then they have to be, for example if i want to get the amount of emails someone sended me in a month then i use this:
for (Person p : AL_persons) {
for (int y = firstYear; y <= lastYear; y++) {
for (int m = 1; m <= 12; m++) {
ArrayList<Email> emailThatMonth = new ArrayList<Email>();
for (Email e : p.emails) {
if (e.date.year().get() == y
&& e.date.monthOfYear().get() == m) {
emailThatMonth.add(e);
}
}
if (emailThatMonth.size() > maxEmailsMonth)
maxEmailsMonth = emailThatMonth.size();
}
}
}
I want to improve that so i can get it far more easy,
I was thinking of storing the first day of every month, so i can re use that.
(not tested code from here on)
ArrayList<DateTime> monthStarts = new ArrayList<DateTime>();
for (int y = firstYear; y <= lastYear; y++) {
for (int m = 1; m <= 12; m++) {
monthStarts.add(new LocalDate(y+"-"+m+"-01"));
}
}
Then to get the emails i could use a submap:
for(DateTime ld : monthStarts) {
ArrayList<Email> emailThatMonth = emails.submap(ld, ld.plusMonths(1));
}
I think this should work, however it's quite some work (not that i mind that), i just wanted to know what you guys think of it, to see if someone has tips or other ideas to deal with it.
note, i use joda time (and i love it)

The current first part looks through all the emails for each person 12*numyears times. You can simplify to only go through them once by finding the month on each email and incrementing different counters as you go. I have not tested this code since I am unsure about some specifics in your class structure.
HashMap<Person,HashMap<String,Integer>> hm = new HashMap<Person,HashMap<String,Integer>>();
for (Person p : all_persons)
{
HashMap<String,Integer> tempMap = new HashMap<String,Integer>();
for (Email e : p.emails)
{
String tag = e.date.year().get() + "-" + e.date.monthOfYear().get();
int lastvalue = tempMap.get(tag);
tempMap.put(tag, lastvalue+1);
}
hm.put(p,tempMap);
}
So for the second part(search for all emails from a given month), we take much the same approach. Iterate through once and add all matches to your new list.
String targetMonth = "2012-01";//or whatever month you're looking for
ArrayList<Email> emailThatMonth = new ArrayList<Email>();
for (Email e: emails)
{
String tag = e.date.year().get() + "-" + e.date.monthOfYear().get();
if (tag.compareToIgnoreCase(targetMonth) == 0)
emailThatMonth.add(e);
}

Related

Saving best Solution of Random Mutation Hill Climbing algorithm - Java

I am trying to save the best solution for my algorithm that prints out a solution for a binary scales problem.
My code is saving the best Fitness result (the lowest number) but it's not saving the best Scales solution (the binary code) that should be the Scales solution of the best Fitness.
public static ScalesSolution RMHC(ArrayList<Double> weights, int iter) {
if(weights == null || weights.size() == 0 || iter < 1) {
return null;
}
ScalesSolution sol = new ScalesSolution(weights.size());
ScalesSolution newSol = new ScalesSolution(sol.GetSol());
double oldSolFitness = sol.ScalesFitness(weights);
double newSolFitness = 0;
for(int i = 1; i <= iter; i++) {
newSol.SmallChange();
newSolFitness = newSol.ScalesFitness(weights);
if(newSolFitness < oldSolFitness) {
oldSolFitness = newSolFitness;
sol = new ScalesSolution(newSol.GetSol());
}
else if(newSolFitness > oldSolFitness) {
newSolFitness = oldSolFitness;
sol = new ScalesSolution(newSol.GetSol());
}
oldSolFitness = newSolFitness;
System.out.println(newSol.GetSol() + "; " + newSolFitness);
}
return sol;
}
In conclusion I want to save the Solution (binary) of the best Fitness found, instead of saving the last Solution found.
If any more info is needed please message me, thanks in advance!

jList output everything on one line

I have created a program for calculating the interest on given values. But when i calculate it, the output on the jList comes out in one line, 10 times.
Can anyone help me, and tell me why this happens :)?
From my calculate class
public ArrayList<String> calculateInterest(double years, double principal, double amount)
{
ArrayList<String> results = new ArrayList<>();
for (years = 1; years <= 10; years++)
{
amount = principal * Math.pow(rate + 1, years);
String amountToString = "" + amount;
results.add(amountToString);
}
return results;
}
´
From my GUI (Under the button)
double aar = Double.parseDouble(txtAntalAar.getText());
double belob = Double.parseDouble(txtBelob.getText());
double rente = Double.parseDouble(txtRente.getText());
ArrayList output = cal.calculateInterest(aar, belob, rente);
for (int i = 0; i < output.size(); i++)
{
myListModel.add(i, output);
}
I have also tried with:
for (String s : cal.calculateInterest(aar, rente, rente))
{
myListModel.addElement(output);
}
But same issue. Here is a photo of the output - I what them to switch line between each number:
You are adding the whole list instead of the element. Use
for (int i = 0; i < output.size(); i++)
myListModel.add(i, output.get(i));
That's because you are adding the entire ArrayList and not de item.
for (String s : cal.calculateInterest(aar, rente, rente))
{
//myListModel.addElement(output); this way you add the entire array
myListModel.addElement(s); // now you add only the item
}

Linked List Optimization

I'm working on this program that emulates restriction enzymes and DNA splicing. I'm using DnaSequenceNode[s] as linked list nodes.
I have a problem with one of the function in my code, cutSplice() is supposed to create a new DnaStrand that is a clone of the current DnaStrand, but with every instance of enzyme replaced by splicee.
For example, if the LinkedDnaStrand is instantiated with "TTGATCC", and
cutSplice("GAT", "TTAAGG") is called, then the linked list should become something like (previous pointers not shown):
first -> "TT" -> "TTAAGG" -> "CC" -> null
My function works. However, my method cutSplice() takes more than 80 seconds to splice 200 DNAs. I'm supposed to bring that 80 seconds to 2 seconds.
This is all my code for the class : LinkedDnaStrand.java
And here's the code for the method cutSplice()
public DnaStrand cutSplice(String enzyme, String splicee) {
DnaStrand newStrand = null;
String original_Dna = this.toString();
String new_Dna = original_Dna.replaceAll(enzyme, splicee);
String[] splicee_split = new_Dna.split(splicee); // splits the new DNA string DnaStrand
newStrand = null;
int i = 0;
if (original_Dna.startsWith(enzyme)) {
newStrand = new LinkedDnaStrand(splicee);
} else {
newStrand = new LinkedDnaStrand(splicee_split[0]);
newStrand.append(splicee);
}
for (i = 1; i < splicee_split.length - 1; i++) {
String node = splicee_split[i];
newStrand.append(node);
newStrand.append(splicee);
}
newStrand.append(splicee_split[splicee_split.length - 1]);
if (original_Dna.endsWith(enzyme)) {
newStrand.append(splicee);
}
return newStrand;
}
Does anybody see anything that could make a critical difference on the time this function takes to process 200 DNAs sample?
Well, it is comfortable to use the string methods, but you are losing time in converting to the string, back to sequence, and (as pointed out in the previous comments) with the regex based string functions.
It will certainly consume less time to operate on the linked list directly, although this will require you to implement the replacement algorithm yourself:
#Override
public LinkedDnaStrand cutSplice(String enzyme, String splicee)
{
LinkedDnaStrand strand = new LinkedDnaStrand();
DnaSequenceNode end = null;
DnaSequenceNode begin = top;
int pos = 0;
DnaSequenceNode tmpStart, tmpEnd;
for (DnaSequenceNode current = top; current != null; current = current.next)
{
if(current.value != enzyme.charAt(pos))
{
tmpStart = tmpEnd = new DnaSequenceNode(begin.value);
for (DnaSequenceNode n = begin.next; n != current.next; n = n.next)
{
DnaSequenceNode c = new DnaSequenceNode(n.value);
tmpEnd.next = c;
c.previous = tmpEnd;
tmpEnd = c;
}
}
else if(++pos == enzyme.length())
{
tmpStart = tmpEnd = new DnaSequenceNode(splicee.charAt(0));
for (int i = 1; i < splicee.length(); ++i)
{
DnaSequenceNode c = new DnaSequenceNode(splicee.charAt(i));
tmpEnd.next = c;
c.previous = tmpEnd;
tmpEnd = c;
}
}
else
{
continue;
}
if(end == null)
{
strand.top = end = tmpStart;
}
else
{
end.next = tmpStart;
tmpStart.previous = end;
}
end = tmpEnd;
begin = current.next;
pos = 0;
}
return strand;
}
I do not claim that there is not any opportunity to further optimize, but this should be a lot faster as the original version. I tested it successfully with the example you gave, if you yet find a bug, feel free to fix it yourself...
Note 1: I did explicitely create a new sequence from the string (instead of using the constructor) to get the end of the sequence without having to iterate over it again.
Note 2: I assumed existing a constructor DnaSequenceNode(char value) and DnaSequenceNode having a member public char value. You might have to adjust the code appropriately if any of these assumptions fails.

Where can I use threads to improve these methods?

Okay so for my project in my CSC330 class I am supposed to use threads to quickly find the answer to queries in a massive data set. Each item in the array is a user and the string is a collection of sites they visited on a website identified by number.
Example (the array is String users[])
users[1] = "1 4 5 7" users[2] = "1 2 7 17 10" users[3] = "6"
The queries are:
are there more than ___ users who looked at X
What percent of users looked at X
Are there more users who looked at X than Y
How many users viewed X ____ number of times
What percent of users looked at X more than Y
there are about a million users in this array and we had to solve the following queries without threads on a smaller scale version of the data for testing. All of mine work. Now I need to switch to the massive text file and I need to use threads to increase the speed. I'm wondering where it would be beneficial and how I could implement these threads. I will supply my code for solving each query. I'm thinking that I could use multiple threads to go through parts of the array at the same time but I'm not sure how to execute this.
public boolean query1(String num, String pageName){
if(num == null){
return false;
}
else
{
int userCount = 0;
int pageNum = convert(pageName);
System.out.println(pageNum);
String pageNumString = Integer.toString(pageNum);
System.out.println(pageNumString);
for(int i = 0; i < users.length; i++ )
{
for(String entry : users[i].split(" "))
{
if(entry.equals(pageNumString))
{
userCount++;
break;
}
}
}
if(userCount > Integer.parseInt(num)){
return false;
}
else{
return true;
}
}
}
public float query2(String pageName){
int userCount = 0;
int pageNum = convert(pageName);
String pageNumString = Integer.toString(pageNum);
for(int i = 0; i < users.length; i++ )
{
for(String entry : users[i].split(" "))
{
if(entry.equals(pageNumString))
{
userCount++;
break;
}
}
}
float percentage = (userCount*100.0f)/users.length;
return percentage;
}
public boolean query3(String pageName, String pageName2){
int userCount1 = 0;
int userCount2 = 0;
String pageNumString = Integer.toString(convert(pageName));
String pageNumString2 = Integer.toString(convert(pageName2));
for(int i = 0; i < users.length; i++ )
{
for(String entry : users[i].split(" "))
{
if(entry.equals(pageNumString))
{
userCount1++;
break;
}
}
for(String entry : users[i].split(" "))
{
if(entry.equals(pageNumString2))
{
userCount2++;
break;
}
}
}
return userCount1 > userCount2;
}
public int query4(String pageName, int numTimes){
int userCount = 0;
String pageNumString = Integer.toString(convert(pageName));
for(int i = 0; i < users.length; i++ )//runs through each user
{ int pageCount = 0;
for(String entry : users[i].split(" "))// runs through each user's pages
{
if(entry.equals(pageNumString))
{
pageCount++; // each time page is found page count increments 1
}
} // once done running through user's pages
if(pageCount == numTimes){ // check if the number of pages is equal to the number given
userCount++; // if so increment userCount
}
}
return userCount;
}
public float query5(String pageName, String pageName2){
int viewedMore = 0;
int userCount1 = 0;
int userCount2 = 0;
String pageNumString = Integer.toString(convert(pageName));
String pageNumString2 = Integer.toString(convert(pageName2));
for(int i = 0; i < users.length; i++ )
{
for(String entry : users[i].split(" ")){
userCount1 = 0;
userCount2 = 0;
if(entry.equals(pageNumString))
{
userCount1++;
break;
}
}
for(String entry : users[i].split(" "))
{
if(entry.equals(pageNumString2))
{
userCount2++;
break;
}
}
if(userCount1 > userCount2){
viewedMore++;
}
}
return viewedMore*100.0f/users.length;
}
At the very least, in query3 and query5 you can spawn off threads for each of the two inner for-loops; there's no reason they must be run sequentially. And for any of the query functions, you can certainly split the array into sections. Since your data is growing large, that approach will most likely be faster than iterating over the data with the main thread.
I would suggest providing the threads contiguous segments (e.g. index 0 to N-1; N to N+N-1 etc). This previous StackOverflow answer provides good reasoning why such an approach is most efficient. Once you get something working, you can play around with the number of threads to optimize.
edit to address your comment below
One approach would be to implement the strategy pattern, such that each of your Query are interchangeable across a client, where an executeQuery() call is the interface method. Think of having a client's call look something like
interface Query {
boolean executeQuery();
}
// client code...
Client client = new Client(...);
client.setQuery(new Query3(String num, String pageNum));
client.query(); // calls query.executeQuery();
Within the concrete Query classes, you can define individual behaviors of what the threads would do. This is a rough example:
public Query3 implements Query {
Query3(String pageNum`, String pageNum2) {
this.pageNum1=pageNum1;
this.pageNum2=pageNum2;
}
boolean executeQuery() {
for(int i = 0; i < users.length; i++ ) {
SearchThread first = new SearchThread(pageNum1);
SearchThread second = new SearchThread(pageNum2);
first.run();
second.run();
}
first.join();
second.join();
return first.userCount > second.userCount;
}
SearchThread extends Thread {
String pageNumString;
int userCount;
SearchThread(String pageNumString) {
this.pageNumString=pageNumString;
}
public void run() {
// do your search over this segment of the array, adding up userCounts
}
Here is another StackOverflow question that describes how to run multiple threads over a single array, with some boilerplate code to use.

Fill missing values on a table

I have a list of dates and prices:
Date Price
1/3/2000 10.00
1/5/2000 10.45
1/7/2000 10.25
... ...
I have a separate list of dates with all dates:
Date
1/1/2000
1/2/2000
1/3/2000
...
I need to have them combined so that the prior price is filled in for the dates that are missing prices:
Date Price
1/1/2000 10.00
1/2/2000 10.00
1/3/2000 10.00
1/4/2000 10.00
1/5/2000 10.45
1/6/2000 10.45
1/7/2000 10.25
... ...
I am currently trying to loop through array lists holding the data but can't line the dates up correctly, especially at the beginning and end. I am using Java/Mysql/JDBC right now but am open to R also. Thanks for any suggestions.
Thanks to everyone for your help. Here's what I ended up doing:
-I created a list of all indexes where the dates matched.
-I then inserted the prices into an array with the same number of elements as the full time list.
-I then created 3 loops, one for the elements before the first matching time, one for the elements after the last matching element and finally one for everything in between.
-These three filled in the prices that were missing.
Just though I'd share. Thanks for all your help.
public static void checkLengths(ArrayList<String> masterTimes, ArrayList<String> testTimes, ArrayList<Double> prices){
ArrayList<Double> temp = new ArrayList<Double>();
ArrayList<Integer> matches = new ArrayList<Integer>();
Double[] temp2 = new Double [masterTimes.size()];
int mt = masterTimes.size();
int tt = testTimes.size();
if(mt == tt){
return;
}else{
int mast = 0;
int test = 0;
String mt1 = masterTimes.get(0);
String tt1 = testTimes.get(0);
test = 0;
for(int i = 0; i < masterTimes.size(); i++){
mt1 = masterTimes.get(i);
tt1 = testTimes.get(test);
System.out.println(" | mt1: " + mt1 + " | tt1: " + tt1);
if(mt1.equals(tt1)){
matches.add(i);
System.out.println("Inserting: " + i);
if(test < testTimes.size()){
test++;
}
if(test == testTimes.size()){
break;
}
}
}
System.out.println("Matches:");
printAL(matches);
// puts in known prices.
for(int i = 0; i < matches.size(); i++){
int g = matches.get(i);
temp2[g] = prices.get(i);
}
System.out.println("FirstPrices:");
printAR(temp2);
// Finds index of first and last matching times.
int matcher1 = matches.get(0);
int ind = matches.size() - 1;
int matcher2 = matches.get(ind);
System.out.println("Matcher1:" + matcher1 + " | Matcher2: " + matcher2);
// If a price is empty/null, it puts the prior price in it.
for(int i = matcher1; i < matcher2; i ++){
System.out.println(i + " | " + temp2[i]);
if(temp2[i] == null){
System.out.println(temp2[i] + " | " + temp2[i-1]);
temp2[i] = temp2[i-1];
}
}
System.out.println("SecondPrices:");
printAR(temp2);
// Deals with start.
for(int i = matcher1; i >= 0; i--){
if(temp2[i] == null){
temp2[i] = temp2[i+1];
}
}
System.out.println("ThirdPrices:");
printAR(temp2);
// Deals with end.
for(int i = matcher2; i < temp2.length; i++){
if(temp2[i] == null){
temp2[i] = temp2[i-1];
}
}
System.out.println("FourthPrices:");
printAR(temp2);
prices.clear();
System.out.println("Final Check:");
for (int i = 0; i < masterTimes.size(); i++){
System.out.println(i + " | " + masterTimes.get(i) + " | " + temp2[i]);
}
}
}
It is difficult to help without looking at the code but it seems like your indexes are not matching up or something is wrong with your looping logic.
Consider using a HashTable or a HashMap using the date strings as keys and price as values.
Loop through your date range one day at a time look up the price in the HashTable, if not found then use the previous price.
This sort of problem does take a bit of doing to do correctly. Sometimes using a flow chart helps if you get stuck.
Try using the following sample code:
import java.sql.*;
import java.util.*;
public class FillDates
{
public static void fillUnknownDates(Connection c) throws SQLException
{
// Loads in a Vector of Strings of all the dates
Statement state = c.createStatement();
ResultSet results = state.executeQuery("SELECT d FROM Dates ORDER BY d;");
Vector<String> dates = new Vector<String>();
while (results.next())
{
dates.add(results.getString("d"));
}
// Load in a list of all date/price combinations
Vector<DatePrice> pairs = new Vector<DatePrice>();
state = c.createStatement();
results = state.executeQuery("SELECT d, p FROM DatePrices ORDER BY d;");
while (results.next())
{
pairs.add(new DatePrice(results.getString("d"), results.getString("p")));
}
// Now go through the two lists and add missing prices
state = c.createStatement();
int dateIndex = 0;
DatePrice last = pairs.get(0), current;
for (int pairIndex = 1; pairIndex < pairs.size(); pairIndex++)
{
current = pairs.get(pairIndex);
while (dateIndex < dates.size() && dates.get(dateIndex).compareTo(current.getDate()) < 0)
{
// Batch things up so it takes less time to run
state.addBatch("INSERT INTO DatePrices VALUES (\""+dates.get(dateIndex)+"\", \""+current.getPrice+"\");");
dateIndex ++;
}
last = current;
}
state.executeBatch();
}
// A convenience class
public static class DatePrice
{
private String date, price;
public DatePrice(String date, String price)
{
this.date = date;
this.price = price;
}
public String getDate()
{
return date;
}
public String getPrice()
{
return price;
}
}
}
Note that it's not complete, and you'll need to change the names of your tables and columns before trying it out.
Okay... I just shooting at it while being on the fon :)
In MySQL, let's assume you got two tables, dates_prices and all_dates. Then LEFT JOIN them on dates and order them by date.
If you use R and MySQL you can use the RMySQL package to load the resulting table to R.
In R you can convert the dates to POSIX with as.POSIXlt. You also might want to use the lagfunction in R (but I am not sure yet if that helps with lags of varying spans).
Apart from that you could use R's ´sqldf` package if you want to try with "plain" R but want to use SQL functionality. If you post some reproducible code to set up the data.. I could try to the give something more concrete back.
EDIT:
The impute package might be what you really looking for... see also here
Here is an R solution.
Uncomment the two install.packages lines if you don't have those packages already installed. Also textConnection(Lines1) and textConnection(Lines2) are just to keep the example self contained and in reality would be replaced with something like "myfile1.dat" and "myfile2.dat" assuming the data is in those files.
It reads in the data creating zoo object z and a Date vector dt. It then merges z with a zero width zoo object (i.e. it has dates but no data) whose date index is made from dt. na.locf (last observation carried forward) fills out the missing values in reverse order since fromLast = TRUE
Lines1 <- "Date Price
1/3/2000 10.00
1/5/2000 10.45
1/7/2000 10.25"
Lines2 <- "Date
1/1/2000
1/2/2000
1/3/2000"
# install.packages("zoo")
# install.packages("chron")
library(zoo)
library(chron)
z <- read.zoo(textConnection(Lines1), header = TRUE, FUN = as.chron)
dt <- as.chron(scan(textConnection(Lines2), skip = 1, what = ""))
na.locf(merge(z, zoo(, dt)), fromLast = TRUE)
The result is:
> na.locf(merge(z, zoo(, dt)), fromLast = TRUE)
01/01/00 01/02/00 01/03/00 01/05/00 01/07/00
10.00 10.00 10.00 10.45 10.25
There are three vignettes (PDF documents) that come with the zoo package and R News 4/1 Help Desk article has info and references on dates.

Categories

Resources