|
Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks. |
What do you guys think is faster?
Method 1: 1. Get all items via api call (assuming 3000 items) 2. for each item in items 2.a get item count via api call using item.id 2.b get item status via api call using item.id 3. sort items descending via item.count, return 5.
Method 2: 1. Get all items via api call (assuming 3000 items) 2. for each item in items 2.a get item count via api call using item.id 3. newItems = sort items descending via item.count take 5 4. for each item in newItems 4.a get item status via api call using item.id
I'm thinking method 2 but I just want to make sure
|
Yup, second makes more sense, cuz if you think about it:
Method 1 1 get for 3000 items (for id) 2 gets on each of those 3000 items (for count & status) 1 sort on 3000 items, look at top 5 items Return top 5 items' statuses
Method 2 1 get for 3000 items (for id) 1 get on each of those 3000 items (for count) 1 sort on 3000 items, look at top 5 items 1 get (for status) on each of these 5 items, return
The bottleneck is probably the API calls, so the fact that you're doing fewer unnecessary gets for status would probably save a lot of time. The 2995 gets for the statuses of non-top-5 items in method 1 aren't needed at all.
|
yeah, talked about it with a colleague since I'm thinking method 2 would be O(2N) while method 1 is O(N) only. Corrected me that method 2 would just be O(N+5)
|
On November 21 2016 16:15 icystorage wrote: yeah, talked about it with a colleague since I'm thinking method 2 would be O(2N) while method 1 is O(N) only. Corrected me that method 2 would just be O(N+5)
Just curious, how did you get O(2N) or O(N)? If you are using BigO notation, you don't need to keep constants.
Besides the point.
First Method: n = 3000 loop = 1 to n sort n O(N + N log N) = O(N log N)
From your original post, you want to return just the top 5 from your sorted list?
use a partition method(rselect, dselect), this should run in, log N. This will partition your data into 2 sets (a1, a2). Then your first algo runs in O(N+ log N). If you need your top 5 sorted. This is would be O(N + log N + a1 log a1) = O(N) since your N = 3000 and a1=5
|
I actually just used linq in sorting it 
We didnt take into account the notation for the sort, just talking about the loops.
|
So started looking at your second method, and I finally understand what you are doing.
So, we can subtract what's common from both. Common: Time Taken = Action 1 = api call to get items n = 1 to n loop to populate item count. n log n = sort
Different: Method 1: n = get status for items
Method 2: 5 = get status for top 5 items
So, your right, you will save time on method 2
I think you can save time on the sort. Look at quicksort partition method. Rselect is just a variation of binary search and partition. (http://analgorithmaday.blogspot.com/2011/05/randomized-selection-algorithm.html) You can do this in log N time, and would make your algorithm faster. Honestly, if your list is this small, then there is no need.
|
yeah, it's just a call from a user's twitter timeline, twitter documentation said that there's a 3200 tweet limit so I just used linq in sorting.
|
Pretty annoyed right now. My project, which I have spent a lot of time on, works perfectly visually. I have to use 3 different algorithms to solve a GUI maze. I can clearly see that my algorithms work as they should to solve the maze.
The code looks good to me. I checked and rechecked and re-rechecked.
And yet when I submit my project to the school's submit server I fail all 3 tests on the algorithm. Also i time out on a BFS test which I don't understand either. It doesn't really seem that complicated.
This is dumb. There seems to be no way to know what is going wrong. I am highly suspicious that there is actually a problem with the test server's code.
|
On November 21 2016 16:44 Neshapotamus wrote: So started looking at your second method, and I finally understand what you are doing.
So, we can subtract what's common from both. Common: Time Taken = Action 1 = api call to get items n = 1 to n loop to populate item count. n log n = sort
Different: Method 1: n = get status for items
Method 2: 5 = get status for top 5 items
So, your right, you will save time on method 2
I think you can save time on the sort. Look at quicksort partition method. Rselect is just a variation of binary search and partition. (http://analgorithmaday.blogspot.com/2011/05/randomized-selection-algorithm.html) You can do this in log N time, and would make your algorithm faster. Honestly, if your list is this small, then there is no need.
In linq, this is called a PartialSort operator
|
On November 22 2016 10:40 travis wrote:Pretty annoyed right now. My project, which I have spent a lot of time on, works perfectly visually. I have to use 3 different algorithms to solve a GUI maze. I can clearly see that my algorithms work as they should to solve the maze. The code looks good to me. I checked and rechecked and re-rechecked. And yet when I submit my project to the school's submit server I fail all 3 tests on the algorithm. Also i time out on a BFS test which I don't understand either. It doesn't really seem that complicated. This is dumb. There seems to be no way to know what is going wrong. I am highly suspicious that there is actually a problem with the test server's code. This is how I do my BFS of my graph, for example My graph has public V data; private Map<V, Connections> vertices = new HashMap<V, Connections>();
// Inner class edge defines what a vertex is class Connections {
// Each vertex has a map listing it's edges private Map<V, Integer> edges = new HashMap<V, Integer>();
public Connections() {
}
}
And my BFS does this (with some added method calls that they require that meet their exact specifications): public void bfs(V start, V end) {
Set<V> visitedSet = new HashSet<V>(); LinkedList<V> queue = new LinkedList<V>();
queue.add(start);
while (!queue.isEmpty()) { V current; current = queue.remove();
visitedSet.add(current);
for (V vertex : vertices.get(current).edges.keySet()) {
if (!visitedSet.contains(vertex)) { queue.add(vertex); } }
if (current.equals(end)) { do the ending stuff here and return }
}
I mean this is pretty straightforward right? I don't even understand what could be wrong with it. And then DFS is even more straightforward and I fail that too.
Why are you using LinkedList instead of Queue? Why do you declare the variable "V current" on a separate line? What is "V data" supposed to do?
Whatever the class V might not have implemented hashcode. Does V implement equals properly either?
Does your code work with your own input? Do you have sample input provided to you? Are you sure you're following the test specifications correctly?
|
On November 22 2016 10:40 travis wrote:Pretty annoyed right now. My project, which I have spent a lot of time on, works perfectly visually. I have to use 3 different algorithms to solve a GUI maze. I can clearly see that my algorithms work as they should to solve the maze. The code looks good to me. I checked and rechecked and re-rechecked. And yet when I submit my project to the school's submit server I fail all 3 tests on the algorithm. Also i time out on a BFS test which I don't understand either. It doesn't really seem that complicated. This is dumb. There seems to be no way to know what is going wrong. I am highly suspicious that there is actually a problem with the test server's code. This is how I do my BFS of my graph, for example My graph has public V data; private Map<V, Connections> vertices = new HashMap<V, Connections>();
// Inner class edge defines what a vertex is class Connections {
// Each vertex has a map listing it's edges private Map<V, Integer> edges = new HashMap<V, Integer>();
public Connections() {
}
}
And my BFS does this (with some added method calls that they require that meet their exact specifications): public void bfs(V start, V end) {
Set<V> visitedSet = new HashSet<V>(); LinkedList<V> queue = new LinkedList<V>();
queue.add(start);
while (!queue.isEmpty()) { V current; current = queue.remove();
visitedSet.add(current);
for (V vertex : vertices.get(current).edges.keySet()) {
if (!visitedSet.contains(vertex)) { queue.add(vertex); } }
if (current.equals(end)) { do the ending stuff here and return }
}
I mean this is pretty straightforward right? I don't even understand what could be wrong with it. And then DFS is even more straightforward and I fail that too.
Maybe your output doesn't match what they are looking for.
|
Well the thing is that I passed all the tests that tested the "setting up" of my graph (and associated maze, since it's about going through a maze). So I know the data structures are good.
And the project comes with a GUI that you can watch it go through the maze. So I can see it doing the maze.
And the project comes with included methods that you call when certain events happen, so the output is really just calling their methods.
|
Are you doing the UC Berkeley Pacman "Search" project?
|
naw ours is just start to finish of a maze and then once start to finish going through weighted paths (with djikstras)
|
On November 22 2016 11:07 Blisse wrote:Show nested quote +On November 22 2016 10:40 travis wrote:Pretty annoyed right now. My project, which I have spent a lot of time on, works perfectly visually. I have to use 3 different algorithms to solve a GUI maze. I can clearly see that my algorithms work as they should to solve the maze. The code looks good to me. I checked and rechecked and re-rechecked. And yet when I submit my project to the school's submit server I fail all 3 tests on the algorithm. Also i time out on a BFS test which I don't understand either. It doesn't really seem that complicated. This is dumb. There seems to be no way to know what is going wrong. I am highly suspicious that there is actually a problem with the test server's code. This is how I do my BFS of my graph, for example My graph has public V data; private Map<V, Connections> vertices = new HashMap<V, Connections>();
// Inner class edge defines what a vertex is class Connections {
// Each vertex has a map listing it's edges private Map<V, Integer> edges = new HashMap<V, Integer>();
public Connections() {
}
}
And my BFS does this (with some added method calls that they require that meet their exact specifications): public void bfs(V start, V end) {
Set<V> visitedSet = new HashSet<V>(); LinkedList<V> queue = new LinkedList<V>();
queue.add(start);
while (!queue.isEmpty()) { V current; current = queue.remove();
visitedSet.add(current);
for (V vertex : vertices.get(current).edges.keySet()) {
if (!visitedSet.contains(vertex)) { queue.add(vertex); } }
if (current.equals(end)) { do the ending stuff here and return }
}
I mean this is pretty straightforward right? I don't even understand what could be wrong with it. And then DFS is even more straightforward and I fail that too. Why are you using LinkedList instead of Queue? Why do you declare the variable "V current" on a separate line? What is "V data" supposed to do? Whatever the class V might not have implemented hashcode. Does V implement equals properly either? Does your code work with your own input? Do you have sample input provided to you? Are you sure you're following the test specifications correctly?
You currently only check visitedSet for duplicates, but to ensure you don't visit more than once you'd also have to check queue. Imagine the following graph:
start, a start, b a, c b, c c, end.
After visiting b (or a, whichever comes last), your data structures will have:
Visited = {start, a, b} Queue = [c, c]
You will then visit c twice, and after that will have:
Visited = {start, a, b, c} Queue = [end, end]
That might be your speed problem.
A way around it is to have a flag "visited" in your vertex objects. That way you don't have to check whether each node is already in your queue (which is O(n)). You simply add them all, but only execute the code if you didn't visit yet.
public void bfs(V start, V end) {
LinkedList<V> queue = new LinkedList<V>();
queue.add(start);
while (!queue.isEmpty()) { V current; current = queue.remove();
if(! current.visited()) {
current.visit();
for (V vertex : vertices.get(current).edges.keySet()) { queue.add(vertex); } }
if (current.equals(end)) { do the ending stuff here and return } }
I also don't see you storing your shortest path here: it will find the end, but won't know how it got there, or how many steps it takes. If that doesn't matter then all is well.
|
On November 22 2016 10:40 travis wrote: Pretty annoyed right now. My project, which I have spent a lot of time on, works perfectly visually. I have to use 3 different algorithms to solve a GUI maze. I can clearly see that my algorithms work as they should to solve the maze.
The code looks good to me. I checked and rechecked and re-rechecked.
And yet when I submit my project to the school's submit server I fail all 3 tests on the algorithm. Also i time out on a BFS test which I don't understand either. It doesn't really seem that complicated.
This is dumb. There seems to be no way to know what is going wrong. I am highly suspicious that there is actually a problem with the test server's code.
These kinds of tests usually throw funky edge-cases at your code to see if it breaks. You can't rule out a problem with the test server, but the tests themselves could be running into code branches that you haven't tested yet.
|
On November 22 2016 12:44 Acrofales wrote: You currently only check visitedSet for duplicates, but to ensure you don't visit more than once you'd also have to check queue.
It seems to me that the check is just delayed by one step. If so, that shouldn't cause a significant slowdown.
|
Don't know why your using a generic V. Use integer instead.
Visited should be a boolean array. The size of visited should be equal to the number of verticies. Make this a class level scope.
You don't have to explicitly terminate your algorithms. It will reach all the connected components by itself and complete. DFS should be implemented using recursion. Otherwise, you will have to create your own stack. This is where having visited at a class scope will help.
You bfs has a fundamental problem. *Write the for loop first *Inside the for loop, check to see if you have visited the adjacent nodes. Then mark the adjacent nodes as being visited.
Some other tips: Don't use a hashmap, use an array. (You can create an array of list<int> per index. The index of the array maps to vertex.) Create a variable called PathTo. PathTo should be a integer array; The size of PathTo array should be equal to the number of verticies. You will need this to build a complete path from source to destination.
Here is a method you should implement if you take my suggestion above: public boolean hasPathTo(int v); //run in constant time public Iterable<Integer> pathTo(int v); //use the PathTo variable and create a path
|
On November 22 2016 17:48 Hanh wrote:Show nested quote +On November 22 2016 12:44 Acrofales wrote: You currently only check visitedSet for duplicates, but to ensure you don't visit more than once you'd also have to check queue. It seems to me that the check is just delayed by one step. If so, that shouldn't cause a significant slowdown. No, the check is in fundamentally the wrong place for an efficient bfs. Think of how this will work for a chain of diamonds.
On November 22 2016 17:50 Neshapotamus wrote: Don't know why your using a generic V. Use integer instead.
Why?
Visited should be a boolean array. The size of visited should be equal to the number of verticies. Make this a class level scope.
Why?
You don't have to explicitly terminate your algorithms. It will reach all the connected components by itself and complete.
Still have to check whether you reached end or not. No need to keep searching the graph if you found your destination. Moreover, you want it to terminate differently, e.g. return true if it found end and false if it didn't. That is missing from the algorithm, I agree.
DFS should be implemented using recursion. Otherwise, you will have to create your own stack. This is where having visited at a class scope will help.
You bfs has a fundamental problem. *Write the for loop first *Inside the for loop, check to see if you have visited the adjacent nodes. Then mark the adjacent nodes as being visited.
Some other tips: Don't use a hashmap, use an array. (You can create an array of list<int> per index. The index of the array maps to vertex.)
You're making some assumptions here about the form of the input he's getting. But yes, numbering the nodes and using an array would also be a more efficient way of checking whether a node was visited than using a hashset.
Create a variable called PathTo. PathTo should be a integer array; The size of PathTo array should be equal to the number of verticies. You will need this to build a complete path from source to destination.
Here is a method you should implement if you take my suggestion above: public boolean hasPathTo(int v); //run in constant time public Iterable<Integer> pathTo(int v); //use the PathTo variable and create a path
You're assuming he has to return the path. Might all be unnecessary.
Finally, some tips regarding automated tests: Test your algorithm with null inputs. Test your algorithm with nodes that aren't null, but aren't in your graph either. Test on disconnected graphs. Think of any other input that could break your algorithm and make sure it doesn't break.
|
width = Math.ceil(width); width = Math.round(width);
Amazing...
|
|
|
|