标题:解限制条件下线性不定方程的解组数
只看楼主
jklqwe111
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:35
帖 子:335
专家分:1125
注 册:2014-4-13
得分:0 
我认为这个题目就是一个计数问题,解决这类问题最基本的方法就是枚举了,如果没有限制条件,那么就可以用组合的方法计算,循环迭代或者递归,其实就是枚举,写出程序不难关键在于找到优化的方法,下面的代码是递归程序,只有一些优化,没有找到更好的优化方法  6 数相加和值100 模 3 用时 0.24秒 和 200  用时 3.1 秒 和 300 用时 15.5 秒
Public Function nums1ModK(ByVal sum As Long, ByVal number As Long, ByVal ModK As Long)
  Dim n As Long
  Dim r As Long
  Dim i As Long
  Dim j As Long
   Dim k As Long
  Dim str As String
  
  If sum < number Then
      nums1ModK = 0
      Exit Function
     
   End If
     
     
  
  If number = 2 Then
      nums1ModK = sum - 1
      n = (sum - 1) \ ModK '需要过滤的个数
      r = sum Mod ModK
      If r = 0 Then 'sum能被整除
         nums1ModK = nums1ModK - n '当sum能被整除时,两个变量必定同被整除或同式不被整除,那么两个同被整除变量要剪掉两个解的个数
      Else
         nums1ModK = nums1ModK - n * 2
      End If
      
      
      Exit Function
  End If
  
  Dim s As Long
  nums1ModK = 0
 
  For s = 1 To sum - (number - 1)
     If (s Mod ModK) <> 0 Then
         
         nums1ModK = nums1ModK + nums1ModK(sum - s, number - 1, ModK)
     End If
  Next
End Function

2022-11-19 11:10
jklqwe111
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:35
帖 子:335
专家分:1125
注 册:2014-4-13
得分:0 
这道题可以使用生成函数来解决,但是这个模型计算量与枚举法等同,只是比较容易找到优化的方法,比如保存中间计算结果,空间换时间,下面计算程序用三个数组保存中间结果,效果很明显,计算速度很快

 6 数相加和值100 模 3 用时 0.00724秒 和 200  用时 0.051 秒 和 300 用时 0.07 秒

Public Function numsModK(ByVal sum As Long, ByVal number As Long, ByVal ModN As Long)
   '多项式乘的展开式中幂等于sum 的系数(x^1+ ...+x^k )^number (k=iif(k mod ModK =0,0,k) k<=sum-(number-1))
   Dim c() As Long
   
   Dim a() As Long
  
   Dim b() As Long
  
   Dim n As Long
   Dim k As Long
   Dim i As Long
   Dim j As Long
    Dim u(1) As Variant
   
   Dim v1 As Long
   Dim v2 As Long
   Dim tmp As Long
   ReDim c(1 To sum)
   
   ReDim a(1 To sum)
   
   ReDim b(1 To sum)
  
   
   
   For n = 1 To sum
     If (n Mod ModN) = 0 Then
        a(n) = 0
        
        b(n) = 0
        
      Else
        a(n) = 1
            
        b(n) = 1
      End If
     Next
     v1 = 0
     v2 = 1
     u(v1) = b
   
     u(v2) = c
     For k = 2 To number
       For n = 1 To sum
         u(v2)(n) = 0
       Next
       For i = 1 To sum - (number - 1)
              
              For j = 1 To sum - 1
               
                   If i + j <= sum Then
                      u(v2)(i + j) = u(v2)(i + j) + u(v1)(j) * a(i)
                   Else
                      Exit For
                   End If
               
              Next
                        
      Next
      v1 = v1 Xor 1&
      v2 = v2 Xor 1&
     
     Next
   
  numsModK = u(v1)(sum)
 
