如何解决如何将2n表示为n个变量的总和Java实现?
| 我想知道是否有一种优雅的方法可以将2n的所有成分导出为n个非负整数变量的总和。 例如,对于n = 2个变量x和y,有5个成分分为两部分: x = 0 y = 4; x = 1 y = 3; x = 2 y = 2; x = 3 y = 1; x = 4 y = 0 这样x + y = 4 = 2n。 更一般而言,可以制定问题以将s的所有组成都找到n个非负整数变量,它们的和等于s。 任何有关如何有效计算此问题的建议都将受到欢迎,一些伪代码将不胜感激。谢谢。 编辑:虽然下面在Perl和Prolog中介绍了解决方案,但是Java实现可能会出现一个新问题,因为在递归调用期间需要传递和操纵线性数据结构(例如数组),并且随着n的获得,这种做法会变得非常昂贵更大,我想知道是否存在替代(更有效)的Java实现来解决此问题。解决方法
这是一些python:
def sumperms(n,total = None):
if total == None:
# total is the target sum,if not specified,set to 2n
total = 2 * n
if n == 1:
# if n is 1,then there is only a single permutation
# return as a tuple.
# python\'s syntax for single element tuple is (element,)
yield (total,)
return
# iterate i over 0 ... total
for i in range(total + 1):
# recursively call self to solve the subproblem
for perm in sumperms(n - 1,total - i):
# append the single element tuple to the \"sub-permutation\"
yield (i,) + perm
# run example for n = 3
for perm in sumperms(3):
print perm
输出:
(0,6)
(0,1,5)
(0,2,4)
(0,3,3)
(0,4,2)
(0,5,1)
(0,6,0)
(1,5)
(1,4)
(1,3)
(1,2)
(1,1)
(1,0)
(2,4)
(2,3)
(2,2)
(2,1)
(2,0)
(3,3)
(3,2)
(3,1)
(3,0)
(4,2)
(4,1)
(4,0)
(5,1)
(5,0)
(6,0)
,恰好在n个非负部分中的2n的合成数量(排序重要的和)为二项式系数C(3n-1,n-1)。例如,如上所述,当n = 2时,C(5,1)= 5。
要看到这一点,请考虑排列3n-1个位置。选择其中n-1个子集,然后将“ dividers”放在这些位置。然后,将剩余的空白位置分为两个分隔符之间的n个组(分隔符相邻的一些空组)。因此,您已经构造了所需组成与空间和分隔线的对应关系,并且分隔线显然被算作一次取n-1的3n-1个事物的组合。
为了列举所有可能的组成,我们可以编写一个程序,实际上从列表[1,...,3n-中选择n-1个严格增加的项s [1],...,s [n-1]。 1]。根据上述规定,对于“ i = 1,...,n”,“ parts”将为x [i] = s [i]-s [i-1]-1(按s [0]的约定) = 0且s [n] = 3n。
出于列出成分的目的,更优雅的方法是从列表[0,...,2n]中选择n-1个微增项t [1],...,t [n-1]并计算部分x [i] = t [i]-t [i-1],其中i = 1,...,n,约定t [0] = 0且t [n] = 2n。
这是一个简短的Prolog程序,它使用P个非负数部分提供了N的更一般的列表:
/* generate all possible ordered sums to N with P nonnegative parts */
composition0(N,P,List) :-
length(P,List),composition0(N,List).
composition0(N,[N]).
composition0(N,[H|T]) :-
for(H,N),M is N - H,composition0(M,T).
谓词compostion0 / 3将其第一个自变量表示为以第二个自变量为长度的非负整数列表(第三个自变量)的总和。
该定义需要一些实用程序谓词,这些谓词通常由实现提供,可能形式略有不同。为了完整性,对于/ 3的计数谓词和列表谓词的长度的Prolog定义如下:
for(H,H,N) :- H =< N.
for(H,I,N) :-
I < N,J is I+1,for(H,J,N).
length(P,List) :- length(P,List).
length(P,[ ]) :- !.
length(P,Q,[_|T]) :-
R is Q+1,length(P,R,T).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。