chong you quan
singapore
|
|
|
 |
|
Jan 8, 2006
about twin prime conjecture
I'm currently thinking of a new way to solve the twin prime conjecture - but it seems I'm stuck with the equation. Since
for x ¡Ý 55 , we can define the inequality (2x+1)/(log(2x+1) - 4) - (2x-1)/(log(2x-1) + 2) > 1. If this inequality is true for infinitely number of times, then that means there are infinite twin primes. However, the opposite (2x-1)/(log(2x-1) - 4) - (2x+1)/(log(2x+1) + 2) < 1 must also be proved so as to complete the proof using this method. However, I am inclined to believe this approach does not work as I am stuck after just a few steps of expansion. On the other hand, it does not mean that approaches of this kind whereby the prime counting function is directly used to ascertain the twin prime conjecture is totally unfruitful.
Posted at 12:52 am by me_too
Permalink
Oct 8, 2005
Ro Sham Bo - Scissors paper stone
I was quite amazed to see a competition for programs to play scissors paper stone... It's called RoShamBo... and it seems there's a very good algo for playing that game... it's the winning program called iocaine powder...
It seems to work by guessing the algorithm of the other program based on previous games... pretty clever and it's amazing that it can be coded! wow...
Posted at 08:36 pm by me_too
Permalink
I realised TopCoder has a lot of resources for learning algorithms. The match editorials themselves provide a great source for learning to solve new problems.
I am almost bored of reading the Div II questions... but the Div I questions can be very challenging... only that some of them are very advance and difficult to solve.
I'm quite amazed how sometimes people can solve those type of problems within one hour... they must be supercoders... but anyway now I have no time to participate in the round matches or even practice in the practice rooms...
Posted at 12:04 pm by me_too
Permalink
I recently read about a simple way to find the maximum number of cliques in a graph :
a: for (int i = 0; i < (1<<graph.length); i++) {
for (int j = 0; j < graph.length; j++) {
if ((i & (1<<j)) != 0 && (i & graph[j]) != (i^(1<<j))) continue a;
if ((i & (1<<j)) == 0 && (i & graph[j]) == i) continue a;
}
maxcliquecount++;
}
In the above code, graph is initialized to the adjacency matrix of the graph. i represents a bitmask of which the nth bit represents whether node n is in the group of nodes to be tested.
The 1st condition tests whether any node that is in the group of nodes is not connected to every other node in the group.
The 2nd condition tests whether any node that is not in the group of nodes is connected to every other node in the group.
If either of them is true, then the group of nodes is not a maximal clique.
If the group of nodes passes all the tests, then it is a maximal clique, and the count is increased.
Maximal clique count is known to be a NP-complete problem, so this is actually a very good algorithm that requires no extra memory and is fast using bitmasks.
Amazingly, I found a webpage on solving the maximal clique (not maximal clique count) problem using DNA... it's at http://www.stanford.edu/~alexli/soco/clique.htm ... interesting ah?
Posted at 11:50 am by me_too
Permalink
Jul 20, 2004
maximum bipartite matching
maximum unweighted bipartite matching - can be solved by network flow - this is what almost every single website will say as an example for transforming a problem into a network flow problem
Well, I learnt a different technique last year. It was based on alternating paths - let us consider matching a's to b's. Start with an arbitrary but correct matching. Then starting with an unmatched a, use unmatched edges to try matching to the b's. Then, from b's back to a's using matched edges, and so continue, by alternating between matched edges and unmatched edges each time, until an unmatched b is found. By flipping the edges (matched->unmatched, unmatched-> matched), we can increase the matching by one (as both the start and end are unmatched edges). I believe this is a special case of network flow.
So I tried coding this out exactly - to just BFS every single possible alternating path. But I realised there can be so many paths that the queue would run out of memory and it was totally disastrous.
But nobody ever said that if a node on side b is visited in a queue, it doesn't have to be visited again - just store where it came from. Then the complexity of coding this BFS is much simpler and can be solved very quickly! To trace back the alternating path, just use the stored values and the matched edges.
But finally, I understood how to code this algo...
I think weighted matching can be similarly solved, each time replacing the cost difference between the matched and unmatched nodes at side b. Not much difference, but a bit more complicated that's all.
Posted at 03:15 am by me_too
Permalink
Jun 24, 2004
I think sometimes it's just hard that there are no simple sample code to look at when learning new algorithms.
Sometimes the implementation of a certain algo is tricky and difficult, though the idea may be simple.
It's just like last time during a test I tried coding a maximum bipartite matching question, but eventually it was full of bugs, when coding for the first time. And I took 2 hrs, which left no time for other questions.
Perhaps the hard way is just to code it when under no pressure...
Dp algos, once understood, are usually easy to debug and code, but more complicated ones like network flow, bipartite matching, minimum spanning tree may be harder to code on the spot. It sometimes may be just the choice of data structure representation that's hard to choose, which affects how the rest of the coding is done.
Posted at 11:25 am by me_too
Permalink
Jun 17, 2004
Wow... amazing... went for Mr Leong's lesson today...
I think his method of taking examples, careful definition, clear representation, extensive elaboration might all work when we are practising...
In actual competition we would need to think a lot faster, sometimes visualisation and clearer definition helps... of course the most needed is a clear mind...
And I finally got the hint that he was making... It about the NOI problem Q3 at http://www.comp.nus.edu.sg/~noi/tasks2004.html
I thought the best algo was DP... a O(4*k) algo... by considering all the possible permutations of how the previous row of 4 can be filled. Each square is either filled or unfilled, so a dp table of size 2^4 * k is needed, and relations between the previous state and the next state is required.
Eventually I figured out that for this case of 4 * k, only 5 out of the 16 are useful. In fact, 4 of the 16 are really neccessary. The 5 are 0011, 1100, 1001, 0110, and 1111. Since 1111 can be calculated from states 0011, 1100, 1001 from the previous row, 1111 is not really needed.
This optimisation can lead to a slightly better runtime I believe.
Then finally after the lesson I got a O(logn) algo...
It's about the same as the previous one, but just consider finding the solution for a 4 * k block with variable states of the leftmost and right most column... (with all other squares in between filled)
Then the combinations are that for a block o 4 * k, 4*(k/2) block can first be found, then combined non-overlappingly by several ways such that a 1*2 block cross from the rightmost column of the 4*(k/2) left block to the leftmost column of the 4*(k/2) right block. If k is odd, then the just find the solution for 4*((k-1)/2), then find the number of ways using the method just described, then add on to it using the previous O(4*k) algo...
With symmetry optimisation actually there are only 6 cases to calculate (instead of (2^4)^2 = 256 due to the 2 rows- leftmost and rightmost required)... Quite amazing right?
This is one of the few O(logn) dp algos I've heard of... Of course if you consider sorting as dp problems then there are many more... well the closest one is a O(nlogn) algo for maximum increasing subsequence found on Steven Halim's page... can't remember where exactly... it's about building the maximum subsequence of the first n numbers, then the next one is found by looking at that subsequence and going backwards from the last number of the subsequence until the largest number that is not smaller than it is found, then replacing that number with the new number... and that sequence grows on, in another array. The catch is that once the sequence length increases, it must be memoized so that it doesn't get lost.
And after going through Steven Halim's website I found that the O(logn) method for fibonacci numbers is described by him here : http://www.comp.nus.edu.sg/~stevenha/programming/prog_maths1.html , right at the bottom of the page.
Oh yes... just yesterday I solved 10593 Kites on acm... didn't realise it was a simple dp problem... until I read through and thought about the emails from the acm team... well as Mr Leong said : "How to find the right definition" is the most important... guess the right definition is really the most important for dp... sometimes it's quite clear, sometimes the definition is very hidden, and requires deep thoughts...
Well above are just some of my thoughts on dp... And though I agree it is not very well named, it's a really powerful and useful technique. It's just about not repeating computations, saving results, ordered computations, looking up previous results, and not solving subproblems over and over again. Once the definition is right subproblems would build up to the correct solution. Greedy is more tricky in this aspect, as one must be careful when greedy is right and applicable. I didn't really think of the airport scheduling problem as greedy until I learnt of it... and it's actually quite interesting, the proof I mean... But there are few "fun" greedy problems, compared to dp... that's why I like dp more...
Posted at 12:36 am by me_too
Permalink
Jun 15, 2004
Just tried solving some bignum problems on acm...
Realised that there are some little funny tricks to improve runtime, for bignum questions...
Following that thought of using a 10000 base, I thought : since I'm using long instead of int, for fibonacci freeze (495) I could have a 1^9 base bignum... and implementated just that on my solution, resubmitted, and my runtime improved from 1.5s to 0.4s, then following that thought I realised I could even use base 1^18, by using long long, and by doing that the runtime improved to .36 eventually...
Quite stupid right? Just using the same algo but different implementation changes runtime so much...
Anyway it has made my number of accepted solutions increase but not the number of problems solved... so I shan't really concentrate on these small little implementation details... sometimes they do matter - like in bignum, the rest of the times they don't really matter that much...
Now I see how some people can get much faster runtimes using the exact same algo... esp for bignum questions...
Posted at 05:42 pm by me_too
Permalink
There's a good website recommended by my friend : http://www.harvestsoft.net/rank.php
It finds the next 20 probably easiest problems for those solving problems from http://acm.uva.es/p
Just realised that, due to rejudging many of those problems which I've solved before appeared on that list of 20 problems...
Some problems have input size increased, some submissions got TLE, some solutions were slightly wrong that didn't take care of extreme cases...
Well so now I'm solving those problems again...
Good thing I still have the solutions which I coded last time...
Daniel's suggestion of using base 10000 for bignum actually works a lot faster than usual string manipulation... tried that for 324 (factorial frequencies)... got quite a good runtime... but not the best though...
Yesterday coded the wrap-around segment sweeping method for 10667(as suggested by Junbin, my RI senior)... well was coding for like 10hrs... with breaks of course... before it was totally correct... it is faster than the usual n^3 method for finding maximum area, but only if given the areas blocked (overlaps don't matter - taken care of).
If given the map of the area instead, it is still possible to convert to blocks in O(n^2), so overall complexity is still the same, but maybe would take more time to run...
It is possible to convert 10043 to 10667, but I think it would be very inefficient if the same algo is used... how to convert : just treat the trees as a block, and on each row and column the next row or column would be used to contain just the trees, then the next row or column is just a whole empty line... so effectively the input size is 2*n instead of n as the trees take up the other half...
So eventually I modified the code for 10667 for 10043, then got 3.6s runtime, using similar algo but with much shorter code... but the runtime is still far from the best...
Still thinking of an n^3 algo for 10043 like taking 2 points as the endpoints of a rectangle and finding whether another point is in that rectangle... if the points are sorted then it might be even easier... but haven't tried yet... not sure whether it's faster...
Now thinking of solving 495... got TLE after rejuding... can't really remember the last runtime... maybe like 29.5s???
Posted at 12:51 pm by me_too
Permalink
Jun 6, 2004
Well, seems that I've learnt a very useful method to find anything that can be expressed in the form of Xn=a1Xn-1+a2Xn-1...akXn-k, where k is a constant...
A simple matix method of the following:
(a1 a2 a3 ... ak)
(1 0 0 ... 0)
(0 1 0 ... 0)
...
(0 0 ... 1 0) |
X |
(Xn)
(Xn-1)
(Xn-2)
...
(Xn-k) |
= |
(Xn+1)
(Xn)
(Xn-1)
...
(Xn-k+1) |
Let the first matrix on the left be M, the middle one be W, and the resultant be R.
Then by matrix multiplication, M(M(M...(MW)))... = Rn, where M is multiplied n-1 times,
and by a certain matrix property, that is equal to M^n-1*W=Rn, in which M^n-1 can be evaluated in logn time by repeated squaring.
This works for any sequence in which the nth term is the sum of some multiple of each of the previous k terms (i.e the matrix contains only constants, and is of constant size)... and can be found in logn time! Quite interesting right?
One useful application is Fibonacci numbers... in logn time! I always wondered if there's a logn algo, but always depended on the O(n) one... this time finally found one that is logn...
For fibonacci, M is
(1 1)
(1 0)
W is
(1)
(0)
or anything else that the question defines...
yah!
Posted at 11:33 am by me_too
Permalink
|
|
|