End Function
2022-11-19 11:22
jklqwe111
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:35
帖 子:335
专家分:1125
注 册:2014-4-13
得分:0 
sum 100  num 6  mod 3    number  7131432
sum 200  num 6  mod 3    number  231122463
sum 300  num 6  mod 3    number  1832583390
2022-11-19 11:29
独木星空
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 43楼 jklqwe111
6个未知数,只是不能取3的倍数,解组数感觉有点小。当然,去掉1/3的数不参与运算,它的选择性是少的太多,但是6个未知数,解组数的数量公式是周期值的5次多项式形式,100/3=33.3个周期。

素数问题的解决是我学习编程永恒的动力。
2022-11-19 16:26
jklqwe111
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:35
帖 子:335
专家分:1125
注 册:2014-4-13
得分:0 
回复 44楼 独木星空
不知你认为的大的规模是什么样地
2022-11-19 18:04
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
得分:0 
回复 42楼 jklqwe111
已经很快了!

能编个毛线衣吗?
2022-11-24 11:26
mrexcel
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:22
帖 子:125
专家分:480
注 册:2022-11-3
得分:0 
递归效率太低,改成数组快了很多:
程序代码:
Function Sol(ByVal sum&, ByVal n&, Optional ByVal mo&) 'As Long
    Dim s(), i&, j&, k&
    ReDim s(1 To sum, 1 To n)
    For i = 1 To sum
        If i Mod mo Then s(i, 1) = 1
    Next

    For k = 2 To n
        For i = 1 To sum - 1
            If s(i, k - 1) Then
                For j = 1 To sum - i
                    If s(j, 1) Then s(i + j, k) = s(i + j, k) + s(i, k - 1)
                Next
            End If
        Next
    Next
    Sol = s(sum, n)
End Function
Sub Calc()
    Dim t!
    t = Timer
    Debug.Print Sol(2000, 6, 3); Timer - t & " seconds"
End Sub


6 数相加和值2000 模 3 共计 23053345578333 个, 用时0.309375 seconds
7 数相加和值2000 模 3 共计 81958890960219 个, 用时0.9640625 seconds
20 数相加和值3000 模 3 共计 2.87277983642225E+45 个, 用时3.265625 seconds
2022-11-24 21:33
mrexcel
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:22
帖 子:125
专家分:480
注 册:2022-11-3
得分:0 
数值计算还是Python相对更好些,vb6大于10^15的结果都是科学计数法,精确数字还得自己写大数运算模块。

50 数相加和值5000 模 3 共计 45745843619405329412424426930045641589286621640968244656258153368255323476091005934810174314429835433406626992 个
2022-11-24 22:42
mrexcel
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:22
帖 子:125
专家分:480
注 册:2022-11-3
得分:0 
多条件稍作修改即可,如:
程序代码:
Function Sol(ByVal sum&, ByVal n&, ParamArray mo()) 'As Long
    Dim s(), i&, j&, k&
    ReDim s(1 To sum, 1 To n)
    For j = 1 To sum
        s(j, 1) = 1
                For i = 0 To UBound(mo) - 1 Step 2
            If j Mod mo(i) = mo(i + 1) Then s(j, 1) = 0: Exit For
        Next
    Next

    For k = 2 To n
        For i = 1 To sum - 1
            If s(i, k - 1) Then
                For j = 1 To sum - i
                    If s(j, 1) Then s(i + j, k) = s(i + j, k) + s(i, k - 1)
                Next
            End If
        Next
    Next
    Sol = s(sum, n)
End Function
Sub Calc()
    Dim t!
    t = Timer
    Debug.Print Sol(1000, 9, 3, 0, 5, 0, 5, 2, 7, 1, 7, 5, 11, 3); Timer - t & " seconds"
End Sub


返回:
104857006764168  0.0715625 seconds

即9个未知数的和等于1000,若每个解模3<>0,模5<>0,模5<>2,模7<>1,模7<>5,模11<>3,则有104857006764168  组解,运行0.07秒左右

[此贴子已经被作者于2022-11-25 08:12编辑过]

2022-11-24 22:55
独木星空
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 47楼 mrexcel
的确够快。主要是给出了不同的算法。
我的也是划块,分区进行计算,矩阵化处理。

素数问题的解决是我学习编程永恒的动力。
2022-11-25 07:41



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-510483-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.196952 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved