Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
|
|
@ -0,0 +1,88 @@
|
|||
#lang racket
|
||||
(require net/url html xml xml/path)
|
||||
|
||||
(struct item (name mass value count) #:transparent)
|
||||
|
||||
;this section is to convert the web page on the problem into the data for the problem
|
||||
;i don't got time to manually type tables, nevermind that this took longer
|
||||
(define (group-n n l)
|
||||
(let group-n ([l l] [acc '()])
|
||||
(if (null? l)
|
||||
(reverse acc)
|
||||
(let-values ([(takes drops) (split-at l n)])
|
||||
(group-n drops (cons takes acc))))))
|
||||
(define (atom? x) (not (or (pair? x) (null? x))))
|
||||
;modified from little schemer...finds nested list where regular member would've returned non-#f
|
||||
(define (member* x t)
|
||||
(cond [(null? t) #f]
|
||||
[(atom? (car t)) (or (and (equal? (car t) x) t)
|
||||
(member* x (cdr t)))]
|
||||
[else (or (member* x (car t))
|
||||
(member* x (cdr t)))]))
|
||||
(define (addr->xexpr f) (compose xml->xexpr f read-html-as-xml get-pure-port string->url))
|
||||
(define (read-page) ((addr->xexpr cadr) "http://rosettacode.org/wiki/Knapsack_problem/Bounded"))
|
||||
(define (get-xml-table xe) (member* 'table xe))
|
||||
(define (xml-table->item-list xe-table)
|
||||
;all html table datas
|
||||
(let* ([strs (se-path*/list '(td) xe-table)]
|
||||
;4 columns per row
|
||||
[rows (group-n 4 strs)]
|
||||
;the last two rows belong to the knapsack entry which we don't want
|
||||
[rows (take rows (- (length rows) 2))])
|
||||
(for/list ([r rows])
|
||||
(let ([r (map string-trim r)])
|
||||
;convert the weight, value, and pieces columns to numbers and structify it
|
||||
(apply item (car r) (map string->number (cdr r)))))))
|
||||
;top-level function to take a string representing a URL and gives the table I didn't want to type
|
||||
(define addr->item-list (compose xml-table->item-list get-xml-table read-page))
|
||||
|
||||
;stores best solution
|
||||
(struct solution (value choices) #:transparent)
|
||||
|
||||
;finds best solution in a list of solutions
|
||||
(define (best sol-list)
|
||||
(let best ([l (cdr sol-list)] [bst (car sol-list)])
|
||||
(match l
|
||||
['() bst]
|
||||
[(cons s l) (if (> (solution-value s) (solution-value bst))
|
||||
(best l s)
|
||||
(best l bst))])))
|
||||
|
||||
;stores the choices leading to best solution...item name and # of that item taken
|
||||
(struct choice (name count) #:transparent)
|
||||
|
||||
;algorithm is derived from Haskell's array-based example
|
||||
;returns vector of solutions for every natural number capacity up to the input max
|
||||
(define (solution-vector capacity)
|
||||
;find best value and items that gave it, trying all items
|
||||
;first we set up a vector for the best solution found for every capacity
|
||||
;the best solution found at the beginning has 0 value with no items
|
||||
(for/fold ([solutions (make-vector (add1 capacity) (solution 0 '()))])
|
||||
([i (addr->item-list)])
|
||||
;the new solutions aren't accumulated until after processing all the way through a particular
|
||||
;capacity, lest capacity c allow capacity c+1 to reuse an item that had been exhausted, i.e.
|
||||
;we have to move on to the next item before we save ANY solutions found for that item, so they
|
||||
;must be saved "in parallel" by overwriting the entire vector at once
|
||||
(for/vector ([target-cap (range 0 (add1 capacity))])
|
||||
(match-let ([(item name mass value count) i])
|
||||
;find best solution for item out of every number that can be taken of that item
|
||||
;we'll call an "item and count of item" a choice
|
||||
(best (for/list ([n (range 0 (add1 count))])
|
||||
;ensure mass of this choice is not greater than target capacity
|
||||
(let ([mass-choice (* n mass)])
|
||||
(if (> mass-choice target-cap)
|
||||
(solution 0 '())
|
||||
;subtract from target capacity the amount taken up by this choice
|
||||
;use it to get the best solution for THAT capacity
|
||||
(let ([remaining-cap-solution (vector-ref solutions (- target-cap mass-choice))])
|
||||
;the new solution found adds the value of this choice to the above value and
|
||||
;adds the choice itself to the list of choices
|
||||
(solution (+ (* n value) (solution-value remaining-cap-solution))
|
||||
(cons (choice name n) (solution-choices remaining-cap-solution))))))))))))
|
||||
|
||||
;top level function to convert solution vector into single best answer
|
||||
(define (knapsack capacity)
|
||||
;the best solution is not necessarily the one that uses max capacity,
|
||||
;e.g. if max is 5 and you have items of mass 4 and 5, and the 4 is worth more
|
||||
(match-let ([(solution value choices) (best (vector->list (solution-vector capacity)))])
|
||||
(solution value (filter (compose positive? choice-count) choices))))
|
||||
Loading…
Add table
Add a link
Reference in a new issue