I have a challenge that I want to share with the group.
This is not homework (but I may assign it as such if I teach the appropriate
class again) and I have found one solution, so don't need anything urgent.
This is more for fun to see if others can find a better solution than I did.
The challenge:
I want to read a book in a given number of days. I want to read an integer
number of chapters each day (there are more chapters than days), no stopping
part way through a chapter, and at least 1 chapter each day. The chapters are
very non uniform in length (some very short, a few very long, many in between)
so I would like to come up with a reading schedule that minimizes the variance
of the length of the days readings (read multiple short chapters on the same
day, long chapters are the only one read that day). I also want to read through
the book in order (no skipping ahead to combine short chapters that are not
naturally next to each other.
My thought was that the optim function with method="SANN" would be an
appropriate approach, but my first couple of tries did not give very good
results. I have since come up with an optim with SANN solution that gives what
I consider good results (but I accept that better is possible).
Below is a data frame with the lengths of the chapters for the book that
originally sparked the challenge for me (but the general idea should work for
any book). Each row represents a chapter (in order) with 3 different measures
of the length of the chapter.
For this challenge I want to read the book in 128 days (there are 239 chapters).
I will post my solutions in a few days, but I want to wait so that my direction
does not influence people from trying other approaches (if there is something
better than optim, that is fine).
Good luck for anyone interested in the challenge,
The data frame:
bom3 <- structure(list(Chapter = structure(1:239, .Label = c("1 Nephi
1",
"1 Nephi 2", "1 Nephi 3", "1 Nephi 4", "1
Nephi 5", "1 Nephi 6",
"1 Nephi 7", "1 Nephi 8", "1 Nephi 9", "1
Nephi 10", "1 Nephi 11",
"1 Nephi 12", "1 Nephi 13", "1 Nephi 14", "1
Nephi 15", "1 Nephi 16",
"1 Nephi 17", "1 Nephi 18", "1 Nephi 19", "1
Nephi 20", "1 Nephi 21",
"1 Nephi 22", "2 Nephi 1", "2 Nephi 2", "2
Nephi 3", "2 Nephi 4",
"2 Nephi 5", "2 Nephi 6", "2 Nephi 7", "2
Nephi 8", "2 Nephi 9",
"2 Nephi 10", "2 Nephi 11", "2 Nephi 12", "2
Nephi 13", "2 Nephi 14",
"2 Nephi 15", "2 Nephi 16", "2 Nephi 17", "2
Nephi 18", "2 Nephi 19",
"2 Nephi 20", "2 Nephi 21", "2 Nephi 22", "2
Nephi 23", "2 Nephi 24",
"2 Nephi 25", "2 Nephi 26", "2 Nephi 27", "2
Nephi 28", "2 Nephi 29",
"2 Nephi 30", "2 Nephi 31", "2 Nephi 32", "2
Nephi 33", "Jacob 1",
"Jacob 2", "Jacob 3", "Jacob 4", "Jacob
5", "Jacob 6", "Jacob 7",
"Enos 1", "Jarom 1", "Omni 1", "Words of
Mormon 1", "Mosiah 1",
"Mosiah 2", "Mosiah 3", "Mosiah 4", "Mosiah
5", "Mosiah 6", "Mosiah 7",
"Mosiah 8", "Mosiah 9", "Mosiah 10", "Mosiah
11", "Mosiah 12",
"Mosiah 13", "Mosiah 14", "Mosiah 15",
"Mosiah 16", "Mosiah 17",
"Mosiah 18", "Mosiah 19", "Mosiah 20",
"Mosiah 21", "Mosiah 22",
"Mosiah 23", "Mosiah 24", "Mosiah 25",
"Mosiah 26", "Mosiah 27",
"Mosiah 28", "Mosiah 29", "Alma 1", "Alma
2", "Alma 3", "Alma 4",
"Alma 5", "Alma 6", "Alma 7", "Alma 8",
"Alma 9", "Alma 10",
"Alma 11", "Alma 12", "Alma 13", "Alma
14", "Alma 15", "Alma 16",
"Alma 17", "Alma 18", "Alma 19", "Alma
20", "Alma 21", "Alma 22",
"Alma 23", "Alma 24", "Alma 25", "Alma
26", "Alma 27", "Alma 28",
"Alma 29", "Alma 30", "Alma 31", "Alma
32", "Alma 33", "Alma 34",
"Alma 35", "Alma 36", "Alma 37", "Alma
38", "Alma 39", "Alma 40",
"Alma 41", "Alma 42", "Alma 43", "Alma
44", "Alma 45", "Alma 46",
"Alma 47", "Alma 48", "Alma 49", "Alma
50", "Alma 51", "Alma 52",
"Alma 53", "Alma 54", "Alma 55", "Alma
56", "Alma 57", "Alma 58",
"Alma 59", "Alma 60", "Alma 61", "Alma
62", "Alma 63", "Helaman 1",
"Helaman 2", "Helaman 3", "Helaman 4",
"Helaman 5", "Helaman 6",
"Helaman 7", "Helaman 8", "Helaman 9",
"Helaman 10", "Helaman 11",
"Helaman 12", "Helaman 13", "Helaman 14",
"Helaman 15", "Helaman 16",
"3 Nephi 1", "3 Nephi 2", "3 Nephi 3", "3
Nephi 4", "3 Nephi 5",
"3 Nephi 6", "3 Nephi 7", "3 Nephi 8", "3
Nephi 9", "3 Nephi 10",
"3 Nephi 11", "3 Nephi 12", "3 Nephi 13", "3
Nephi 14", "3 Nephi 15",
"3 Nephi 16", "3 Nephi 17", "3 Nephi 18", "3
Nephi 19", "3 Nephi 20",
"3 Nephi 21", "3 Nephi 22", "3 Nephi 23", "3
Nephi 24", "3 Nephi 25",
"3 Nephi 26", "3 Nephi 27", "3 Nephi 28", "3
Nephi 29", "3 Nephi 30",
"4 Nephi 1", "Mormon 1", "Mormon 2", "Mormon
3", "Mormon 4",
"Mormon 5", "Mormon 6", "Mormon 7", "Mormon
8", "Mormon 9", "Ether 1",
"Ether 2", "Ether 3", "Ether 4", "Ether
5", "Ether 6", "Ether 7",
"Ether 8", "Ether 9", "Ether 10", "Ether
11", "Ether 12", "Ether 13",
"Ether 14", "Ether 15", "Moroni 1", "Moroni
2", "Moroni 3", "Moroni 4",
"Moroni 5", "Moroni 6", "Moroni 7", "Moroni
8", "Moroni 9", "Moroni 10"
), class = "factor"), Words = c(908L, 879L, 1067L, 1262L, 761L,
202L, 992L, 1221L, 259L, 924L, 1315L, 860L, 1899L, 1284L, 1488L,
1618L, 2523L, 1217L, 1292L, 698L, 945L, 1506L, 1543L, 1460L,
1170L, 1300L, 1169L, 895L, 405L, 812L, 2388L, 966L, 338L, 647L,
587L, 203L, 857L, 370L, 687L, 570L, 587L, 928L, 520L, 134L, 587L,
891L, 1699L, 1483L, 1461L, 1240L, 804L, 708L, 988L, 426L, 647L,
719L, 1365L, 619L, 929L, 3758L, 511L, 1242L, 1160L, 734L, 1398L,
857L, 966L, 2112L, 1117L, 1605L, 740L, 309L, 1555L, 938L, 864L,
957L, 1271L, 1291L, 1073L, 391L, 1056L, 560L, 650L, 1382L, 978L,
963L, 1328L, 620L, 1186L, 954L, 837L, 1200L, 1601L, 812L, 1879L,
1496L, 1433L, 1016L, 1035L, 2787L, 390L, 1443L, 1231L, 1511L,
1442L, 1466L, 1858L, 1347L, 1526L, 711L, 1010L, 1848L, 1623L,
1701L, 1279L, 955L, 1871L, 764L, 1509L, 752L, 1665L, 1260L, 575L,
708L, 2666L, 1478L, 1837L, 855L, 1576L, 699L, 1229L, 2027L, 651L,
793L, 1153L, 701L, 1229L, 2221L, 1243L, 911L, 1809L, 1572L, 1073L,
1345L, 1734L, 1682L, 1757L, 1085L, 988L, 1218L, 2177L, 1517L,
1748L, 489L, 1777L, 854L, 2220L, 593L, 1418L, 599L, 1527L, 1076L,
2084L, 1797L, 1142L, 1210L, 1480L, 720L, 1561L, 873L, 1855L,
1241L, 824L, 1025L, 1340L, 769L, 1353L, 1518L, 931L, 1200L, 1132L,
871L, 965L, 807L, 1434L, 1294L, 834L, 628L, 731L, 913L, 879L,
1344L, 1233L, 1538L, 1155L, 507L, 415L, 620L, 183L, 793L, 1269L,
1457L, 394L, 130L, 1949L, 706L, 1262L, 939L, 822L, 1067L, 914L,
454L, 1710L, 1510L, 901L, 1370L, 1253L, 892L, 226L, 1048L, 899L,
1231L, 1424L, 1415L, 762L, 1536L, 1219L, 1132L, 1314L, 147L,
119L, 120L, 153L, 91L, 335L, 1929L, 1064L, 1012L, 1149L), Letters = c(3746L,
3640L, 4295L, 4968L, 3202L, 777L, 3941L, 4769L, 1075L, 3829L,
5159L, 3527L, 7874L, 5236L, 6149L, 6555L, 10180L, 4960L, 5399L,
2767L, 3758L, 6275L, 6391L, 6151L, 4685L, 5267L, 4767L, 3780L,
1574L, 3261L, 9985L, 4106L, 1332L, 2557L, 2454L, 810L, 3540L,
1406L, 2668L, 2304L, 2474L, 3715L, 2090L, 533L, 2442L, 3587L,
7294L, 6363L, 5809L, 4997L, 3197L, 2941L, 4065L, 1743L, 2539L,
3149L, 5815L, 2765L, 4027L, 15366L, 2091L, 4988L, 4730L, 3149L,
5906L, 3704L, 4188L, 8675L, 4771L, 6586L, 2965L, 1313L, 6326L,
3948L, 3489L, 3942L, 5205L, 5309L, 4300L, 1574L, 4559L, 2393L,
2655L, 5755L, 4070L, 4027L, 5649L, 2651L, 4978L, 3970L, 3610L,
5112L, 6733L, 3513L, 7990L, 6356L, 6179L, 4340L, 4432L, 11260L,
1657L, 5913L, 5033L, 6274L, 5835L, 5865L, 7802L, 5776L, 6295L,
3034L, 4383L, 7842L, 6659L, 6905L, 5104L, 4162L, 7733L, 3321L,
6241L, 3212L, 6840L, 5294L, 2471L, 2748L, 10762L, 6269L, 7479L,
3416L, 6477L, 3043L, 4719L, 8764L, 2494L, 3168L, 4790L, 2983L,
5129L, 9795L, 5043L, 3913L, 7635L, 6693L, 4669L, 5968L, 7508L,
7271L, 7543L, 4730L, 4095L, 5152L, 9129L, 6395L, 7357L, 2166L,
7512L, 3544L, 9554L, 2505L, 6171L, 2568L, 6542L, 4781L, 8655L,
7721L, 4751L, 5134L, 6032L, 3013L, 6536L, 3504L, 7527L, 5106L,
3607L, 4247L, 5524L, 3404L, 5947L, 6506L, 3891L, 5256L, 4944L,
3700L, 4006L, 3392L, 5732L, 5185L, 3402L, 2451L, 2962L, 3679L,
3550L, 5429L, 5083L, 6354L, 4659L, 2155L, 1754L, 2496L, 721L,
3326L, 4917L, 5856L, 1589L, 564L, 8300L, 2987L, 5317L, 3820L,
3595L, 4483L, 3664L, 1805L, 6931L, 6225L, 3508L, 5481L, 5007L,
3623L, 891L, 4265L, 3746L, 5041L, 5823L, 5726L, 3238L, 6443L,
5053L, 4664L, 5370L, 614L, 459L, 491L, 629L, 351L, 1457L, 7812L,
4677L, 4305L, 4603L), Verses = c(20, 24, 31, 38, 22, 6, 22, 38,
6, 22, 36, 23, 42, 30, 36, 39, 55, 25, 24, 22, 26, 31, 32, 30,
25, 35, 34, 18, 11, 25, 54, 25, 8, 22, 26, 6, 30, 13, 25, 22,
21, 34, 16, 6, 22, 32, 30, 33, 35, 32, 14, 18, 21, 9, 15, 19,
35, 14, 18, 77, 13, 27, 27, 15, 30, 18, 18, 41, 27, 30, 15, 7,
33, 21, 19, 22, 29, 37, 35, 12, 31, 15, 20, 35, 29, 26, 36, 16,
39, 25, 24, 39, 37, 20, 47, 33, 38, 27, 20, 62, 8, 27, 32, 34,
32, 46, 37, 31, 29, 19, 21, 39, 43, 36, 30, 23, 35, 18, 30, 17,
37, 30, 14, 17, 60, 38, 43, 23, 41, 16, 30, 47, 15, 19, 26, 15,
31, 54, 24, 24, 41, 36, 25, 30, 40, 37, 40, 23, 24, 35, 57, 36,
41, 13, 36, 21, 52, 17, 34, 14, 37, 26, 52, 41, 29, 28, 41, 19,
38, 26, 39, 31, 17, 25, 30, 19, 26, 33, 26, 30, 26, 25, 22, 19,
41, 48, 34, 27, 24, 20, 25, 39, 36, 46, 29, 17, 14, 18, 6, 21,
33, 39, 9, 2, 49, 19, 29, 22, 23, 24, 22, 10, 41, 37, 43, 25,
28, 19, 6, 30, 27, 26, 35, 34, 23, 41, 31, 31, 34, 4, 3, 4, 3,
2, 9, 48, 30, 26, 34)), .Names = c("Chapter", "Words",
"Letters",
"Verses"), row.names = c(NA, -239L), class = "data.frame")
--
Gregory (Greg) L. Snow Ph.D.
Statistical Data Center
Intermountain Healthcare
greg.snow at imail.org
801.408.8111
Greg
Nice problem: I wasted my whole day on it :-)
I was explaining my plan for a solution to a colleague who is a
computer scientist, he pointed out that I was trying to re-invent the
wheel known as dynamic programming. here is my code, apparently it is
called "bottom up dynamic programming". It runs pretty quickly, and
returns (what I hope is :-) the optimal sum of squares and the
cut-points.
function(X=bom3$Verses,days=128){
# find optimal BOM reading schedule for Greg Snow
# minimize variance of quantity to read per day over 128 days
#
N = length(X)
Nm1 = N-1
SSQ<- matrix(NA,nrow=days,ncol=N)
Cuts <- list()
#
# SSQ[i,j]: the ssqs about the overall mean for the optimal partition
# for i days on the chapters 1 to j
#
M = sum(X)/days
CS = cumsum(X)
SSQ[1,]= (CS-M)^2
Cuts[[1]]= as.list(1:N)
#
for(m in 2:days){
Cuts[[m]]=list()
#for(i in 1:(m-1)) Cuts[[m]][[i]] = Cuts[[m-1]][[i]]
for(n in m:N){
CS = cumsum(X[n:1])[n:1]
SSQ1 = (CS-M)^2
j = (m-1):(n-1)
TS = SSQ[m-1,j]+(SSQ1[j+1])
SSQ[m,n] = min(TS)
k = min(which((min(TS)== TS)))+m-1
Cuts[[m]][[n]] = c(Cuts[[m-1]][[k-1]],n)
}
}
list(SSQ=SSQ[days,N],Cuts=Cuts[[days]][[N]])
}
$SSQ
[1] 11241.05
$Cuts
[1] 2 4 7 9 11 13 15 16 17 19 21 23 25 27 30 31 34 37
[19] 39 41 44 46 48 50 53 56 59 60 62 64 66 68 70 73 75 77
[37] 78 80 82 84 86 88 89 91 92 94 95 96 97 99 100 103 105 106
[55] 108 110 112 113 115 117 119 121 124 125 126 127 129 131 132 135 137 138
[73] 140 141 142 144 145 146 148 150 151 152 154 156 157 160 162 163 164 166
[91] 167 169 171 173 175 177 179 181 183 185 186 188 190 192 193 194 196 199
[109] 201 204 205 207 209 211 213 214 215 217 220 222 223 225 226 228 234 236
[127] 238 239
On Tue, Jan 12, 2010 at 11:33:36AM -0700, Greg Snow
wrote:> I have a challenge that I want to share with the group.
>
> This is not homework (but I may assign it as such if I teach the
appropriate class again) and I have found one solution, so don't need
anything urgent. This is more for fun to see if others can find a better
solution than I did.
>
> The challenge:
>
> I want to read a book in a given number of days. I want to read an integer
number of chapters each day (there are more chapters than days), no stopping
part way through a chapter, and at least 1 chapter each day. The chapters are
very non uniform in length (some very short, a few very long, many in between)
so I would like to come up with a reading schedule that minimizes the variance
of the length of the days readings (read multiple short chapters on the same
day, long chapters are the only one read that day). I also want to read through
the book in order (no skipping ahead to combine short chapters that are not
naturally next to each other.
>
> My thought was that the optim function with method="SANN" would
be an appropriate approach, but my first couple of tries did not give very good
results. I have since come up with an optim with SANN solution that gives what
I consider good results (but I accept that better is possible).
>
> Below is a data frame with the lengths of the chapters for the book that
originally sparked the challenge for me (but the general idea should work for
any book). Each row represents a chapter (in order) with 3 different measures
of the length of the chapter.
>
> For this challenge I want to read the book in 128 days (there are 239
chapters).
>
> I will post my solutions in a few days, but I want to wait so that my
direction does not influence people from trying other approaches (if there is
something better than optim, that is fine).
>
> Good luck for anyone interested in the challenge,
>
> The data frame:
>
> bom3 <- structure(list(Chapter = structure(1:239, .Label = c("1
Nephi 1",
> "1 Nephi 2", "1 Nephi 3", "1 Nephi 4",
"1 Nephi 5", "1 Nephi 6",
> "1 Nephi 7", "1 Nephi 8", "1 Nephi 9",
"1 Nephi 10", "1 Nephi 11",
> "1 Nephi 12", "1 Nephi 13", "1 Nephi 14",
"1 Nephi 15", "1 Nephi 16",
> "1 Nephi 17", "1 Nephi 18", "1 Nephi 19",
"1 Nephi 20", "1 Nephi 21",
> "1 Nephi 22", "2 Nephi 1", "2 Nephi 2",
"2 Nephi 3", "2 Nephi 4",
> "2 Nephi 5", "2 Nephi 6", "2 Nephi 7",
"2 Nephi 8", "2 Nephi 9",
> "2 Nephi 10", "2 Nephi 11", "2 Nephi 12",
"2 Nephi 13", "2 Nephi 14",
> "2 Nephi 15", "2 Nephi 16", "2 Nephi 17",
"2 Nephi 18", "2 Nephi 19",
> "2 Nephi 20", "2 Nephi 21", "2 Nephi 22",
"2 Nephi 23", "2 Nephi 24",
> "2 Nephi 25", "2 Nephi 26", "2 Nephi 27",
"2 Nephi 28", "2 Nephi 29",
> "2 Nephi 30", "2 Nephi 31", "2 Nephi 32",
"2 Nephi 33", "Jacob 1",
> "Jacob 2", "Jacob 3", "Jacob 4", "Jacob
5", "Jacob 6", "Jacob 7",
> "Enos 1", "Jarom 1", "Omni 1", "Words of
Mormon 1", "Mosiah 1",
> "Mosiah 2", "Mosiah 3", "Mosiah 4",
"Mosiah 5", "Mosiah 6", "Mosiah 7",
> "Mosiah 8", "Mosiah 9", "Mosiah 10",
"Mosiah 11", "Mosiah 12",
> "Mosiah 13", "Mosiah 14", "Mosiah 15",
"Mosiah 16", "Mosiah 17",
> "Mosiah 18", "Mosiah 19", "Mosiah 20",
"Mosiah 21", "Mosiah 22",
> "Mosiah 23", "Mosiah 24", "Mosiah 25",
"Mosiah 26", "Mosiah 27",
> "Mosiah 28", "Mosiah 29", "Alma 1",
"Alma 2", "Alma 3", "Alma 4",
> "Alma 5", "Alma 6", "Alma 7", "Alma
8", "Alma 9", "Alma 10",
> "Alma 11", "Alma 12", "Alma 13", "Alma
14", "Alma 15", "Alma 16",
> "Alma 17", "Alma 18", "Alma 19", "Alma
20", "Alma 21", "Alma 22",
> "Alma 23", "Alma 24", "Alma 25", "Alma
26", "Alma 27", "Alma 28",
> "Alma 29", "Alma 30", "Alma 31", "Alma
32", "Alma 33", "Alma 34",
> "Alma 35", "Alma 36", "Alma 37", "Alma
38", "Alma 39", "Alma 40",
> "Alma 41", "Alma 42", "Alma 43", "Alma
44", "Alma 45", "Alma 46",
> "Alma 47", "Alma 48", "Alma 49", "Alma
50", "Alma 51", "Alma 52",
> "Alma 53", "Alma 54", "Alma 55", "Alma
56", "Alma 57", "Alma 58",
> "Alma 59", "Alma 60", "Alma 61", "Alma
62", "Alma 63", "Helaman 1",
> "Helaman 2", "Helaman 3", "Helaman 4",
"Helaman 5", "Helaman 6",
> "Helaman 7", "Helaman 8", "Helaman 9",
"Helaman 10", "Helaman 11",
> "Helaman 12", "Helaman 13", "Helaman 14",
"Helaman 15", "Helaman 16",
> "3 Nephi 1", "3 Nephi 2", "3 Nephi 3",
"3 Nephi 4", "3 Nephi 5",
> "3 Nephi 6", "3 Nephi 7", "3 Nephi 8",
"3 Nephi 9", "3 Nephi 10",
> "3 Nephi 11", "3 Nephi 12", "3 Nephi 13",
"3 Nephi 14", "3 Nephi 15",
> "3 Nephi 16", "3 Nephi 17", "3 Nephi 18",
"3 Nephi 19", "3 Nephi 20",
> "3 Nephi 21", "3 Nephi 22", "3 Nephi 23",
"3 Nephi 24", "3 Nephi 25",
> "3 Nephi 26", "3 Nephi 27", "3 Nephi 28",
"3 Nephi 29", "3 Nephi 30",
> "4 Nephi 1", "Mormon 1", "Mormon 2",
"Mormon 3", "Mormon 4",
> "Mormon 5", "Mormon 6", "Mormon 7",
"Mormon 8", "Mormon 9", "Ether 1",
> "Ether 2", "Ether 3", "Ether 4", "Ether
5", "Ether 6", "Ether 7",
> "Ether 8", "Ether 9", "Ether 10", "Ether
11", "Ether 12", "Ether 13",
> "Ether 14", "Ether 15", "Moroni 1",
"Moroni 2", "Moroni 3", "Moroni 4",
> "Moroni 5", "Moroni 6", "Moroni 7",
"Moroni 8", "Moroni 9", "Moroni 10"
> ), class = "factor"), Words = c(908L, 879L, 1067L, 1262L, 761L,
> 202L, 992L, 1221L, 259L, 924L, 1315L, 860L, 1899L, 1284L, 1488L,
> 1618L, 2523L, 1217L, 1292L, 698L, 945L, 1506L, 1543L, 1460L,
> 1170L, 1300L, 1169L, 895L, 405L, 812L, 2388L, 966L, 338L, 647L,
> 587L, 203L, 857L, 370L, 687L, 570L, 587L, 928L, 520L, 134L, 587L,
> 891L, 1699L, 1483L, 1461L, 1240L, 804L, 708L, 988L, 426L, 647L,
> 719L, 1365L, 619L, 929L, 3758L, 511L, 1242L, 1160L, 734L, 1398L,
> 857L, 966L, 2112L, 1117L, 1605L, 740L, 309L, 1555L, 938L, 864L,
> 957L, 1271L, 1291L, 1073L, 391L, 1056L, 560L, 650L, 1382L, 978L,
> 963L, 1328L, 620L, 1186L, 954L, 837L, 1200L, 1601L, 812L, 1879L,
> 1496L, 1433L, 1016L, 1035L, 2787L, 390L, 1443L, 1231L, 1511L,
> 1442L, 1466L, 1858L, 1347L, 1526L, 711L, 1010L, 1848L, 1623L,
> 1701L, 1279L, 955L, 1871L, 764L, 1509L, 752L, 1665L, 1260L, 575L,
> 708L, 2666L, 1478L, 1837L, 855L, 1576L, 699L, 1229L, 2027L, 651L,
> 793L, 1153L, 701L, 1229L, 2221L, 1243L, 911L, 1809L, 1572L, 1073L,
> 1345L, 1734L, 1682L, 1757L, 1085L, 988L, 1218L, 2177L, 1517L,
> 1748L, 489L, 1777L, 854L, 2220L, 593L, 1418L, 599L, 1527L, 1076L,
> 2084L, 1797L, 1142L, 1210L, 1480L, 720L, 1561L, 873L, 1855L,
> 1241L, 824L, 1025L, 1340L, 769L, 1353L, 1518L, 931L, 1200L, 1132L,
> 871L, 965L, 807L, 1434L, 1294L, 834L, 628L, 731L, 913L, 879L,
> 1344L, 1233L, 1538L, 1155L, 507L, 415L, 620L, 183L, 793L, 1269L,
> 1457L, 394L, 130L, 1949L, 706L, 1262L, 939L, 822L, 1067L, 914L,
> 454L, 1710L, 1510L, 901L, 1370L, 1253L, 892L, 226L, 1048L, 899L,
> 1231L, 1424L, 1415L, 762L, 1536L, 1219L, 1132L, 1314L, 147L,
> 119L, 120L, 153L, 91L, 335L, 1929L, 1064L, 1012L, 1149L), Letters =
c(3746L,
> 3640L, 4295L, 4968L, 3202L, 777L, 3941L, 4769L, 1075L, 3829L,
> 5159L, 3527L, 7874L, 5236L, 6149L, 6555L, 10180L, 4960L, 5399L,
> 2767L, 3758L, 6275L, 6391L, 6151L, 4685L, 5267L, 4767L, 3780L,
> 1574L, 3261L, 9985L, 4106L, 1332L, 2557L, 2454L, 810L, 3540L,
> 1406L, 2668L, 2304L, 2474L, 3715L, 2090L, 533L, 2442L, 3587L,
> 7294L, 6363L, 5809L, 4997L, 3197L, 2941L, 4065L, 1743L, 2539L,
> 3149L, 5815L, 2765L, 4027L, 15366L, 2091L, 4988L, 4730L, 3149L,
> 5906L, 3704L, 4188L, 8675L, 4771L, 6586L, 2965L, 1313L, 6326L,
> 3948L, 3489L, 3942L, 5205L, 5309L, 4300L, 1574L, 4559L, 2393L,
> 2655L, 5755L, 4070L, 4027L, 5649L, 2651L, 4978L, 3970L, 3610L,
> 5112L, 6733L, 3513L, 7990L, 6356L, 6179L, 4340L, 4432L, 11260L,
> 1657L, 5913L, 5033L, 6274L, 5835L, 5865L, 7802L, 5776L, 6295L,
> 3034L, 4383L, 7842L, 6659L, 6905L, 5104L, 4162L, 7733L, 3321L,
> 6241L, 3212L, 6840L, 5294L, 2471L, 2748L, 10762L, 6269L, 7479L,
> 3416L, 6477L, 3043L, 4719L, 8764L, 2494L, 3168L, 4790L, 2983L,
> 5129L, 9795L, 5043L, 3913L, 7635L, 6693L, 4669L, 5968L, 7508L,
> 7271L, 7543L, 4730L, 4095L, 5152L, 9129L, 6395L, 7357L, 2166L,
> 7512L, 3544L, 9554L, 2505L, 6171L, 2568L, 6542L, 4781L, 8655L,
> 7721L, 4751L, 5134L, 6032L, 3013L, 6536L, 3504L, 7527L, 5106L,
> 3607L, 4247L, 5524L, 3404L, 5947L, 6506L, 3891L, 5256L, 4944L,
> 3700L, 4006L, 3392L, 5732L, 5185L, 3402L, 2451L, 2962L, 3679L,
> 3550L, 5429L, 5083L, 6354L, 4659L, 2155L, 1754L, 2496L, 721L,
> 3326L, 4917L, 5856L, 1589L, 564L, 8300L, 2987L, 5317L, 3820L,
> 3595L, 4483L, 3664L, 1805L, 6931L, 6225L, 3508L, 5481L, 5007L,
> 3623L, 891L, 4265L, 3746L, 5041L, 5823L, 5726L, 3238L, 6443L,
> 5053L, 4664L, 5370L, 614L, 459L, 491L, 629L, 351L, 1457L, 7812L,
> 4677L, 4305L, 4603L), Verses = c(20, 24, 31, 38, 22, 6, 22, 38,
> 6, 22, 36, 23, 42, 30, 36, 39, 55, 25, 24, 22, 26, 31, 32, 30,
> 25, 35, 34, 18, 11, 25, 54, 25, 8, 22, 26, 6, 30, 13, 25, 22,
> 21, 34, 16, 6, 22, 32, 30, 33, 35, 32, 14, 18, 21, 9, 15, 19,
> 35, 14, 18, 77, 13, 27, 27, 15, 30, 18, 18, 41, 27, 30, 15, 7,
> 33, 21, 19, 22, 29, 37, 35, 12, 31, 15, 20, 35, 29, 26, 36, 16,
> 39, 25, 24, 39, 37, 20, 47, 33, 38, 27, 20, 62, 8, 27, 32, 34,
> 32, 46, 37, 31, 29, 19, 21, 39, 43, 36, 30, 23, 35, 18, 30, 17,
> 37, 30, 14, 17, 60, 38, 43, 23, 41, 16, 30, 47, 15, 19, 26, 15,
> 31, 54, 24, 24, 41, 36, 25, 30, 40, 37, 40, 23, 24, 35, 57, 36,
> 41, 13, 36, 21, 52, 17, 34, 14, 37, 26, 52, 41, 29, 28, 41, 19,
> 38, 26, 39, 31, 17, 25, 30, 19, 26, 33, 26, 30, 26, 25, 22, 19,
> 41, 48, 34, 27, 24, 20, 25, 39, 36, 46, 29, 17, 14, 18, 6, 21,
> 33, 39, 9, 2, 49, 19, 29, 22, 23, 24, 22, 10, 41, 37, 43, 25,
> 28, 19, 6, 30, 27, 26, 35, 34, 23, 41, 31, 31, 34, 4, 3, 4, 3,
> 2, 9, 48, 30, 26, 34)), .Names = c("Chapter", "Words",
"Letters",
> "Verses"), row.names = c(NA, -239L), class =
"data.frame")
>
>
> --
> Gregory (Greg) L. Snow Ph.D.
> Statistical Data Center
> Intermountain Healthcare
> greg.snow at imail.org
> 801.408.8111
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
Well, Albyn Jones gave a great solution to my challenge that found the best
reading schedule.
My original thought was that doing an exhaustive search would take too much
time, but Albyn showed that there are ways to do it efficiently.
My approach (as mentioned before) was to use optim with method SANN. I treated
it like a balls and urns problem. Since I wanted to read 239 chapters in 128
days it would be like putting 239 balls in 128 urns. I started with 1 ball in
each urn, then put the remain balls into urns to get a starting state (tried a
couple different starting situations, 1 additional ball in each of the 1st urns,
all the remaining balls in the first or last urn). Then my update step was just
to take a single ball from one of the urns with 2 or more balls and move it to
another urn at random.
On tricky thing with this method is that moving one ball could change things
quite a bit because one setup could have the longest chapters being read by
themselves, but moving one ball would result in a long chapter now being grouped
with others. My first update function just moved the ball to a random urn, then
I tried moving the ball only one urn forward or backwards (this seemed to work
better, but probably needed a longer run time). Finally the best method that I
found chose the ball to move proportional to the lengths of the days reading and
chose the urn to put it in with highest probability for days with the shortest
readings.
I thought my answers were pretty good (they looked reasonable), but Albyn's
solution had half the variance as my best result. Below is the code that I used
for my best results in case anyone is interested. I would also be interested if
anyone could find a way to improve on what I did to get better results (help me
learn SANN better, the arguments I used came mostly from trial and error).
days <- seq( as.Date('1/24/10',"%m/%d/%y"),
as.Date('5/31/10','%m/%d/%y'), by=1)
sq2.2 <- rep(1, length(days))
sq2.2[ length(days) ] <- nrow(bom3) -sum(sq2.2) + 1
genseq4 <- function(sq) {
w <- rep(1:length(days), sq)
tmp <- tapply( bom3$Verses, w, sum )
ww <- which(sq>1)
dwn <- if (length(ww) > 1) {
sample( ww, 1, prob= tmp[ww] )
} else {
ww
}
up <- sample( seq_along(sq)[-dwn], 1, prob=max(tmp) - tmp[-dwn] )
sq[dwn] <- sq[dwn] - 1
sq[up] <- sq[up] + 1
sq
}
distance <- function(sq) {
w <- rep(1:length(days), sq)
tmp <- tapply( bom3$Verses, w, sum )
var(tmp)
}
res <- optim(sq2.2, distance, genseq4, method="SANN",
control=list(maxit=30000, temp=50, trace=TRUE ))
--
Gregory (Greg) L. Snow Ph.D.
Statistical Data Center
Intermountain Healthcare
greg.snow at imail.org
801.408.8111