Path: blob/master/sage/combinat/integer_vector_weighted.py
4036 views
"""1Weighted Integer Vectors2"""3#*****************************************************************************4# Copyright (C) 2007 Mike Hansen <[email protected]>,5#6# Distributed under the terms of the GNU General Public License (GPL)7#8# This code is distributed in the hope that it will be useful,9# but WITHOUT ANY WARRANTY; without even the implied warranty of10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU11# General Public License for more details.12#13# The full text of the GPL is available at:14#15# http://www.gnu.org/licenses/16#*****************************************************************************1718from combinat import CombinatorialClass19from __builtin__ import list as builtinlist20from sage.rings.integer import Integer21from sage.combinat.words.word import Word22from permutation import Permutation_class2324def WeightedIntegerVectors(n, weight):25"""26Returns the combinatorial class of integer vectors of n weighted by27weight.2829EXAMPLES::3031sage: WeightedIntegerVectors(8, [1,1,2])32Integer vectors of 8 weighted by [1, 1, 2]33sage: WeightedIntegerVectors(8, [1,1,2]).first()34[0, 0, 4]35sage: WeightedIntegerVectors(8, [1,1,2]).last()36[8, 0, 0]37sage: WeightedIntegerVectors(8, [1,1,2]).cardinality()382539sage: WeightedIntegerVectors(8, [1,1,2]).random_element()40[1, 1, 3]41"""42return WeightedIntegerVectors_nweight(n, weight)4344class WeightedIntegerVectors_nweight(CombinatorialClass):45def __init__(self, n, weight):46"""47TESTS::4849sage: WIV = WeightedIntegerVectors(8, [1,1,2])50sage: WIV == loads(dumps(WIV))51True52"""53self.n = n54self.weight = weight5556def __repr__(self):57"""58TESTS::5960sage: repr(WeightedIntegerVectors(8, [1,1,2]))61'Integer vectors of 8 weighted by [1, 1, 2]'62"""63return "Integer vectors of %s weighted by %s"%(self.n, self.weight)6465def __contains__(self, x):66"""67TESTS::6869sage: [] in WeightedIntegerVectors(0, [])70True71sage: [] in WeightedIntegerVectors(1, [])72False73sage: [3,0,0] in WeightedIntegerVectors(6, [2,1,1])74True75sage: [1] in WeightedIntegerVectors(1, [1])76True77sage: [1] in WeightedIntegerVectors(2, [2])78True79sage: [2] in WeightedIntegerVectors(4, [2])80True81sage: [2, 0] in WeightedIntegerVectors(4, [2, 2])82True83sage: [2, 1] in WeightedIntegerVectors(4, [2, 2])84False85sage: [2, 1] in WeightedIntegerVectors(6, [2, 2])86True87sage: [2, 1, 0] in WeightedIntegerVectors(6, [2, 2])88False89sage: [0] in WeightedIntegerVectors(0, [])90False91"""92if not isinstance(x, builtinlist):93return False94if len(self.weight) != len(x):95return False96s = 097for i in range(len(x)):98if not isinstance(x[i], (int, Integer)):99return False100s += x[i]*self.weight[i]101if s != self.n:102return False103104return True105106def _recfun(self, n, l):107"""108EXAMPLES::109110sage: w = WeightedIntegerVectors(3, [2,1,1])111sage: w._recfun(3, [1,1,2])112[[0, 1, 1], [1, 0, 1], [0, 3, 0], [1, 2, 0], [2, 1, 0], [3, 0, 0]]113"""114result = []115w = l[-1]116l = l[:-1]117if l == []:118d = int(n) / int(w)119if n%w == 0:120return [[d]]121else:122return [] #bad branch...123124for d in range(int(n)/int(w), -1, -1):125result += [ x + [d] for x in self._recfun(n-d*w, l) ]126127return result128129def list(self):130"""131TESTS::132133sage: WeightedIntegerVectors(7, [2,2]).list()134[]135sage: WeightedIntegerVectors(3, [2,1,1]).list()136[[1, 0, 1], [1, 1, 0], [0, 0, 3], [0, 1, 2], [0, 2, 1], [0, 3, 0]]137138::139140sage: ivw = [ WeightedIntegerVectors(k, [1,1,1]) for k in range(11) ]141sage: iv = [ IntegerVectors(k, 3) for k in range(11) ]142sage: all( [ sorted(iv[k].list()) == sorted(ivw[k].list()) for k in range(11) ] )143True144145::146147sage: ivw = [ WeightedIntegerVectors(k, [2,3,7]) for k in range(11) ]148sage: all( [ i.cardinality() == len(i.list()) for i in ivw] )149True150"""151if len(self.weight) == 0:152if self.n == 0:153return [[]]154else:155return []156157perm = Word(self.weight).standard_permutation()158l = [x for x in sorted(self.weight)]159return [perm._left_to_right_multiply_on_right(Permutation_class(x)) for x in self._recfun(self.n,l)]160161162163