home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume15 / greedy / part01 next >
Encoding:
Text File  |  1990-12-16  |  14.4 KB  |  461 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: news@usc.edu
  3. organization: RAND Corp., Santa Monica, Ca.
  4. subject: v15i083: Awk program for putting a set of files on minimum floppies.
  5. from: thomas%randvax.UUCP@usc.edu (Susan Thomas)
  6. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  7.  
  8. Posting-number: Volume 15, Issue 83
  9. Submitted-by: thomas%randvax.UUCP@usc.edu (Susan Thomas)
  10. Archive-name: greedy/part01
  11.  
  12. [Assuming I've finally figured out the latest rearrangement at uunet, I'm going
  13. to post some 30 submissions now, then notify the new moderator.  When I get
  14. confirmation form him/her, I will post anything remaining in the queue and send
  15. a message notifying the net, then redirect the aliases.  ++bsa]
  16.  
  17. (I'm posting this for a friend)
  18.  
  19. This is a awk implementation of the "greedy" bin-packing algorithm 
  20. as applied to the problem of spreading a set of files over a set 
  21. of floppies in such a way as to require the least number of
  22. floppies.  It takes a list of files and generates copying scripts
  23. which embody the optimal allocation of files.
  24.  
  25. Greedy is not the optimal algorithm.  It's just a easily implemented
  26. heuristic.
  27.  
  28. The archive contains a read.me with more information.
  29.  
  30. ---------------------------------------------------------------------------
  31. Submitted-by: ajayshah@usc.edu
  32. Archive-name: greedy/part01
  33.  
  34. ---- Cut Here and unpack ----
  35. #!/bin/sh
  36. # This is greedy, a shell archive (shar 3.32)
  37. # made 10/22/1990 07:17 UTC by ajayshah@usc.edu
  38. # Source directory /tmp/PACKING
  39. #
  40. # existing files WILL be overwritten
  41. #
  42. # This shar contains:
  43. # length  mode       name
  44. # ------ ---------- ------------------------------------------
  45. #   1691 -rw-r--r-- copying.bat.good
  46. #   1983 -rw-r--r-- lookup.table.good
  47. #   3968 -rw-r--r-- pack.awk
  48. #   1864 -rw-r--r-- read.me
  49. #   1281 -rw-r--r-- testdata
  50. #
  51. if touch 2>&1 | fgrep 'amc' > /dev/null
  52.  then TOUCH=touch
  53.  else TOUCH=true
  54. fi
  55. # ============= copying.bat.good ==============
  56. echo "x - extracting copying.bat.good (Text)"
  57. sed 's/^X//' << 'SHAR_EOF' > copying.bat.good &&
  58. X@echo off
  59. Xecho This set of files will need 3 floppies.
  60. Xecho Make sure you have so many HD formatted floppies handy.
  61. Xecho and then hit ENTER.
  62. Xpause
  63. Xecho Insert Floppy Number 1 and hit ENTER:
  64. Xpause
  65. Xcopy ./PC/C/backlog.c b:
  66. Xcopy ./PC/C/boss01.zip b:
  67. Xcopy ./PC/C/boss02a.zip b:
  68. Xcopy ./PC/C/boss02b.zip b:
  69. Xcopy ./PC/C/cc03.arc b:
  70. Xcopy ./PC/C/ccc1053b.arc b:
  71. Xcopy ./PC/C/ccc1053c.arc b:
  72. Xcopy ./PC/C/cnews005.arc b:
  73. Xcopy ./PC/C/cnews009.arc b:
  74. Xecho Insert Floppy Number 2 and hit ENTER:
  75. Xpause
  76. Xcopy ./PC/BORLAND/bgidriv.arc b:
  77. Xcopy ./PC/BORLAND/bgifont.arc b:
  78. Xcopy ./PC/BORLAND/bgifonts.arc b:
  79. Xcopy ./PC/BORLAND/bgiherc.arc b:
  80. Xcopy ./PC/BORLAND/bgvga256.arc b:
  81. Xcopy ./PC/BORLAND/tcppt1.zip b:
  82. Xcopy ./PC/C/abmake14.arc b:
  83. Xcopy ./PC/C/ansi-c.arc b:
  84. Xcopy ./PC/C/apm.arc b:
  85. Xcopy ./PC/C/boss03.zip b:
  86. Xcopy ./PC/C/bplus11.arc b:
  87. Xcopy ./PC/C/c-flow.arc b:
  88. Xcopy ./PC/C/c4window.arc b:
  89. Xcopy ./PC/C/cc01.arc b:
  90. Xcopy ./PC/C/cc02.arc b:
  91. Xcopy ./PC/C/cc04.arc b:
  92. Xcopy ./PC/C/ccc1053a.arc b:
  93. Xcopy ./PC/C/ccompile.arc b:
  94. Xcopy ./PC/C/cephes.arc b:
  95. Xcopy ./PC/C/clp_v11.arc b:
  96. Xcopy ./PC/C/cnews003.arc b:
  97. Xcopy ./PC/C/cnews004.arc b:
  98. Xcopy ./PC/C/cnews006.arc b:
  99. Xcopy ./PC/C/cnews008.arc b:
  100. Xcopy ./PC/C/cnews010.arc b:
  101. Xecho Insert Floppy Number 3 and hit ENTER:
  102. Xpause
  103. Xcopy ./PC/BORLAND/00-index.txt b:
  104. Xcopy ./PC/BORLAND/td1pat.arc b:
  105. Xcopy ./PC/C/00-index.txt b:
  106. Xcopy ./PC/C/64colors.zip b:
  107. Xcopy ./PC/C/advc11.arc b:
  108. Xcopy ./PC/C/argtest.c b:
  109. Xcopy ./PC/C/asyncpec.arc b:
  110. Xcopy ./PC/C/bituudec.c b:
  111. Xcopy ./PC/C/break.arc b:
  112. Xcopy ./PC/C/btoa.arc b:
  113. Xcopy ./PC/C/c_check.arc b:
  114. Xcopy ./PC/C/cbooks.arc b:
  115. Xcopy ./PC/C/cdecl.arc b:
  116. Xcopy ./PC/C/cnews001.arc b:
  117. Xcopy ./PC/C/cnews002.arc b:
  118. Xcopy ./PC/C/cnews007.arc b:
  119. Xecho Toodles.
  120. SHAR_EOF
  121. $TOUCH -am 1022000890 copying.bat.good &&
  122. chmod 0644 copying.bat.good ||
  123. echo "restore of copying.bat.good failed"
  124. set `wc -c copying.bat.good`;Wc_c=$1
  125. if test "$Wc_c" != "1691"; then
  126.     echo original size 1691, current size $Wc_c
  127. fi
  128. # ============= lookup.table.good ==============
  129. echo "x - extracting lookup.table.good (Text)"
  130. sed 's/^X//' << 'SHAR_EOF' > lookup.table.good &&
  131. X./PC/BORLAND/00-index.txt --> Floppy Number 3
  132. X./PC/BORLAND/bgidriv.arc --> Floppy Number 2
  133. X./PC/BORLAND/bgifont.arc --> Floppy Number 2
  134. X./PC/BORLAND/bgifonts.arc --> Floppy Number 2
  135. X./PC/BORLAND/bgiherc.arc --> Floppy Number 2
  136. X./PC/BORLAND/bgvga256.arc --> Floppy Number 2
  137. X./PC/BORLAND/tcppt1.zip --> Floppy Number 2
  138. X./PC/BORLAND/td1pat.arc --> Floppy Number 3
  139. X./PC/C/00-index.txt --> Floppy Number 3
  140. X./PC/C/64colors.zip --> Floppy Number 3
  141. X./PC/C/abmake14.arc --> Floppy Number 2
  142. X./PC/C/advc11.arc --> Floppy Number 3
  143. X./PC/C/ansi-c.arc --> Floppy Number 2
  144. X./PC/C/apm.arc --> Floppy Number 2
  145. X./PC/C/argtest.c --> Floppy Number 3
  146. X./PC/C/asyncpec.arc --> Floppy Number 3
  147. X./PC/C/backlog.c --> Floppy Number 1
  148. X./PC/C/bituudec.c --> Floppy Number 3
  149. X./PC/C/boss01.zip --> Floppy Number 1
  150. X./PC/C/boss02a.zip --> Floppy Number 1
  151. X./PC/C/boss02b.zip --> Floppy Number 1
  152. X./PC/C/boss03.zip --> Floppy Number 2
  153. X./PC/C/bplus11.arc --> Floppy Number 2
  154. X./PC/C/break.arc --> Floppy Number 3
  155. X./PC/C/btoa.arc --> Floppy Number 3
  156. X./PC/C/c-flow.arc --> Floppy Number 2
  157. X./PC/C/c4window.arc --> Floppy Number 2
  158. X./PC/C/c_check.arc --> Floppy Number 3
  159. X./PC/C/cbooks.arc --> Floppy Number 3
  160. X./PC/C/cc01.arc --> Floppy Number 2
  161. X./PC/C/cc02.arc --> Floppy Number 2
  162. X./PC/C/cc03.arc --> Floppy Number 1
  163. X./PC/C/cc04.arc --> Floppy Number 2
  164. X./PC/C/ccc1053a.arc --> Floppy Number 2
  165. X./PC/C/ccc1053b.arc --> Floppy Number 1
  166. X./PC/C/ccc1053c.arc --> Floppy Number 1
  167. X./PC/C/ccompile.arc --> Floppy Number 2
  168. X./PC/C/cdecl.arc --> Floppy Number 3
  169. X./PC/C/cephes.arc --> Floppy Number 2
  170. X./PC/C/clp_v11.arc --> Floppy Number 2
  171. X./PC/C/cnews001.arc --> Floppy Number 3
  172. X./PC/C/cnews002.arc --> Floppy Number 3
  173. X./PC/C/cnews003.arc --> Floppy Number 2
  174. X./PC/C/cnews004.arc --> Floppy Number 2
  175. X./PC/C/cnews005.arc --> Floppy Number 1
  176. X./PC/C/cnews006.arc --> Floppy Number 2
  177. X./PC/C/cnews007.arc --> Floppy Number 3
  178. X./PC/C/cnews008.arc --> Floppy Number 2
  179. X./PC/C/cnews009.arc --> Floppy Number 1
  180. X./PC/C/cnews010.arc --> Floppy Number 2
  181. SHAR_EOF
  182. $TOUCH -am 1022000890 lookup.table.good &&
  183. chmod 0644 lookup.table.good ||
  184. echo "restore of lookup.table.good failed"
  185. set `wc -c lookup.table.good`;Wc_c=$1
  186. if test "$Wc_c" != "1983"; then
  187.     echo original size 1983, current size $Wc_c
  188. fi
  189. # ============= pack.awk ==============
  190. echo "x - extracting pack.awk (Text)"
  191. sed 's/^X//' << 'SHAR_EOF' > pack.awk &&
  192. X
  193. X# This awk program packs a set of files over a set of floppies
  194. X# using the "greedy bin-packing algorithm".
  195. X
  196. X# It is hardcoded for 3.5" HD floppies being written to b:
  197. X# To change the "b:" assumption goto line 106.
  198. X# To change the 3.5" HD assumption goto lines 16-17.
  199. X
  200. XBEGIN {
  201. X    name = 1;     #
  202. X    size = 2;     #
  203. X    taken = 3;    #
  204. X    FID = 4;      #
  205. X              # Ignore these four defns.
  206. X
  207. X    FCAPACITY = 1457664;    # change this for floppies other than DSHD 3.5"
  208. X    CLUSTERSIZE = 512;    # ditto.
  209. X
  210. X    stderr = "/dev/tty";
  211. X    }
  212. X
  213. X{table[NR, name] = $1;
  214. X table[NR, size] = $2;
  215. X table[NR, taken] = 0; # 0 for not yet taken, 1 for taken.
  216. X table[NR, FID] = 0; #allocating the FID column now tends to make it faster.
  217. X
  218. X if (table[NR, size] > FCAPACITY) {
  219. X    print "File " table[NR, name] " on line " NR " is too large for one floppy.";
  220. X    goch = 1;
  221. X    exit 1
  222. X    }
  223. X}
  224. X
  225. XEND {
  226. X    if (goch == 1) exit 1;
  227. X    #So far, all that has been done is setup table.
  228. X    print "Finished reading in all data." > stderr;
  229. X
  230. X    floppy = 0;
  231. X    todo = NR;
  232. X    done = 0;
  233. X    while (done < todo) {
  234. X        # If there are more files to be done, then open a
  235. X        # new floppy.
  236. X        print "done = " done " todo = " todo > stderr;
  237. X
  238. X        floppy++; spaceleft = FCAPACITY;
  239. X        trymore = 0;
  240. X        while (trymore == 0) {
  241. X            # look for a file to put into this floppy.
  242. X            bestfile = 0; bestsize = 0;
  243. X            for (i = 1; i <= todo; i++) {
  244. X            # Linear scan over all files looking for best fit.
  245. X                if (table[i, taken] == 0) { 
  246. X                #this file has not yet been taken
  247. X                    if ((table[i, size]+CLUSTERSIZE) < spaceleft) { 
  248. X                    #this file can (in principle) fit in the slot
  249. X                        if (table[i, size] > bestsize) {
  250. X                        #this file does it better than the best 
  251. X                        #file we've found so far!
  252. X                            bestfile = i;
  253. X                            bestsize = table[i, size];
  254. X                        }
  255. X                    }
  256. X                }
  257. X            }
  258. X            #End of linear scan.
  259. X            if (bestfile == 0) {
  260. X                #we didn't find a file to fit this space
  261. X                trymore = 1 #quit trying further with this floppy
  262. X                print "Wasted space on floppy " floppy " = " spaceleft;
  263. X            }
  264. X            else {
  265. X                print "Putting file " table[bestfile, name] " of size " table[bestfile, size] " into floppy " floppy  "." > stderr;
  266. X                table[bestfile, FID] = floppy;
  267. X                table[bestfile, taken] = 1;
  268. X                spaceleft = spaceleft - table[bestfile, size] - CLUSTERSIZE;
  269. X                    # CLUSTERSIZE bytes is worstcase wastage of space
  270. X                    # with clusters of CLUSTERSIZE bytes.
  271. X                done++
  272. X            }
  273. X        }
  274. X    }
  275. X    # End of greedy algorithm.
  276. X
  277. X    # Once you land here, you've finished with all files.
  278. X    # We generate two things now:
  279. X    # First, generate the MS-DOS batch file which'll do the copying.
  280. X    # Next, generate the lookup table which maps a file into it's
  281. X    # FID (floppy ID)
  282. X
  283. X    # Printing batch file to StdOut:
  284. X    msdosbat = "copying.bat";
  285. X    print "@echo off" > msdosbat;
  286. X    print "echo This set of files will need " floppy " floppies." > msdosbat;
  287. X    print "echo Make sure you have so many HD formatted floppies handy." > msdosbat;
  288. X    print "echo and then hit ENTER." > msdosbat;
  289. X    print "pause" > msdosbat;
  290. X    for (f = 1; f <= floppy; f++) {
  291. X        # running over every floppy
  292. X        print "echo Insert Floppy Number " f " and hit ENTER:" > msdosbat; 
  293. X        print "pause" > msdosbat;
  294. X        # Now generate code for the copying:
  295. X        for (i = 1; i <= todo; i++) {
  296. X            if (table[i, FID] == f) {
  297. X                print "copy " table[i, name] " b:" > msdosbat;
  298. X            }                                    #\
  299. X        }                                          # \
  300. X    }                                                #  \__ Change this for other drives.
  301. X    print "echo Toodles." > msdosbat;
  302. X
  303. X    # Now to generate the lookup table to file "lookup.table"
  304. X    for (i = 1; i <= todo; i++) {
  305. X        print table[i, name] " --> Floppy Number " table[i, FID] > "lookup.table"
  306. X    }
  307. X
  308. X    for (i=1; i<=5; i++) print "" > stderr;
  309. X    print "I have created two files for you." > stderr;
  310. X    print "" > stderr;
  311. X    print "The file copying.bat is a MessDos batch file which does the copying." > stderr;
  312. X    print "The file lookup.table is a lookup table mapping a file to it's floppy." > stderr;
  313. X    print "" > stderr;
  314. X    print "Toodles!" > stderr;
  315. X}
  316. X
  317. SHAR_EOF
  318. $TOUCH -am 1022001690 pack.awk &&
  319. chmod 0644 pack.awk ||
  320. echo "restore of pack.awk failed"
  321. set `wc -c pack.awk`;Wc_c=$1
  322. if test "$Wc_c" != "3968"; then
  323.     echo original size 3968, current size $Wc_c
  324. fi
  325. # ============= read.me ==============
  326. echo "x - extracting read.me (Text)"
  327. sed 's/^X//' << 'SHAR_EOF' > read.me &&
  328. X
  329. XWHAT?
  330. X
  331. XThis is a awk implementation of the "greedy" bin-packing algorithm 
  332. Xas applied to the problem of spreading a set of files over a set 
  333. Xof floppies in such a way as to require the least number of
  334. Xfloppies.  It takes a list of files and generates copying scripts
  335. Xwhich embody the optimal allocation of files.
  336. X
  337. XGreedy is not the optimal algorithm.  It's just a easily implemented
  338. Xheuristic.
  339. X
  340. X---------------------------------------------------------------------------
  341. X
  342. X
  343. X
  344. XHOW?
  345. X
  346. XIt needs an input file of the form 
  347. X
  348. X./PC/BORLAND/00-index.txt 866
  349. X./PC/BORLAND/bgidriv.arc 101151
  350. X
  351. Xetc., where the first field is the filename and the 2nd field is 
  352. Xthe filesize.
  353. X
  354. XUsage:
  355. X
  356. X    nawk -f pack.awk filelist
  357. X    or
  358. X    gawk -f pack.awk filelist
  359. X
  360. XThe program talks a lot on /dev/tty about it's activities.  Finally, 
  361. Xit generates two files: a MS-DOS batch file which does the copying
  362. Xand a lookup table mapping filenames to floppy numbers.  Modifications
  363. Xon what is generated, etc., are not difficult.
  364. X
  365. XThe file 'testdata' is for demo purposes.  Try saying
  366. X
  367. X    nawk -f pack.awk testdata
  368. X
  369. XIf you want a doublecheck, then the "correct" results are files 
  370. X'copying.bat.good' and 'lookup.table.good'.
  371. X
  372. XIt does NOT work with awk; you must have either nawk or gawk.
  373. X
  374. X---------------------------------------------------------------------------
  375. X
  376. X
  377. X
  378. XIt's horrendously slow.  I only plan to be using it once in a while
  379. Xso it's fine by me.  If someone ports it to C or so, I'd like to get
  380. Xa copy!
  381. X
  382. XIf someone implements a smarter heuristic, then I'd be even more
  383. Xinterested!
  384. X
  385. X_______________________________________________________________________________
  386. XAjay Shah,    ajayshah@usc.edu                              ajayshah%rcc%rand.org
  387. XApt: (213) 734-3930                      RAND Corporation: (213) 393-0411 x7281
  388. X_______________________________________________________________________________
  389. X
  390. SHAR_EOF
  391. $TOUCH -am 1022001290 read.me &&
  392. chmod 0644 read.me ||
  393. echo "restore of read.me failed"
  394. set `wc -c read.me`;Wc_c=$1
  395. if test "$Wc_c" != "1864"; then
  396.     echo original size 1864, current size $Wc_c
  397. fi
  398. # ============= testdata ==============
  399. echo "x - extracting testdata (Text)"
  400. sed 's/^X//' << 'SHAR_EOF' > testdata &&
  401. X./PC/BORLAND/00-index.txt 866
  402. X./PC/BORLAND/bgidriv.arc 101151
  403. X./PC/BORLAND/bgifont.arc 81908
  404. X./PC/BORLAND/bgifonts.arc 87716
  405. X./PC/BORLAND/bgiherc.arc 58540
  406. X./PC/BORLAND/bgvga256.arc 28922
  407. X./PC/BORLAND/tcppt1.zip 40323
  408. X./PC/BORLAND/td1pat.arc 11443
  409. X./PC/C/00-index.txt 11904
  410. X./PC/C/64colors.zip 12382
  411. X./PC/C/abmake14.arc 62897
  412. X./PC/C/advc11.arc 14336
  413. X./PC/C/ansi-c.arc 15213
  414. X./PC/C/apm.arc 86050
  415. X./PC/C/argtest.c 1442
  416. X./PC/C/asyncpec.arc 6186
  417. X./PC/C/backlog.c 3797
  418. X./PC/C/bituudec.c 7191
  419. X./PC/C/boss01.zip 139935
  420. X./PC/C/boss02a.zip 241954
  421. X./PC/C/boss02b.zip 200308
  422. X./PC/C/boss03.zip 81988
  423. X./PC/C/bplus11.arc 22618
  424. X./PC/C/break.arc 8204
  425. X./PC/C/btoa.arc 6182
  426. X./PC/C/c-flow.arc 62706
  427. X./PC/C/c4window.arc 53248
  428. X./PC/C/c_check.arc 21504
  429. X./PC/C/cbooks.arc 12874
  430. X./PC/C/cc01.arc 4073
  431. X./PC/C/cc02.arc 93940
  432. X./PC/C/cc03.arc 117176
  433. X./PC/C/cc04.arc 113452
  434. X./PC/C/ccc1053a.arc 36508
  435. X./PC/C/ccc1053b.arc 227761
  436. X./PC/C/ccc1053c.arc 309945
  437. X./PC/C/ccompile.arc 49024
  438. X./PC/C/cdecl.arc 15088
  439. X./PC/C/cephes.arc 58368
  440. X./PC/C/clp_v11.arc 26056
  441. X./PC/C/cnews001.arc 7995
  442. X./PC/C/cnews002.arc 7393
  443. X./PC/C/cnews003.arc 25600
  444. X./PC/C/cnews004.arc 67584
  445. X./PC/C/cnews005.arc 115712
  446. X./PC/C/cnews006.arc 40020
  447. X./PC/C/cnews007.arc 13312
  448. X./PC/C/cnews008.arc 73748
  449. X./PC/C/cnews009.arc 96256
  450. X./PC/C/cnews010.arc 72437
  451. SHAR_EOF
  452. $TOUCH -am 1021235690 testdata &&
  453. chmod 0644 testdata ||
  454. echo "restore of testdata failed"
  455. set `wc -c testdata`;Wc_c=$1
  456. if test "$Wc_c" != "1281"; then
  457.     echo original size 1281, current size $Wc_c
  458. fi
  459. exit 0
  460.  
  461.