Mathematica减少/求解:要求非重复值的最佳方法

问题描述

|| 几次我发现我有一个系统,我需要指定所有变量都获得不同的值(即非重复)。 我通常这样做:
k = {a,b,c,d,e,f,g}; 
Reduce[
   a != 2 && f == a + b && g == c - d && f == (d + e)/2 && f == e + g &&
   First[And @@@ {0 < # < 8 & /@ k}] && 
   Times@(Sequence @@ (Subsets[k,{2}] /. {x_,y_} -> (x - y))) != 0,k,Integers]
约简方程的最后一部分
Times@(Sequence @@ (Subsets[k,y_} -> (x - y))) != 0
要求不同的值。 有更好的方法可以做到这一点吗? (我的意思是,不是乘积等于零,而是要指定
I need all variables different
)     

解决方法

        对于较小的问题,最好进行后期处理以除去不需要的解决方案。对于较大的问题,至少有两种有用的方法。 (1)如果允许值是连续的或接近连续的,则可以为每个原始变量和可能值的网格创建0-1变量。例如,如果您的变量旨在填充标准Sudoku数组,则x [i,j,k] = 1可用于指示第i行col j的值是k。约束例如第1行中没有重复的值将是
Sum[x[1,j,1]==1,{j,9}]
...     Sum [x [1,j,9] == 1,{j,9}] 如果不是所有位置(例如行)都需要使用所有值,则可以将这些值设为不等式。 (2)另一种方法是,如果需要区分值,则对每对使用0-1变量。我们假设值范围上至少存在一个已知的上限和下限。叫它m。因此,对于任何一对变量x和y,我们都知道-m和m之间的差异(可以在其中添加/减去变量,但不是必需的)。 对于需要区分的x [i]和x [j]对,添加新变量0-1 k [i,j]。这个想法是,如果x [i]> x [j]为1,而x [j]> x [i]为0。 对于这对,我们添加两个方程。我将以非展开形式显示它们,因为这可能会更容易理解。
x[i]-x[j] >= k[i,j] + m*(k[i,j]-1)
x[j]-x[i] >= (1-k[i,j]) + m*(-k[i,j])
如果x [i]> x [j],则仅当k [i,j] == 1时才满足。反之亦然,x [j]> x [i]和k [i.j] == 0。 当变量可以跨越的值范围实质上大于变量的数量时,或者当所有对都被约束为不同值的情况要少得多时,这可能是首选方法。 丹尼尔·里奇布劳 *这是星期六晚上,所以把我倒退的东西都倒过来。另外,请修正所有错字。     ,        从速度的角度来看,该产品条件会导致大量开销。如果您的解决方案始终是数字,则可以用solutions5ѭ生成所有解决方案,然后对其进行过滤-在某些情况下可能会更快。例如,在当前情况下:
k = {a,b,c,d,e,f,g};
sl = Reduce[ a != 2 && f == a + b && g == c - d && f == (d + e)/2 && f == e + g &&
      First[And @@@ {0 < # < 8 & /@ k}],k,Integers]
您可以进行后处理,例如这样(也许不是最好的方法):
In[21]:= Select[{#,First[k /. Solve[#,k]]} & /@ List @@ sl,MatchQ[Tally[#[[2]],Equal][[All,2]],{1 ..}] &][[All,1]]

Out[21]= {a == 3 && b == 2 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1}
至少对于这种情况,它要快得多。     ,        为什么不直接提供唯一性约束?
k = {a,g};
uniqueness = {a != b != e};
sl = Reduce[
  a != 2 && f == a + b && g == c - d && f == (d + e)/2 && f == e + g &&
    First[And @@@ {0 < # < 8 & /@ k}] && First@uniqueness,Integers]//Timing

Out[1]= {0.046791,a == 3 && b == 2 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1}
粗略地看一下上面的约束,大多数唯一性要求都会被其他约束自我满足,设置
a≠b≠e
会修复所有其余的约束。无需测试所有内容。例如
f = a + b
f ≠ a
f ≠ b
f = e + g
f ≠ e
f ≠ g
2f = d + e
f ≠ d
∵14ѭ⇒
g ≠ d
c = g + d
c ≠ g
c ≠ d
依此类推...您可能可以对其进行详细研究。 我了解这可能只是一个测试示例,并且我没有一个聪明而快速的一站式答案,而无需考虑问题即可使用。