利用DeepSeek改写newkid的排列组合算法输出格点路径

newkid在itpub发表最大子集问题的等价问题PL/SQL程序。

create or replace function f_set(n in number) return number
as
  function f2(ball in number,box in number) return number
  as
     v_ret number;
  begin
     if ball=0 or box=1 then
        return 1;
     end if;
     v_ret :=0;
     for i in 0..ball loop ------ 第一个盒子可以放0个到N个球
         v_ret:=v_ret+f2(i,box-1);
     end loop;
     return v_ret;
  end;
begin
  return f2(n-1,n);
end;
/

我让DeepSeek将上述PL/SQL翻译成Python,并告知格点集合问题相当于从(1,N)走到(N,1),只允许向下或者向右,总共几种走法?
又等价于把N-1个球放到N个盒子,有几种方法?改写上述python程序,使之不但输出路径条数,还输出具体路径。
输出代码如下:

def f_set_with_paths(n):
    def f2(ball, box):
        if ball == 0 or box == 1:
            # 返回路径数量和解的列表
            if ball == 0:
                # 所有球都在最后一个盒子
                return 1, [[0] * (box - 1) + [ball]]
            else:  # box == 1
                # 所有球都在第一个盒子
                return 1, [[ball]]
        
        total_paths = 0
        all_solutions = []
        
        for i in range(0, ball + 1):  # 第一个盒子可以放0个到ball个球
            paths, solutions = f2(i, box - 1)
            total_paths += paths
            # 在每个解的前面加上当前盒子放的数量
            for sol in solutions:
                all_solutions.append([ball - i] + sol)
        
        return total_paths, all_solutions
    
    paths_count, solutions = f2(n - 1, n)
    
    # 将盒子分配方案转换为格点路径
    grid_paths = []
    for sol in solutions:
        path = [(1, n)]  # 起点 (1, N)
        x, y = 1, n
        
        # 每个盒子的球数表示向右走的步数
        for i in range(len(sol)):
            # 向右走 sol[i] 步
            for step in range(sol[i]):
                x += 1
                path.append((x, y))
            # 向下走1步(除了最后一个)
            if i < len(sol) - 1:
                y -= 1
                path.append((x, y))
        
        grid_paths.append(path)
    
    return paths_count, solutions, grid_paths

# 测试
if __name__ == "__main__":
    n = 5
    paths_count, box_solutions, grid_paths = f_set_with_paths(n)
    
    print(f"路径条数: {paths_count}")
    print(f"\n盒子分配方案 (每个盒子放的球数):")
    for i, sol in enumerate(box_solutions, 1):
        print(f"方案 {i}: {sol}")
    
    print(f"\n格点路径 (从(1,{n})到({n},1)):")
    for i, path in enumerate(grid_paths, 1):
        print(f"路径 {i}: {path}")

这个改写后的程序:

  1. 保持原有逻辑:仍然计算从(1,N)到(N,1)只允许向下或向右的路径数
  2. 输出路径条数:返回总的路径数量
  3. 输出具体路径
    • 盒子分配方案:显示每个盒子放的球数(向右走的步数)
    • 格点路径:显示从(1,N)到(N,1)的具体格点路径

算法解释

  • 把N-1个球放到N个盒子 ↔ 从(1,N)走到(N,1)
  • 每个盒子放的球数 = 在该行向右走的步数
  • 换到下一行 = 向下走一步
  • 边界条件:球数为0或盒子数为1时只有一种分配方式

示例输出
对于n=3,会输出所有从(1,3)到(3,1)的路径,如:

  • (1,3)→(2,3)→(3,3)→(3,2)→(3,1)
  • (1,3)→(1,2)→(2,2)→(3,2)→(3,1) 等

当n=5时,运行结果如下

time python3 pyboxpath.py
路径条数: 70

盒子分配方案 (每个盒子放的球数):
方案 1: [4, 0, 0, 0, 0]
...
方案 70: [0, 0, 0, 0, 4]

格点路径 (从(1,5)到(5,1)):
路径 1: [(1, 5), (2, 5), (3, 5), (4, 5), (5, 5), (5, 4), (5, 3), (5, 2), (5, 1)]
...
路径 70: [(1, 5), (1, 4), (1, 3), (1, 2), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1)]

real	0m0.081s
user	0m0.016s
sys	0m0.008s

再去掉具体路径输出,分别对n=8、9、12、15计时

import time

def f_set(n):
    def f2(ball, box):
        if ball == 0 or box == 1:
            return 1
        v_ret = 0
        for i in range(0, ball + 1):
            v_ret += f2(i, box - 1)
        return v_ret
    
    return f2(n - 1, n)

def main():
    # 测试不同的n值
    n_values = [8,9,12,15]
    results = []
    
    for n in n_values:
        start_time = time.time()
        paths_count = f_set(n)
        end_time = time.time()
        execution_time = end_time - start_time
        
        results.append({
            'n': n,
            'paths_count': paths_count,
            'execution_time': execution_time
        })
    
    # 输出结果
    print("n\t路径条数\t用时(秒)")
    print("-" * 30)
    for result in results:
        print(f"{result['n']}\t{result['paths_count']}\t\t{result['execution_time']:.6f}")

if __name__ == "__main__":
    main()

执行结果

python3 pybox.py
n	路径条数	用时(秒)
------------------------------
8	3432		0.000812
9	12870		0.003067
12	705432		0.164429
15	40116600		9.409100
``` Clear["Global`*"] cp = 33.85 0.000000001; cs = 33.92 0.000000001; lp = 86.47 0.000001; ls = 85.16 0.000001; r1 = 0.03; r2 = 0.05; rp = 0.50; rs = 0.43; f = 95000; w = 2 Pi f; V = 48.8 0.9; Z1 = r1 + (I w lp + 1/(I w cp) + rp); Z2 = -rp - (I w lp - I w M); Z3 = (-I M w); Z4 = 2/(I w ce) + (I w M + rp + rs + I w ls); Z5 = -rs - (I w ls - I w M); Z6 = rl + (I w ls + rs + 1/(I w cs) + r2); values = {M -> 44.5*0.000001, ce -> 0.00019180962063004538`, rl -> 79.21626856036153`}; values1 = {i1 -> 3.742 - 0.000 I}; targetf[M_, ce_, rl_] := Evaluate[-((-V Z5^2 + V Z4 Z6)/( Z3^2 Z4 - 2 Z2 Z3 Z5 + Z1 Z5^2 + Z2^2 Z6 -Z1 Z4 Z6)) - (i1 /. values1)]; parentsnum = 5000; kid0num = 10000; ranges = {{44.5*10^-6, 44.51*10^-6}, {-10, Log[10, 2*10^-8]}, {1*10^-9, 10*10^-9}, {-13, Log[10, 1.5*10^-11]}, {60, 100}, {-6, Log[10, 1.5*10^-4]}}; LaunchKernels[16]; parentsDE = SortBy[ParallelMap[{Norm[ targetf[#1 + I #2, #3 + I #4, #5 + I #6] & @@ #], #} &, Table[{RandomReal[ranges[[1]]], 10^RandomReal[ranges[[2]]], RandomReal[ranges[[3]]], 10^RandomReal[ranges[[4]]], RandomReal[ranges[[5]]], 10^RandomReal[ranges[[6]]]}, {parentsnum}]], First]; (*初始化数据存储列表*) generationData = {}; Do[(*纯差分变异*) pairsDE = Table[RandomSample[Reverse[#] -> #, 3], {kid0num}] &@ Range@Length@parentsDE; kidDE = Select[(parentsDE[[#1, 2]] + RandomReal[{0.3, 0.7}] (parentsDE[[#2, 2]] - parentsDE[[#3, 2]])) & @@@ pairsDE, ranges[[1, 1]] <= #[[1]] <= ranges[[1, 2]] && 10^ranges[[2, 1]] <= #[[2]] <= 10^ranges[[2, 2]] && ranges[[3, 1]] <= #[[3]] <= ranges[[3, 2]] && 10^ranges[[4, 1]] <= #[[4]] <= 10^ranges[[4, 2]] && ranges[[5, 1]] <= #[[5]] <= ranges[[5, 2]] && 10^ranges[[6, 1]] <= #[[6]] <= 10^ranges[[6, 2]] &]; (*联合变异*)baseDE = Table[{RandomReal[ranges[[1]]], 10^RandomReal[ranges[[2]]], RandomReal[ranges[[3]]], 10^RandomReal[ranges[[4]]], RandomReal[ranges[[5]]], 10^RandomReal[ranges[[6]]]}, {kid0num}]; indexDE = RandomInteger[{1, 6}, {kid0num, 3}]; kidDE = MapThread[ ReplacePart[#1, Thread[#3 -> #2[[#3]]]] &, {kidDE, baseDE, indexDE}]; (*更新种群*)parentsDE = SortBy[Join[parentsDE, ParallelMap[{Norm[targetf @@ #], #} &, kidDE, Method -> "CoarsestGrained"]], First][[;; parentsnum]]; (*记录当前代数据*) AppendTo[generationData, Join[parentsDE[[1, 2]], {parentsDE[[1, 1]], Mean[First /@ parentsDE]}]];, {ii, 50}]; (*导出到Excel*) headers = {"M实部", "M虚部(\[Times]10^?)", "ce实部", "ce虚部(\[Times]10^?)", "rl实部", "rl虚部(\[Times]10^?)", "最优适应度", "平均适应度"}; Export["DE_Results.xlsx", Prepend[generationData, headers]]```The expression #3 cannot be used as a part specification. The expression #3 cannot be used as a part specification. Objects of unequal length in (0.9299999999999999` +50.832225772144284` I)+{<<1>>}+{{0.` +26.56268109816373` I,0.` +0.0015173539190360401` I,0.` +0.0012559781608126675` I,0.` +5.328618811355394`*^-7 I,0.` +4.667827287520987`*^7 I,0.` +55.029585531162795` I},<<49>>,<<2510>>} cannot be combined. Objects of unequal length in (0.93 +50.8322 I)+{<<1>>}+{{0. -0.0752935 I,0. -4022.04 I,0. -384.862 I,0. -416841. I,0. -3.48386*10^-8 I,0. -0.115201 I},<<49>>,<<9950>>} cannot be combined. Objects of unequal length in {{-627.327+25.0515 I,-2663.62+51.6127 I,-2663.64+51.6129 I,-2663.77+51.6142 I,-2.17886*10^15-4.66782*10^7 I,-11.4151-3.41542 I},<<49>>,<<2510>>} {<<1>>} cannot be combined. Further output of Thread::tdlen will be suppressed during this calculation.代码运行时诊断出一些问题,帮我修改,问题如上:
03-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值