i trying convert following collatz conjecture algorithm from:
public class collatzconjexture { public static int calculate(int startindex, int maxsequence) { int chainlength = 0; int key = 0; bool continutecalulating = true; int longestchain = 0; int64 remainder = 0; (int = startindex; <= maxsequence; i++) { chainlength = 1; remainder = i; continutecalulating = true; while (continutecalulating) { remainder = calculatecollatzconjecture(remainder); if (remainder == 1) continutecalulating = false; chainlength += 1; } if (chainlength > longestchain) { longestchain = chainlength; key = i; } } return key; } private static int64 calculatecollatzconjecture(int64 number) { if (number % 2 == 0) return number / 2; else return (3 * number) + 1; } }
to instead use .net 4.0 parallel.for :
int chainlength = 0; int key = 0; bool continutecalulating = true; int longestchain = 0; int64 remainder = 0; int[] nums = enumerable.range(1, 1500000).toarray(); long total = 0; // use type parameter make subtotal long, not int parallel.for<int>(1, nums.length, () => 1, (j, loop, subtotal) => { remainder = j; while (continutecalulating) { remainder = calculatecollatzconjecture(remainder); if (remainder == 1) continutecalulating = false; chainlength += 1; } if (chainlength > longestchain) { longestchain = chainlength; key = j; } return key; }, (x) => interlocked.add(ref key, x) );
i have feeling i'm not far it, famous last words.
thanks in advance.
your problem don't want use parallel.for
in instance because have array (nums
) iterate over, calls parallel.foreach
. however, array created enumerable.range
, don't use anything, best way asparallel
, linq (plinq):
public static class collatzconjexture2 { public static int calculate(int startindex, int maxsequence) { var nums = enumerable.range(startindex, maxsequence); return nums.asparallel() // compute length of chain each number .select(n => new { key = n, len = collatzchainlength(n) }) // find longest chain .aggregate((max, cur) => cur.len > max.len || // make sure have lowest key longest chain max.len == cur.len && cur.key < max.key ? cur : max) // number produced longest chain .key; } private static int collatzchainlength(int64 number) { int chainlength; (chainlength = 1; number != 1; chainlength++) number = (number & 1) == 0 ? number >> 1 : number * 3 + 1; return chainlength; } }
this method twice fast on computer serial implementation. note optimized main loop computation inline rather calling function , uses bitwise math instead of multiplying , dividing. made twice fast again. compiling x64 instead of x86 made more twice fast.
Comments
Post a Comment