math.binpack: make binpacking much faster by caching total weight per bin.
parent
2a4ad0f44a
commit
c4125ad96a
|
@ -6,14 +6,10 @@ USING: help.syntax help.markup kernel assocs sequences quotations ;
|
||||||
IN: math.binpack
|
IN: math.binpack
|
||||||
|
|
||||||
HELP: binpack
|
HELP: binpack
|
||||||
{ $values { "assoc" assoc } { "n" "number of bins" } { "bins" "packed bins" } }
|
{ $values { "items" sequence } { "#bins" "number of bins" } { "bins" "packed bins" } }
|
||||||
{ $description "Packs the (key, value) pairs into the specified number of bins, using the value as a weight." } ;
|
|
||||||
|
|
||||||
HELP: binpack*
|
|
||||||
{ $values { "items" sequence } { "n" "number of bins" } { "bins" "packed bins" } }
|
|
||||||
{ $description "Packs a sequence of numbers into the specified number of bins." } ;
|
{ $description "Packs a sequence of numbers into the specified number of bins." } ;
|
||||||
|
|
||||||
HELP: binpack!
|
HELP: map-binpack
|
||||||
{ $values { "items" sequence } { "quot" quotation } { "n" "number of bins" } { "bins" "packed bins" } }
|
{ $values { "items" sequence } { "quot" { $quotation ( item -- weight ) } } { "#bins" "number of bins" } { "bins" "packed bins" } }
|
||||||
{ $description "Packs a sequence of items into the specified number of bins, using the quotation to determine the weight." } ;
|
{ $description "Packs a sequence of items into the specified number of bins, using the quotation to determine the weight." } ;
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
! Copyright (C) 2008 John Benediktsson
|
! Copyright (C) 2008 John Benediktsson
|
||||||
! See http://factorcode.org/license.txt for BSD license
|
! See http://factorcode.org/license.txt for BSD license
|
||||||
|
|
||||||
USING: kernel tools.test math.binpack ;
|
USING: kernel tools.test sequences ;
|
||||||
|
|
||||||
[ t ] [ { V{ } } { } 1 binpack = ] unit-test
|
IN: math.binpack
|
||||||
|
|
||||||
[ t ] [ { { 3 } { 2 1 } } { 1 2 3 } 2 binpack* = ] unit-test
|
{ { { } } } [ { } 1 binpack ] unit-test
|
||||||
|
|
||||||
[ t ] [ { { 1000 } { 100 60 30 7 } { 70 60 40 23 3 } }
|
{ { { 3 } { 2 1 } } } [ { 1 2 3 } 2 binpack ] unit-test
|
||||||
{ 100 23 40 60 1000 30 60 07 70 03 } 3 binpack* = ] unit-test
|
|
||||||
|
|
||||||
|
{ { { 1000 } { 100 60 30 7 } { 70 60 40 23 3 } } }
|
||||||
|
[ { 100 23 40 60 1000 30 60 07 70 03 } 3 binpack ] unit-test
|
||||||
|
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{ "violet" "orange" }
|
||||||
|
{ "indigo" "green" }
|
||||||
|
{ "yellow" "blue" "red" }
|
||||||
|
}
|
||||||
|
} [
|
||||||
|
{ "red" "orange" "yellow" "green" "blue" "indigo" "violet" }
|
||||||
|
[ length ] 3 map-binpack
|
||||||
|
] unit-test
|
||||||
|
|
|
@ -1,24 +1,36 @@
|
||||||
! Copyright (C) 2008 John Benediktsson
|
! Copyright (C) 2008 John Benediktsson
|
||||||
! See http://factorcode.org/license.txt for BSD license
|
! See http://factorcode.org/license.txt for BSD license
|
||||||
|
|
||||||
USING: sequences kernel arrays vectors accessors assocs shuffle sorting locals math math.functions ;
|
USING: arrays assocs kernel locals math math.functions sequences
|
||||||
|
sorting sorting.extras vectors fry ;
|
||||||
|
USE: accessors
|
||||||
|
|
||||||
IN: math.binpack
|
IN: math.binpack
|
||||||
|
|
||||||
: (binpack) ( bins item -- )
|
<PRIVATE
|
||||||
[ [ values sum ] map ] keep
|
|
||||||
zip sort-keys values first push ;
|
|
||||||
|
|
||||||
:: binpack ( assoc n -- bins )
|
TUPLE: bin items total ;
|
||||||
assoc sort-values <reversed> :> values
|
|
||||||
values length :> #values
|
|
||||||
n #values n / ceiling <array> [ <vector> ] map :> bins
|
|
||||||
values [ bins (binpack) ] each
|
|
||||||
bins ;
|
|
||||||
|
|
||||||
: binpack* ( items n -- bins )
|
: <bin> ( -- bin )
|
||||||
[ dup zip ] dip binpack [ keys ] map ;
|
V{ } clone 0 bin boa ; inline
|
||||||
|
|
||||||
: binpack! ( items quot n -- bins )
|
: smallest-bin ( bins -- bin )
|
||||||
[ dupd map zip ] dip binpack [ keys ] map ; inline
|
[ total>> ] infimum-by ; inline
|
||||||
|
|
||||||
|
: add-to-bin ( item bin -- )
|
||||||
|
[ items>> push ]
|
||||||
|
[ [ second ] dip [ + ] change-total drop ] 2bi ;
|
||||||
|
|
||||||
|
:: (binpack) ( alist #bins -- bins )
|
||||||
|
alist sort-values <reversed> :> items
|
||||||
|
#bins [ <bin> ] replicate :> bins
|
||||||
|
items [ bins smallest-bin add-to-bin ] each
|
||||||
|
bins [ items>> keys ] map ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: binpack ( items #bins -- bins )
|
||||||
|
[ dup zip ] dip (binpack) ;
|
||||||
|
|
||||||
|
: map-binpack ( items quot: ( item -- weight ) #bins -- bins )
|
||||||
|
[ dupd map zip ] dip (binpack) ; inline
|
||||||
|
|
Loading…
Reference in New Issue