python - Cocoa - maximum depth for nested loops? -
i trying write algorithm locates possible solutions choosing 10 values 10x10 grid. no 2 values can share same row or column. there 10! combinations (just on 3,600,000).
my initial algorithm uses 10 nested loops , checks each possible combination of 10 squares. when try run app on macbook takes many, many minutes relieve boredom log each test console, way can watch tests rack up.
the problem app runs until test number 714271 , freezes. result repeatable.
i assume it's memory thing , counter somewhere exceeding max allowed value number has no significance when google it.
code looks this:
-(ibaction)findsolutions:(id)sender{ nsmutablearray* flags = [[nsmutablearray alloc]initwithobjects:[nsnumber numberwithint:0], [nsnumber numberwithint:0], [nsnumber numberwithint:0], [nsnumber numberwithint:0], [nsnumber numberwithint:0], [nsnumber numberwithint:0], [nsnumber numberwithint:0], [nsnumber numberwithint:0], [nsnumber numberwithint:0], [nsnumber numberwithint:0], nil]; nsmutablestring* solutionsstring = [[nsmutablestring alloc]init]; int a,b,c,d,e,f,g,h,i,j,z,sum; for(a=0;a<=9;a++){ for(b=0;b<=9;b++){ for(c=0;c<=9;c++){ for(d=0;d<=9;d++){ for(e=0;e<=9;e++){ for(f=0;f<=9;f++){ for(g=0;g<=9;g++){ for(h=0;h<=9;h++){ for(i=0;i<=9;i++){ for(j=0;j<=9;j++){ for(z=0;z<=9;z++){ [flags replaceobjectatindex:z withobject:[nsnumber numberwithint:0]]; } //clear flags matrix //load flags matrix [flags replaceobjectatindex:a withobject:[nsnumber numberwithint:1]]; [flags replaceobjectatindex:b withobject:[nsnumber numberwithint:1]]; [flags replaceobjectatindex:c withobject:[nsnumber numberwithint:1]]; [flags replaceobjectatindex:d withobject:[nsnumber numberwithint:1]]; [flags replaceobjectatindex:e withobject:[nsnumber numberwithint:1]]; [flags replaceobjectatindex:f withobject:[nsnumber numberwithint:1]]; [flags replaceobjectatindex:g withobject:[nsnumber numberwithint:1]]; [flags replaceobjectatindex:h withobject:[nsnumber numberwithint:1]]; [flags replaceobjectatindex:i withobject:[nsnumber numberwithint:1]]; [flags replaceobjectatindex:j withobject:[nsnumber numberwithint:1]]; sum = 0; for(z=0;z<=9;z++){ sum = sum + [[flags objectatindex:z]intvalue]; } // sum flags matrix. = 10 if columns filled if (sum == 10) { nslog(@"test no. %d, sum=%d, a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d",y,sum,a,b,c,d,e,f,g,h,i,j); [solutionsstring appendstring:[nsstring stringwithformat:@"test no. %d, sum=%d, a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d",y,sum,a,b,c,d,e,f,g,h,i,j]]; [txtsolutionsfound setstringvalue:solutionsstring]; } // these possible solutions nslog(@"a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d",a,b,c,d,e,f,g,h,i,j); } } } } } } } } } } } final update have confession make. gave trying code work in obj-c , rewrote in python. has been running couple of hours, checked 1.2 billion of 10^10 combinations, has not clagged system memory , on average using 50% less cpu time obj-c code. love of cocoa apps , creation of ui brilliant sheer workability, python hard beat.
python code looks like:
row0 = [164,116,106,76,122,46,109,86,7,134] row1 = [70,170,108,25,182,77,134,192,60,26] row2 = [14,108,140,130,90,46,6,154,168,90] row3 = [138,48,130,127,54,2,112,78,76,98] row4 = [86,65,110,22,64,82,46,62,146,94] row5 = [70,194,20,152,76,162,54,98,122,50] row6 = [91,0,116,230,32,138,203,175,104,88] row7 = [68,222,87,124,99,209,28,147,108,72] row8 = [51,85,74,40,132,98,118,159,70,44] row9 = [30,122,92,190,8,77,152,7,106,70] maxvalue = 0 flagmatrix = [0,0,0,0,0,0,0,0,0,0] solutionmatrix = [0,0,0,0,0,0,0,0,0,0] in range(0,10): b in range(0,10): c in range(0,10): d in range(0,10): e in range(0,10): f in range(0,10): g in range(0,10): h in range(0,10): in range(0,10): j in range(0,10): z in range(0,10): flagmatrix[z]=0 #this clear flag matrix #now load matrix flagmatrix[a]=1 flagmatrix[b]=1 flagmatrix[c]=1 flagmatrix[d]=1 flagmatrix[e]=1 flagmatrix[f]=1 flagmatrix[g]=1 flagmatrix[h]=1 flagmatrix[i]=1 flagmatrix[j]=1 sum=0 flag in flagmatrix: sum = sum+flag if sum == 10: print "solution found @ ",a,b,c,d,e,f,g,h,i,j solution = row0[a]+row1[b]+row2[c]+row3[d]+row4[e]+row5[f]+row6[g]+row7[h]+row8[i]+row9[j] print "solution = ", solution if solution > maxvalue: maxvalue = solution solutionmatrix[1]=b solutionmatrix[2]=c solutionmatrix[3]=d solutionmatrix[4]=e solutionmatrix[5]=f solutionmatrix[6]=g solutionmatrix[7]=h solutionmatrix[8]=i solutionmatrix[9]=j print "current maxvalue = ", maxvalue print "final max value = ", maxvalue print "final solution matrix = ", solutionmatrix
i ran code, and, within few minutes, began enter paging hell.
now, in command-line version of program. had removed creation of temporary nsstrings , nslog every test, , had not yet encountered nslog successful test. objects version created nsnumbers, and, mentioned in comment on mustisignup's answer, nsnumber objects not pile because create 2 of them—nsnumber objects interned, every time apparently create nsnumber object, reusing object created.
so seeing program consume ton of memory odd.
the next step when program consumes ton of memory run under instruments, using leaks template. that's did. took heapshot every few seconds, , instruments reported 5–12 mb of memory growth each time.
looking @ contents of 1 of heapshots (showing had been allocated since previous one), found non-object memory. looking @ stack trace 1 allocation, found allocated by… autorelease, called apparently directly main.
double-clicking on main stack frame, took me 1 of “creations” of nsnumber object. this, inferred although reuses existing objects, retains , autoreleases them.
as documented, objects respond autorelease adding autorelease pool. that's significant because autorelease pool, @ heart, mutable array (that releases of contents when gets drained). ordinarily, doesn't count because total size of objects far outweighs displacement, speak, in pool, in case, have 2 objects adding pool millions of times each on life of program.
the solution hoist “creation” expressions out of code variable declarations:
nsnumber *zero = [nsnumber numberwithint:0]; nsnumber *one = [nsnumber numberwithint:1]; and replace them everywhere they'd formerly appeared uses of variables. program's still dog slow, memory usage flat.
i have no idea whether that's relevant problem, maybe is, , @ rate, it's necessary improvement.
also, nslog writes system log, goes disk. consider logging nstextview instead, or drawing grid , marked places in custom view. you'll have break code not single long-running loop, that's necessary improvement anyway—it's you'll need learn anyway, , practice case.
Comments
Post a Comment