剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第八转的修炼。设想一个场景:
如果允许你带一台不连网的计算机去参加高考,你会放弃选择一个手拿计算器和草稿本吗
?阿伟决定和小伟来尝试一下用计算机算高考题会是怎样的感觉。
正剧开始:
星历2016年05月26日 10:23:46, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起做着2014年的江苏省数学高考题]。
这一年的题和上一年一样的难,阿伟决定再交一次白卷。
好,卷子贴完,下面进入这次的主题。
这是上一节的那个测试题:
当时得到了这样的一组解:
当时阿伟就觉得不对,后来越想越不对。
所以这次从头来研究一下二元二次方程式组:
阿伟觉得这里可以出一个高考题,问你经过合并同类项后,上面这个判断式是多少项,
你能答出是58项吗?这是一个排列组合方面的题哦。
上面这个式子当然不可能是阿伟手打的,它是这样得出来的:
<span style="font-size:18px;">#二元二次方程组一般形式 def tmp5(): solve = StringAlgSolve(); #第一个方程 expr_1 = ['A_[1]x^[2]', 'B_[1]xy', 'C_[1]y^[2]', 'D_[1]x', 'E_[1]y', 'F_[1]']; #第二个方程 expr_2 = ['A_[2]x^[2]', 'B_[2]xy', 'C_[2]y^[2]', 'D_[2]x', 'E_[2]y', 'F_[2]']; #系数限定式B_[1]+B_[2]+(A_[1]+D_[1]+A_[2]+D_[2])(C_[1]+C_[2]+E_[1]+E_[2])(A_[1]+A_[2]+C_[1]+C_2]) != 0 g_1 = alg.strformat(['A_[1]', 'A_[2]', 'D_[1]', 'D_[2]']); g_2 = alg.strformat(['C_[1]', 'C_[2]', 'E_[1]', 'E_[2]']); g_3 = alg.strformat(['A_[1]', 'A_[2]', 'C_[1]', 'C_[2]']); g_4 = alg.strformat(['B_[1]', 'B_[2]']); expr_judge = alg.strcombine(alg.stradd(g_4, alg.strdot(alg.strdot(g_1, g_2), g_3))); print('系数表达式', expr_judge, ' != 0'); print(len(expr_judge)); >>> 系数表达式 ['(1)*B_[1]^[1]', '(1)*B_[2]^[1]', '(1)*A_[1]^[2]*C_[1]^[1]', '(2)*A_[1]^[1]*A_[2]^[1]*C_[1]^[1]', '(1)*A_[1]^[1]*C_[1]^[2]', '(2)*A_[1]^[1]*C_[1]^[1]*C_[2]^[1]', '(1)*A_[1]^[2]*C_[2]^[1]', '(2)*A_[1]^[1]*A_[2]^[1]*C_[2]^[1]', '(1)*A_[1]^[1]*C_[2]^[2]', '(1)*A_[1]^[2]*E_[1]^[1]', '(2)*A_[1]^[1]*A_[2]^[1]*E_[1]^[1]', '(1)*A_[1]^[1]*C_[1]^[1]*E_[1]^[1]', '(1)*A_[1]^[1]*C_[2]^[1]*E_[1]^[1]', '(1)*A_[1]^[2]*E_[2]^[1]', '(2)*A_[1]^[1]*A_[2]^[1]*E_[2]^[1]', '(1)*A_[1]^[1]*C_[1]^[1]*E_[2]^[1]', '(1)*A_[1]^[1]*C_[2]^[1]*E_[2]^[1]', '(1)*A_[2]^[2]*C_[1]^[1]', '(1)*A_[2]^[1]*C_[1]^[2]', '(2)*A_[2]^[1]*C_[1]^[1]*C_[2]^[1]', '(1)*A_[2]^[2]*C_[2]^[1]', '(1)*A_[2]^[1]*C_[2]^[2]', '(1)*A_[2]^[2]*E_[1]^[1]', '(1)*A_[2]^[1]*C_[1]^[1]*E_[1]^[1]', '(1)*A_[2]^[1]*C_[2]^[1]*E_[1]^[1]', '(1)*A_[2]^[2]*E_[2]^[1]', '(1)*A_[2]^[1]*C_[1]^[1]*E_[2]^[1]', '(1)*A_[2]^[1]*C_[2]^[1]*E_[2]^[1]', '(1)*A_[1]^[1]*C_[1]^[1]*D_[1]^[1]', '(1)*A_[2]^[1]*C_[1]^[1]*D_[1]^[1]', '(1)*C_[1]^[2]*D_[1]^[1]', '(2)*C_[1]^[1]*C_[2]^[1]*D_[1]^[1]', '(1)*A_[1]^[1]*C_[2]^[1]*D_[1]^[1]', '(1)*A_[2]^[1]*C_[2]^[1]*D_[1]^[1]', '(1)*C_[2]^[2]*D_[1]^[1]', '(1)*A_[1]^[1]*D_[1]^[1]*E_[1]^[1]', '(1)*A_[2]^[1]*D_[1]^[1]*E_[1]^[1]', '(1)*C_[1]^[1]*D_[1]^[1]*E_[1]^[1]', '(1)*C_[2]^[1]*D_[1]^[1]*E_[1]^[1]', '(1)*A_[1]^[1]*D_[1]^[1]*E_[2]^[1]', '(1)*A_[2]^[1]*D_[1]^[1]*E_[2]^[1]', '(1)*C_[1]^[1]*D_[1]^[1]*E_[2]^[1]', '(1)*C_[2]^[1]*D_[1]^[1]*E_[2]^[1]', '(1)*A_[1]^[1]*C_[1]^[1]*D_[2]^[1]', '(1)*A_[2]^[1]*C_[1]^[1]*D_[2]^[1]', '(1)*C_[1]^[2]*D_[2]^[1]', '(2)*C_[1]^[1]*C_[2]^[1]*D_[2]^[1]', '(1)*A_[1]^[1]*C_[2]^[1]*D_[2]^[1]', '(1)*A_[2]^[1]*C_[2]^[1]*D_[2]^[1]', '(1)*C_[2]^[2]*D_[2]^[1]', '(1)*A_[1]^[1]*D_[2]^[1]*E_[1]^[1]', '(1)*A_[2]^[1]*D_[2]^[1]*E_[1]^[1]', '(1)*C_[1]^[1]*D_[2]^[1]*E_[1]^[1]', '(1)*C_[2]^[1]*D_[2]^[1]*E_[1]^[1]', '(1)*A_[1]^[1]*D_[2]^[1]*E_[2]^[1]', '(1)*A_[2]^[1]*D_[2]^[1]*E_[2]^[1]', '(1)*C_[1]^[1]*D_[2]^[1]*E_[2]^[1]', '(1)*C_[2]^[1]*D_[2]^[1]*E_[2]^[1]'] != 0 58 </span>
<span style="font-size:18px;"> //二元二次方程组系数条件判断式 if (1) { var mathText = new MathText(); //希腊字母表(存此用于Ctrl C/V //ΑΒΓΔΕΖΗ ΘΙΚΛΜΝΞ ΟΠΡ ΣΤΥ ΦΧΨ Ω //αβγδεζη θικλμνξ οπρ στυ φχψ ω //希腊大小写字母 var Gc = 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ'; var Gs = 'αβγδεζηθικλμνξοπρστυφχψω'; var s = [ /* 'B_[1]+B_[2]+A_[1]^[2]*C_[1]+(2)*A_[1]*A_[2]*C_[1]+A_[1]*C_[1]^[2]', '+(2)*A_[1]*C_[1]*C_[2]+A_[1]^[2]*C_[2]+(2)*A_[1]*A_[2]*C_[2]+A_[1]*C_[2]^[2]', '+A_[1]^[2]*E_[1]+(2)*A_[1]*A_[2]*E_[1]+A_[1]*C_[1]*E_[1]+A_[1]*C_[2]*E_[1]', '+A_[1]^[2]*E_[2]+(2)*A_[1]*A_[2]*E_[2]+A_[1]*C_[1]*E_[2]+A_[1]*C_[2]*E_[2]', '+A_[2]^[2]*C_[1]+A_[2]*C_[1]^[2]+(2)*A_[2]*C_[1]*C_[2]+A_[2]^[2]*C_[2]', '+A_[2]*C_[2]^[2]+A_[2]^[2]*E_[1]+A_[2]*C_[1]*E_[1]+A_[2]*C_[2]*E_[1]', '+A_[2]^[2]*E_[2]+A_[2]*C_[1]*E_[2]+A_[2]*C_[2]*E_[2]+A_[1]*C_[1]*D_[1]', '+A_[2]*C_[1]*D_[1]+C_[1]^[2]*D_[1]+(2)*C_[1]*C_[2]*D_[1]+A_[1]*C_[2]*D_[1]', '+A_[2]*C_[2]*D_[1]+C_[2]^[2]*D_[1]+A_[1]*D_[1]*E_[1]+A_[2]*D_[1]*E_[1]',*/ '+C_[1]*D_[1]*E_[1]+C_[2]*D_[1]*E_[1]+A_[1]*D_[1]*E_[2]+A_[2]*D_[1]*E_[2]', '+C_[1]*D_[1]*E_[2]+C_[2]*D_[1]*E_[2]+A_[1]*C_[1]*D_[2]+A_[2]*C_[1]*D_[2]', '+C_[1]^[2]*D_[2]+(2)*C_[1]*C_[2]*D_[2]+A_[1]*C_[2]*D_[2]+A_[2]*C_[2]*D_[2]', '+C_[2]^[2]*D_[2]+A_[1]*D_[2]*E_[1]+A_[2]*D_[2]*E_[1]+C_[1]*D_[2]*E_[1]', '+C_[2]*D_[2]*E_[1]+A_[1]*D_[2]*E_[2]+A_[2]*D_[2]*E_[2]+C_[1]*D_[2]*E_[2]', '+C_[2]*D_[2]*E_[2]', '!= 0' ]; var x =40, y=40; var r1 = 40; var len = s.length; for (var i = 0; i < len; i++) { if (s[i] == '') { if (x < 100) { x += 300; y-=r1*3; } else { x = 20; y += r1; } } else { mathText.print(s[i], x, y, 'red', '|'); y+=r1; } } } </span>
但结果阿伟发现这个表达式没什么用,白忙活了。
下面转到代入消元过程中来:
<span style="font-size:18px;">#二元二次方程组一般形式 def tmp6(): solve = StringAlgSolve(); #第一个方程 expr_1 = alg.strformat(['A_[1]x^[2]', 'B_[1]xy', 'C_[1]y^[2]', 'D_[1]x', 'E_[1]y', 'F_[1]']); #第二个方程 expr_2 = alg.strformat(['A_[2]x^[2]', 'B_[2]xy', 'C_[2]y^[2]', 'D_[2]x', 'E_[2]y', 'F_[2]']); #把y用x表示,转换成只含x的二次方程组 expr_1_y = solve.coefArray(expr_1, 'y'); print('step 2: ', expr_1_y); delta = alg.strformat(['B_[1]^2x^[2]', '2B_[1]E_[1]x', 'E_[1]^2', '-4A_[1]C_[1]x^[2]', '-4C_[1]D_[1]x','-4C_[1]F_[1]']); print('delta = ', delta); </span>
<span style="font-size:18px;"> //二元二次方程组系数条件判断式 if (0) { var mathText = new MathText(); //希腊字母表(存此用于Ctrl C/V //ΑΒΓΔΕΖΗ ΘΙΚΛΜΝΞ ΟΠΡ ΣΤΥ ΦΧΨ Ω //αβγδεζη θικλμνξ οπρ στυ φχψ ω //希腊大小写字母 var GreekCaps = 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ'; var GreakSmall = 'αβγδεζηθικλμνξοπρστυφχψω'; var s = [ '把由代数式_[(1)]得的y关于x的表达式代入式_[(2)]', '(1)*C_[2]*y^[2]', '((1)*B_[2]*x+(1)*E_[2])*y', '(1)*A_[2]*x^[2]+(1)*D_[2]*x+(1)*F_[2]', ' ', 'y = -0.5B_[1]C_[1]^[-1]x-0.5E_[1]C_[1]^[-1]+ 0.5C_[1]^[-1]|Δ^[0.5]', 'y = -0.5B_[1]C_[1]^[-1]x-0.5E_[1]C_[1]^[-1]-0.5C_[1]^[-1]|Δ^[0.5]' ]; var x =40, y=40; var r1 = 40; var len = s.length; for (var i = 0; i < len; i++) { if (s[i] == '') { if (x < 100) { x += 300; y-=r1*3; } else { x = 20; y += r1; } } else { mathText.print(s[i], x, y, 'red', '|'); y+=r1; } } } </span>
下面就该进入暴力的代入过程了:
<span style="font-size:18px;">#二元二次方程组一般形式 def tmp7(): solve = StringAlgSolve(); #第一个方程 expr_1 = alg.strformat(['A_[1]x^[2]', 'B_[1]xy', 'C_[1]y^[2]', 'D_[1]x', 'E_[1]y', 'F_[1]']); #第二个方程 expr_2 = alg.strformat(['A_[2]x^[2]', 'B_[2]xy', 'C_[2]y^[2]', 'D_[2]x', 'E_[2]y', 'F_[2]']); #此部分为方程(1)中y用x表示的有理部分, 无理部分 coef_y1_real = alg.strformat(['-0.5B_[1]C_[1]^[-1]x', '-0.5E_[1]C_[1]^[-1]']); coef_y1_image = alg.strformat(['0.5C_[1]^[-1]']); delta = alg.strformat(['B_[1]^[2]x^[2]', '2B_[1]E_[1]x', 'E_[1]^[2]', '-4A_[1]C_[1]x^[2]', '-4C_[1]D_[1]x','-4C_[1]F_[1]']); print('delta:'); print(delta); #y^[2]的有理部分, 无理部分,下标系数2作平方理解 coef_y12_real = alg.strcombine(alg.strpow_n(coef_y1_real, 2) +alg.strdot(alg.strpow_n(coef_y1_image, 2), delta)); coef_y12_image = alg.strcombine(alg.strdot(alg.strdot(['(2)'], coef_y1_real), coef_y1_image)); #关于delta^[0.5]的系数,这是一个无理项 #由于代入方程(2)时各次方的系数分别是 p2 = alg.strformat(['C_[2]']); p1 = alg.strformat(['B_[2]x', 'E_[2]']); p0 = alg.strformat(['A_[2]x^[2]', 'D_[2]x', 'F_[2]']); #由此得有理部分,无理部分系数分别是 coef_y2_real = alg.strcombine(alg.strdot(p2, coef_y12_real)+ alg.strdot(p1, coef_y1_real)+ p0); coef_y2_image = alg.strcombine(alg.strdot(p2, coef_y12_image)+ alg.strdot(p1, coef_y1_image)); print('化简至倒数第二步,Δ^[0.5]以外的所有部分'); print(coef_y2_real); print('化简至倒数第二步,Δ^[0.5]的系数部分'); print(coef_y2_image); #向着x的四次方大一统表达式进军, 最后的根式除去 expr_x = alg.strcombine(alg.strpow_n(coef_y2_real, 2)+ alg.minus(alg.strdot(alg.strcombine(alg.strpow_n(coef_y2_image, 2)), delta))); ''' #中间步骤检查 expr_x_0 = alg.strcombine(alg.strpow_n(coef_y2_image, 2));#alg.strcombine(alg.strdot(, delta)); expr_x_1 = alg.strcombine(alg.strdot(expr_x_0, delta)); ''' print('化简成为关于x的四次式'); print(expr_x); coefArray = []; for i in range(len(expr_x)): if (expr_x[i].find('(0.0)')!= -1): continue; else: coefArray.append(expr_x[i]); print('去除为0的项'); print(coefArray); print(len(coefArray)); </span>
上面这段的主要目的是得到一个具有63项的系数阵列,它通吃所有的二元二次方程组:
<span style="font-size:18px;"> #解二元二次方程组的第二种方法尝试,最暴力的代入消元法 def solveEquationExp2_2(self, valueMap): ''' #第一个方程 expr_1 = alg.strformat(['A_[1]x^[2]', 'B_[1]xy', 'C_[1]y^[2]', 'D_[1]x', 'E_[1]y', 'F_[1]']); #第二个方程 expr_2 = alg.strformat(['A_[2]x^[2]', 'B_[2]xy', 'C_[2]y^[2]', 'D_[2]x', 'E_[2]y', 'F_[2]']); ''' #一共63项的关于未知数x的最高四次方的系数矩阵 coefArray = ['(1.0)*A_[2]^[1]*B_[1]^[2]*C_[1]^[-2]*C_[2]^[1]*x^[4]', '(1.0)*B_[1]^[2]*C_[1]^[-2]*C_[2]^[1]*D_[2]^[1]*x^[3]', '(1.0)*B_[1]^[2]*C_[1]^[-2]*C_[2]^[1]*F_[2]^[1]*x^[2]', '(2.0)*A_[2]^[1]*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*x^[3]', '(2.0)*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*D_[2]^[1]*E_[1]^[1]*x^[2]', '(2.0)*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*F_[2]^[1]*x^[1]', '(1.0)*A_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[2]*x^[2]', '(1.0)*C_[1]^[-2]*C_[2]^[1]*D_[2]^[1]*E_[1]^[2]*x^[1]', '(1.0)*C_[1]^[-2]*C_[2]^[1]*E_[1]^[2]*F_[2]^[1]', '(1.0)*A_[1]^[2]*C_[1]^[-2]*C_[2]^[2]*x^[4]', '(2.0)*A_[1]^[1]*C_[1]^[-2]*C_[2]^[2]*D_[1]^[1]*x^[3]', '(2.0)*A_[1]^[1]*C_[1]^[-2]*C_[2]^[2]*F_[1]^[1]*x^[2]', '(-1.0)*A_[1]^[1]*B_[1]^[1]*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*x^[4]', '(-1.0)*A_[1]^[1]*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*x^[3]', '(-1.0)*A_[1]^[1]*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[2]^[1]*x^[3]', '(-1.0)*A_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*E_[2]^[1]*x^[2]', '(-2.0)*A_[1]^[1]*A_[2]^[1]*C_[1]^[-1]*C_[2]^[1]*x^[4]', '(-2.0)*A_[1]^[1]*C_[1]^[-1]*C_[2]^[1]*D_[2]^[1]*x^[3]', '(-2.0)*A_[1]^[1]*C_[1]^[-1]*C_[2]^[1]*F_[2]^[1]*x^[2]', '(1.0)*C_[1]^[-2]*C_[2]^[2]*D_[1]^[2]*x^[2]', '(2.0)*C_[1]^[-2]*C_[2]^[2]*D_[1]^[1]*F_[1]^[1]*x^[1]', '(-1.0)*B_[1]^[1]*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*D_[1]^[1]*x^[3]', '(-1.0)*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*D_[1]^[1]*E_[1]^[1]*x^[2]', '(-1.0)*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*D_[1]^[1]*E_[2]^[1]*x^[2]', '(-1.0)*C_[1]^[-2]*C_[2]^[1]*D_[1]^[1]*E_[1]^[1]*E_[2]^[1]*x^[1]', '(-2.0)*A_[2]^[1]*C_[1]^[-1]*C_[2]^[1]*D_[1]^[1]*x^[3]', '(-2.0)*C_[1]^[-1]*C_[2]^[1]*D_[1]^[1]*D_[2]^[1]*x^[2]', '(-2.0)*C_[1]^[-1]*C_[2]^[1]*D_[1]^[1]*F_[2]^[1]*x^[1]', '(1.0)*C_[1]^[-2]*C_[2]^[2]*F_[1]^[2]', '(-1.0)*B_[1]^[1]*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*F_[1]^[1]*x^[2]', '(-1.0)*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*F_[1]^[1]*x^[1]', '(-1.0)*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[2]^[1]*F_[1]^[1]*x^[1]', '(-1.0)*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*E_[2]^[1]*F_[1]^[1]', '(-2.0)*A_[2]^[1]*C_[1]^[-1]*C_[2]^[1]*F_[1]^[1]*x^[2]', '(-2.0)*C_[1]^[-1]*C_[2]^[1]*D_[2]^[1]*F_[1]^[1]*x^[1]', '(-2.0)*C_[1]^[-1]*C_[2]^[1]*F_[1]^[1]*F_[2]^[1]', '(-1.0)*A_[2]^[1]*B_[1]^[1]*B_[2]^[1]*C_[1]^[-1]*x^[4]', '(-1.0)*B_[1]^[1]*B_[2]^[1]*C_[1]^[-1]*D_[2]^[1]*x^[3]', '(-1.0)*B_[1]^[1]*B_[2]^[1]*C_[1]^[-1]*F_[2]^[1]*x^[2]', '(-1.0)*A_[2]^[1]*B_[2]^[1]*C_[1]^[-1]*E_[1]^[1]*x^[3]', '(-1.0)*B_[2]^[1]*C_[1]^[-1]*D_[2]^[1]*E_[1]^[1]*x^[2]', '(-1.0)*B_[2]^[1]*C_[1]^[-1]*E_[1]^[1]*F_[2]^[1]*x^[1]', '(-1.0)*A_[2]^[1]*B_[1]^[1]*C_[1]^[-1]*E_[2]^[1]*x^[3]', '(-1.0)*B_[1]^[1]*C_[1]^[-1]*D_[2]^[1]*E_[2]^[1]*x^[2]', '(-1.0)*B_[1]^[1]*C_[1]^[-1]*E_[2]^[1]*F_[2]^[1]*x^[1]', '(-1.0)*A_[2]^[1]*C_[1]^[-1]*E_[1]^[1]*E_[2]^[1]*x^[2]', '(-1.0)*C_[1]^[-1]*D_[2]^[1]*E_[1]^[1]*E_[2]^[1]*x^[1]', '(-1.0)*C_[1]^[-1]*E_[1]^[1]*E_[2]^[1]*F_[2]^[1]', '(1)*A_[2]^[2]*x^[4]', '(2)*A_[2]^[1]*D_[2]^[1]*x^[3]', '(2)*A_[2]^[1]*F_[2]^[1]*x^[2]', '(1)*D_[2]^[2]*x^[2]', '(2)*D_[2]^[1]*F_[2]^[1]*x^[1]', '(1)*F_[2]^[2]', '(1.0)*A_[1]^[1]*B_[2]^[2]*C_[1]^[-1]*x^[4]', '(1.0)*B_[2]^[2]*C_[1]^[-1]*D_[1]^[1]*x^[3]', '(1.0)*B_[2]^[2]*C_[1]^[-1]*F_[1]^[1]*x^[2]', '(2.0)*A_[1]^[1]*B_[2]^[1]*C_[1]^[-1]*E_[2]^[1]*x^[3]', '(2.0)*B_[2]^[1]*C_[1]^[-1]*D_[1]^[1]*E_[2]^[1]*x^[2]', '(2.0)*B_[2]^[1]*C_[1]^[-1]*E_[2]^[1]*F_[1]^[1]*x^[1]', '(1.0)*A_[1]^[1]*C_[1]^[-1]*E_[2]^[2]*x^[2]', '(1.0)*C_[1]^[-1]*D_[1]^[1]*E_[2]^[2]*x^[1]', '(1.0)*C_[1]^[-1]*E_[2]^[2]*F_[1]^[1]']; #这整个是一个和为零的多项式 #赋值系数,应该有12个 len_ = len(valueMap); size = len(coefArray); result = []; for i in range(size): s = coefArray[i]; #由于字母排序原因,一般x会排在最后,各系数ABCDEF会排在前面, #这会带来一些方便 index = s.find('x'); if (index != -1): #系数部分 part1 = s[:index-1]; #参数x部分 part2 = s[index-1:]; else: part1 = s; part2 = ''; for j in range(len_): part1 = part1.replace(valueMap[j][0], '('+str(valueMap[j][1])+')'); part1 = part1.replace('^[', '**('); part1 = part1.replace(']', ')'); #print(part1); part1 = '('+str(eval(part1))+')'; result.append(part1+part2); #print(result); result = alg.strcombine(result); #print(result); coef_x = self.coefPoly(result, 'x'); print('系数数组:', coef_x); roots = np.roots(coef_x); print('解: ', roots); return roots;</span>
然后就可以做上面的测试了:
<span style="font-size:18px;">#x的四次方式的系数代入数值化简 def tmp8(): solve = StringAlgSolve(); #第一个方程 expr_1 = alg.strformat(['A_[1]x^[2]', 'B_[1]xy', 'C_[1]y^[2]', 'D_[1]x', 'E_[1]y', 'F_[1]']); #第二个方程 expr_2 = alg.strformat(['A_[2]x^[2]', 'B_[2]xy', 'C_[2]y^[2]', 'D_[2]x', 'E_[2]y', 'F_[2]']); valMap = [['A_[1]', 1], ['B_[1]', 2],['C_[1]', 1], ['D_[1]', 0], ['E_[1]', 0],['F_[1]', -1], ['A_[2]', 1], ['B_[2]', 0],['C_[2]', 4], ['D_[2]', 0], ['E_[2]', 0],['F_[2]', -1]]; roots = solve.solveEquationExp2_2(valMap); #两个方程 f = alg.strformat(['x^[2]', 'y^[2]', '2xy', '-1']); print('step1: ', f); poly_y_f = solve.coefArray(f, 'y'); print('step2: ', poly_y_f); g = alg.strformat(['x^[2]', '4y^[2]', '-1']); print('step1: ', g); poly_y_g = solve.coefArray(g, 'y'); print('step2: ', poly_y_g); #求方程式<1>的y关于x的表达式 expr_y_root = solve.solvePoly(poly_y_f); print('step7: ', expr_y_root); expr_y_root2 = solve.solvePoly(poly_y_g); print('step7: ', expr_y_root2); #求相交点的坐标对组 points = []; points2 = []; for i in range(len(roots)): real = abs(roots[i].real); abs_ = abs(roots[i]); #实数根 if abs(real-abs_) < 0.001: for j in range(len(expr_y_root)): x = roots[i]; y = solve.strEval(expr_y_root[j], 'x', x); points.append([x, y]); y = solve.strEval(expr_y_root2[j], 'x', x); points2.append([x, y]); print('step8: '); for i in range(len(points)): if (abs(points[i][0]-points2[i][0]) < 1e-6 and abs(points[i][1]-points2[i][1])<1e-6): print('相交点:[{0}, {1}]'.format(round(points[i][0], 3), round(points[i][1], 3))); </span>
结果:
这次的结果就是对的了。
那么这里贴一下工具吧,几经变迁,实在很难说改了多少地方。
<span style="font-size:18px;">### # @usage 代数式字符串的运算 # @author mw # @date 2016年05月17日 星期二 16:48:56 # @param # @return # ### #计算代数式用, 传入的是单项式,返回coef*expr的形式 def strmono(s): #'x', '-x', '2x', '-2x', '-2x^[2]', '3x_[2]^[3]', '-3x_[2]^[3]' stmp = s; size = len(stmp); alphaIndex = 0; signIndex = 0; for i in range(size): if (stmp[i].isalpha()): alphaIndex = i; break; if (i >= size-1): alphaIndex = i+1; if (stmp[0] == '-'): signIndex = 1; if (signIndex >= alphaIndex): return monoformat('(-1)*'+stmp[alphaIndex:]); else: if alphaIndex >= size: return monoformat('(-'+stmp[signIndex:alphaIndex]+')'); return monoformat('(-'+stmp[signIndex:alphaIndex]+')*'+stmp[alphaIndex:]); elif (stmp[0] == '('): #已经格式化的情况,这种情况输入时是(coef)*expr return monoformat(stmp); else: signIndex = 0; if (signIndex >= alphaIndex): return monoformat('(1)*'+stmp[alphaIndex:]); else: if alphaIndex >= size: return monoformat('('+stmp[signIndex:alphaIndex]+')'); return monoformat('('+stmp[signIndex:alphaIndex]+')*'+stmp[alphaIndex:]); #计算两个单项式的乘积 def strmul(mono1, mono2): #这个处理是保证每个单项式统一格式(coef)*expr ''' if (mono1[0] != '(' or mono2[0] != '('): #如果没有规格化,那么就做一下 mono1 = strmono(mono1); mono2 = strmono(mono2); ''' stmp1 = mono1; stmp2 = mono2; #乘号的位置 signIndex1 = stmp1.find('*'); signIndex2 = stmp2.find('*'); if (signIndex1 == -1): coef1 = stmp1; expr1 = ''; else: coef1 = stmp1[:signIndex1]; expr1 = stmp1[signIndex1+1:]; if (signIndex2 == -1): coef2 = stmp2; expr2 = ''; else: coef2 = stmp2[:signIndex2]; expr2 = stmp2[signIndex2+1:]; coef = coef1+'*'+coef2; if (signIndex1 == -1 or signIndex2 == -1): expr = expr1+expr2; else: expr = expr1+'*'+expr2; if (expr == ''): return '('+str(round(eval(coef), 6))+')'; return '('+str(round(eval(coef), 6))+')*'+expr; #计算两个单项式的商 def strdiv(s1, s2): #这个处理是保证每个单项式统一格式(coef)*expr stmp1 = strmono(s1); stmp2 = strmono(s2); #乘号的位置 signIndex1 = stmp1.find('*'); signIndex2 = stmp2.find('*'); if (signIndex1 == -1): coef1 = stmp1; expr1 = ''; else: coef1 = stmp1[:signIndex1]; expr1 = stmp1[signIndex1+1:]; if (signIndex2 == -1): coef2 = stmp2; expr2 = ''; else: coef2 = stmp2[:signIndex2]; expr2 = stmp2[signIndex2+1:]; coef = coef1+'/'+coef2; if (signIndex1 == -1 and signIndex2 != -1): expr = '('+expr2+')^[-1]'; elif (signIndex1 == -1 or signIndex2 == -1): expr = expr1+expr2; else: expr = expr1+'/'+expr2; if (expr == ''): return '('+str(round(eval(coef), 6))+')'; return '('+str(round(eval(coef), 6))+')*'+expr; #把多项式中每一项都乘系数 def strscale(array, scale): scale = '('+str(scale)+')'; for i in range(len(array)): s = array[i]; for j in range(len(s)): if (s[j].isdigit()): index = j; break; lbracket = s.find('('); rbracket = s.find(')', lbracket); coef = s[lbracket:index]+scale+'*'+s[index:rbracket+1]; coef = '('+str(eval(coef))+')'; array[i] = coef+s[rbracket+1:]; return array; #找一个字符串中所有待查找子串的位置,返回位置阵列 def findall(string, sub): size = len(string); index = []; cur = string.find(sub); index.append(cur) while (index[-1] != -1): cur = string.find(sub, index[-1]+1); index.append(cur); return index; #计算单项式的乘方, s^n def strpow(s, n): stmp = strmono(s); signIndex = stmp.find('*'); if (signIndex == -1): coef = stmp+'**'+str(n); expr = ''; return '('+str(round(eval(coef), 6))+')'; else: coef = stmp[:signIndex]+'**'+str(n); expr = '('+stmp[signIndex+1:]+')^['+str(n)+']'; return '('+str(round(eval(coef), 6))+')*'+expr; #计算代数式用,传入的两个阵列都具有['s1', 's2', ..., 'sn']这样的格式 def strdot(array1, array2): size1 = len(array1); size2 = len(array2); result = []; for i in range(size1): for j in range(size2): result.append(strmul(array1[i], array2[j])); return result; #把格式化后的单项式分解成[coef, expr]对组的形式 def explodemono(mono): stmp = mono; #乘号的位置 signIndex = stmp.find('*'); if (signIndex == -1): coef = stmp; expr = ''; else: coef = stmp[:signIndex]; expr = stmp[signIndex+1:]; return [coef, expr]; #合并同类项,传入的阵列具有['s1', 's2', ..., 'sn']这样的格式 def strcombine(array): size = len(array); explode = []; for i in range(size): #这里传入的阵列已经是规格化后的了,否则要加一层strmono处理。 explode.append(explodemono(monocombine(array[i]))); result = []; for i in range(size): size_1 = len(result); if size_1 <= 0: result.append(explode[i]); else: for j in range(size_1): if result[j][1] == explode[i][1]: result[j][0] = result[j][0] + '+' + explode[i][0]; break; if j >= size_1-1: result.append(explode[i]); result_1 = []; size_1 = len(result); for j in range(size_1): result[j][0] = str(round(eval(result[j][0]), 6)); if (abs(float(result[j][0])) <= 1e-3): result_1.append('(0)'); else: tmps = result[j][1]; if (tmps == ''): result_1.append('('+result[j][0]+')'); else: result_1.append('('+result[j][0]+')*'+result[j][1]); return result_1; #指数为正整数的乘方 def strpow_n(array, n): #计算 result = []; if (n == 1): result = array; elif (n == 2): result = strdot(array, array); elif (n >= 3): tmp = strdot(array, array); n -= 2; while (n > 0): result = strdot(tmp, array); tmp = result; n -= 1; return result; #阵列取负 def minus(array): for i in range(len(array)): if array[i][1] == '-': #array[i][0]是'(, 这是规范 array[i] = array[i][0]+array[i][2:]; else: array[i] = array[i][0]+'-'+array[i][1:]; return array; ### # @usage 代数式运算 # @author mw # @date 2016年05月18日 星期三 07:37:01 # @param # @return # ### #两个多项式相加,合并同类项不在此进行 def stradd(array1, array2): #两个多项式相加,这里直接返回数组的相加 return array1+array2; #为了简便输入,不要求输入规范化代数式,(coef)*expr形式 #所以在此对多项式进行规范化 #至于单项式规范化,调用strmono函数即可 def strformat(array): for i in range(len(array)): array[i] = strmono(array[i]); return array; #把单项式完全格式化,使经过运算的没运算过的都具有统一的格式 def monoformat(mono): #规范化单项式,保证任意两个参数之间都添加一个'*'号 #这是为了和经过代数式乘法运算之后的格式统一 chars = len(mono); s = ''; for i in range(chars-1): if (mono[i] == ']' or mono[i] == ')') and mono[i+1].isalpha(): s += mono[i]+'*'; elif mono[i].isalpha() and mono[i+1].isalpha(): s += mono[i]+'*'; #这里还有一个死角,就是下标或指数如果是用的代数式,并且是多项相乘 #可能会有一点问题,暂时不考虑了 else: s += mono[i]; s += mono[-1]; return s; #把单项式炸开,这里的单项式已经达到最大规范化,是(coef)*x_[1]^[2]*y_[2]^[2]这种结构形式了 #'*'号是要作为分隔符的,不可缺少 def explodemono_2(mono): part = mono.split('*'); #每个部分的[前部,指数部]的对组 map_ = []; for i in range(len(part)): expIndex = part[i].find('^'); if (expIndex != -1): map_.append([part[i][:expIndex], part[i][expIndex:]]); else: s = part[i]; #系数 if s[0] == '(': map_.append([part[i], '']); #代数式 else: map_.append([part[i], '^[1]']); map_ = sorted(map_, key = lambda a : a[0]); return map_; #单项式同类项合并 def monocombine(mono): map_ = explodemono_2(mono); size = len(map_); result = []; for i in range(size): size_1 = len(result); if (size_1 <= 0): result.append(map_[i]); else: for j in range(size_1): if result[j][0] == map_[i][0]: #双方的中括号位置 #由于规范化后的原因,这个括号是一定有的 p1 = result[j][1].find('['); p2 = result[j][1].find(']'); p3 = map_[i][1].find('['); p4 = map_[i][1].find(']'); s = result[j][1][p1+1:p2]+'+'+map_[i][1][p3+1:p4]; size_2 = len(s); for k in range(size_2): if s[k].isalpha(): break; #如果没有字符参数,可以计算出结果,就计算 if (k >= size_2-1): s = str(eval(s)); result[j][1] = '^['+s+']'; break; if (j >= size_1-1): result.append(map_[i]); size_1 = len(result); s = ''; for i in range(size_1): if (i > 0 and result[i][1] == '^[0]'): continue; s += result[i][0]+result[i][1]; if (i < size_1-1): s += '*'; return s; import numpy.f2py import numpy.random import numpy.polynomial import numpy.ma import numpy.distutils import numpy.compat import numpy as np; import numpy.linalg import numpy.matrixlib import numpy.fft import numpy.distutils.fcompiler import numpy.core import numpy.distutils.command ### # @usage 对于含有代数符号的等式及相关类型进行计算 # @author mw # @date 2016年05月24日 星期二 08:21:57 # @param # @return # ### #所有输入的字符串都是要符合(coef)*expr这种规范的 #相应转换可以调用alg.strmono处理单项式 #或调用alg.strformat来处理多项式 class StringAlgSolve(): #格式化输入的多项式阵列 def format(self, array): return alg.strformat(array); #把一个字符串阵列表示的多项式,转换成指定变量的系数多项式 #比如 ['(1/4)x^[2]', '-(1/12)y^[2]', '-1'], 以y作为参数 => ['(-(1/12))', 0, '(1/4)x^[2]+(-1)'] #传入的格式必须是已经格式化过的(coef)*x^[2]*y_[2]^[3]...这种类似形式 def coefTransfer(self, array, element): coefMap = []; len_ = len(array); len_2 = len(element); for i in range(len_): s = array[i]; len_3 = len(s); index = s.find(element); #参数的0次方 if (index == -1): coefMap.append([array[i], 0]); elif (index+len_2 < len_3 and s[index+len_2] != '^'): #参数的一次方 coefMap.append([s[:index-1]+s[index+len_2:], 1]); elif (index+len_2 >= len_3): #这里回退一个位置是因为根据格式参数之间有一个'*'号相连,要退掉 coefMap.append([s[:index-1], 1]); else: #左右中括号作为定界符,这就是为什么要求先格式化 LBracket = index+len_2+1; RBracket = s.find(']', LBracket); #幂的次数 exp_ = int(s[LBracket+1:RBracket]); coefMap.append([s[:index-1]+s[RBracket+1:], exp_]); #对coefMap中的项按参数的次数进行合并 coefMap_2 = []; coefMap_2.append(coefMap[0]); for i in range(1, len(coefMap)): len_3 = len(coefMap_2); for j in range(len_3): if (coefMap_2[j][1] == coefMap[i][1]): coefMap_2[j][0] = coefMap_2[j][0]+ '+'+coefMap[i][0]; break; if (j >= len_3-1): coefMap_2.append(coefMap[i]); coefMap = coefMap_2; #把系数映射由高到低排列 coefMap = sorted(coefMap, key = lambda a : a[1], reverse = True); #返回的是参数的系数映射表[[coef, exp]...]对组 return coefMap; #返回参数的系数阵列 def coefArray(self, array, element): coefMap = self.coefTransfer(array, element); len_4 = len(coefMap); maxCoef, minCoef = coefMap[0][1], coefMap[len_4-1][1]; coefArray = ['0']*(maxCoef-minCoef+1); for i in range(len_4): coefArray[maxCoef-coefMap[i][1]] = coefMap[i][0]; return coefArray; #获取多项式的系数值,比如5x^2+4x+1 = 0应该返回[5, 4, 1] def coefPoly(self, array, element): coefMap = self.coefTransfer(array, element); len_4 = len(coefMap); maxCoef, minCoef = coefMap[0][1], coefMap[len_4-1][1]; coefArray = [0]*(maxCoef-minCoef+1); for i in range(len_4): index = coefMap[i][0].find('^'); if (index != -1): s = coefMap[i][0][:index]; else: s = coefMap[i][0]; #这里是必须要能求值的,这个方法是为了便于调用numpy.roots求多项式的根 coefArray[maxCoef-coefMap[i][1]] = eval(s); return coefArray; #求解多项式的根(在参数情况下) def solvePoly(self, coefArray): len_ = len(coefArray); # #求解二次方程 if (len_ == 3): a, b, c = str(coefArray[0]), str(coefArray[1]), str(coefArray[2]); #注意,由于此处得出的系数阵列是这样的形式:['(-(1/12))', 0, '(1/4)x^[2]+(-1)'] #已经无法用alg中函数去做任何计算,只能纯粹进行字符串的叠加处理 delta = self.strAdd(self.strPow(b, '2'), self.strMul('-4', self.strMul(a, c))); #分子,分母 numerator = self.strAdd(self.strMinus('0', b), self.strPow(delta, '0.5')); numerator2 = self.strMinus(self.strMinus('0', b), self.strPow(delta, '0.5')); denomerator = self.strMul('2', a); return [self.strDiv(numerator, denomerator), self.strDiv(numerator2, denomerator)]; #求解一次方程 if (len_ == 2): a, b = str(coefArray[0]), str(coefArray[1]); return [self.strDiv(b, self.strMinus('0', a))]; return ''; #代数式里的两个代数式相乘,这里就是两个字符串相加的处理而已 def strMul(self, str1, str2): if (self.judgeZero(str1)): return ''; else: if (self.judgeZero(str2)): return ''; else: return '('+str1+')*('+str2+')'; #两个代数式相除 def strDiv(self, str1, str2): if (self.judgeZero(str1)): return ''; else: if (self.judgeZero(str2)): return '(inf)'; else: return '('+str1+')/('+str2+')'; #代数式相减 def strMinus(self, str1, str2): if (self.judgeZero(str1)): if (self.judgeZero(str2)): return ''; else: return '(-('+str2+'))'; else: if (self.judgeZero(str2)): return '('+str1+')'; else: return '('+str1+')-('+str2+')'; #代数式相加 def strAdd(self, str1, str2): if (self.judgeZero(str1)): if (self.judgeZero(str2)): return ''; else: return '('+str2+')'; else: if (self.judgeZero(str2)): return '('+str1+')'; else: return '('+str1+')+('+str2+')'; #代数式里的代数式乘方,这里就是字符串的处理而已 def strPow(self, str1, str2): str2 = str(str2); if (self.judgeZero(str1)): return ''; else: if (self.judgeZero(str2)): return '('+str1+')'; else: return '('+str1+')^['+str2+']'; #判断字符串是否为0 def judgeZero(self, str1): for i in range(len(str1)): if (str1[i].isdigit() and str1[i] != '0'): #存在数字不为0, 所以这个代数式不为0 return False; #由于在规范化输出时已经保证了如果系数为0, 无论有多少参数都取0 #所以只要存在参数就说明代数式不为0 elif (str1[i].isalpha()): return False; return True; #给参数赋值,计算代数式的值 #比如输入 ('x^[2]+1', 'x', 3) => 10 #要确保给的条件足以让代数式计算出数值,否则肯定报错 def strEval(self, str1, element, elementValue): #代入数值,去指数 str1 = str1.replace(element, '('+str(elementValue)+')'); str1 = str1.replace('^[', '**'); str1 = str1.replace(']', ''); return eval(str1); #对于本身不带参数的字符串,清除格式即可计算出数值 def arrayEval(self, array): for i in range(len(array)): str1 = array[i]; str1 = str1.replace('^[', '**'); str1 = str1.replace(']', ''); str1 = eval(str1); array[i] = str1; return array; #把一个只包括+号的多项式字符串拆分成多项式数组 #如'(1)*x^[2]+(-1)' => ['(1)*x^[2]', '(-1)'] def str2Array(self, str1): array = []; #加号位置 signIndex = str1.find('+'); #print(signIndex); start = 0; count = 0; if (signIndex != -1): while (signIndex != '-1' and count < 10): #符合要求的必须连着下一个单项式的系数 #按照统一格式是左括号开始 if str1[signIndex+1] == '(': array.append(str1[start:signIndex]); start = signIndex + 1; signIndex = str1.find('+', signIndex+1); if (signIndex == -1): break; array.append(str1[start:]); return array; #解二元二次方程组 def solveEquationExp2(self, array1, array2): #输入的是两个系数矩阵 #矩阵具有这样的形式:[['1'], [b_[1]], [c_[1]]] #也就是对于ax^[2]+bx+c=0来说, a=1, 而b, c是带参数多项式数组 #注意,系数是数组,不是字符串等。 a_1, b_1, c_1 = array1[0], array1[1], array1[2]; a_2, b_2, c_2 = array2[0], array2[1], array2[2]; #恒等式 ''' [ '(1.0)*b_[1]^[1]*b_[2]^[1]*c_[1]^[1]', '(1.0)*b_[1]^[1]*b_[2]^[1]*c_[2]^[1]', '(1.0)*c_[1]^[2]', '(-2.0)*c_[1]^[1]*c_[2]^[1]', '(1.0)*c_[2]^[2]', '(1.0)*b_[1]^[2]*c_[2]^[1]', '(1.0)*b_[2]^[2]*c_[1]^[1]'] = 0 ''' #这些运算都是针对数组的 b1b2 = alg.strcombine(alg.strdot(b_1, b_2)); c1c2 = alg.strcombine(alg.strdot(c_1, c_2)); c12 = alg.strcombine(alg.strpow_n(c_1, 2)); c22 = alg.strcombine(alg.strpow_n(c_2, 2)); b12 = alg.strcombine(alg.strpow_n(b_1, 2)); b22 = alg.strcombine(alg.strpow_n(b_2, 2)); part1 = alg.strcombine(alg.strdot(b1b2, alg.stradd(c_1, c_2))); part2 = alg.strcombine(c12+alg.strdot(['(-2)'], c1c2)+c22); part3 = alg.strcombine(alg.stradd(alg.strdot(b12, c_2), alg.strdot(b22, c_1))); result = alg.strcombine(part1+part2+part3); return result; #解二元二次方程组的第二种方法尝试,最暴力的代入消元法 def solveEquationExp2_2(self, valueMap): ''' #第一个方程 expr_1 = alg.strformat(['A_[1]x^[2]', 'B_[1]xy', 'C_[1]y^[2]', 'D_[1]x', 'E_[1]y', 'F_[1]']); #第二个方程 expr_2 = alg.strformat(['A_[2]x^[2]', 'B_[2]xy', 'C_[2]y^[2]', 'D_[2]x', 'E_[2]y', 'F_[2]']); ''' #一共63项的关于未知数x的最高四次方的系数矩阵 coefArray = ['(1.0)*A_[2]^[1]*B_[1]^[2]*C_[1]^[-2]*C_[2]^[1]*x^[4]', '(1.0)*B_[1]^[2]*C_[1]^[-2]*C_[2]^[1]*D_[2]^[1]*x^[3]', '(1.0)*B_[1]^[2]*C_[1]^[-2]*C_[2]^[1]*F_[2]^[1]*x^[2]', '(2.0)*A_[2]^[1]*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*x^[3]', '(2.0)*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*D_[2]^[1]*E_[1]^[1]*x^[2]', '(2.0)*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*F_[2]^[1]*x^[1]', '(1.0)*A_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[2]*x^[2]', '(1.0)*C_[1]^[-2]*C_[2]^[1]*D_[2]^[1]*E_[1]^[2]*x^[1]', '(1.0)*C_[1]^[-2]*C_[2]^[1]*E_[1]^[2]*F_[2]^[1]', '(1.0)*A_[1]^[2]*C_[1]^[-2]*C_[2]^[2]*x^[4]', '(2.0)*A_[1]^[1]*C_[1]^[-2]*C_[2]^[2]*D_[1]^[1]*x^[3]', '(2.0)*A_[1]^[1]*C_[1]^[-2]*C_[2]^[2]*F_[1]^[1]*x^[2]', '(-1.0)*A_[1]^[1]*B_[1]^[1]*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*x^[4]', '(-1.0)*A_[1]^[1]*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*x^[3]', '(-1.0)*A_[1]^[1]*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[2]^[1]*x^[3]', '(-1.0)*A_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*E_[2]^[1]*x^[2]', '(-2.0)*A_[1]^[1]*A_[2]^[1]*C_[1]^[-1]*C_[2]^[1]*x^[4]', '(-2.0)*A_[1]^[1]*C_[1]^[-1]*C_[2]^[1]*D_[2]^[1]*x^[3]', '(-2.0)*A_[1]^[1]*C_[1]^[-1]*C_[2]^[1]*F_[2]^[1]*x^[2]', '(1.0)*C_[1]^[-2]*C_[2]^[2]*D_[1]^[2]*x^[2]', '(2.0)*C_[1]^[-2]*C_[2]^[2]*D_[1]^[1]*F_[1]^[1]*x^[1]', '(-1.0)*B_[1]^[1]*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*D_[1]^[1]*x^[3]', '(-1.0)*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*D_[1]^[1]*E_[1]^[1]*x^[2]', '(-1.0)*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*D_[1]^[1]*E_[2]^[1]*x^[2]', '(-1.0)*C_[1]^[-2]*C_[2]^[1]*D_[1]^[1]*E_[1]^[1]*E_[2]^[1]*x^[1]', '(-2.0)*A_[2]^[1]*C_[1]^[-1]*C_[2]^[1]*D_[1]^[1]*x^[3]', '(-2.0)*C_[1]^[-1]*C_[2]^[1]*D_[1]^[1]*D_[2]^[1]*x^[2]', '(-2.0)*C_[1]^[-1]*C_[2]^[1]*D_[1]^[1]*F_[2]^[1]*x^[1]', '(1.0)*C_[1]^[-2]*C_[2]^[2]*F_[1]^[2]', '(-1.0)*B_[1]^[1]*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*F_[1]^[1]*x^[2]', '(-1.0)*B_[2]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*F_[1]^[1]*x^[1]', '(-1.0)*B_[1]^[1]*C_[1]^[-2]*C_[2]^[1]*E_[2]^[1]*F_[1]^[1]*x^[1]', '(-1.0)*C_[1]^[-2]*C_[2]^[1]*E_[1]^[1]*E_[2]^[1]*F_[1]^[1]', '(-2.0)*A_[2]^[1]*C_[1]^[-1]*C_[2]^[1]*F_[1]^[1]*x^[2]', '(-2.0)*C_[1]^[-1]*C_[2]^[1]*D_[2]^[1]*F_[1]^[1]*x^[1]', '(-2.0)*C_[1]^[-1]*C_[2]^[1]*F_[1]^[1]*F_[2]^[1]', '(-1.0)*A_[2]^[1]*B_[1]^[1]*B_[2]^[1]*C_[1]^[-1]*x^[4]', '(-1.0)*B_[1]^[1]*B_[2]^[1]*C_[1]^[-1]*D_[2]^[1]*x^[3]', '(-1.0)*B_[1]^[1]*B_[2]^[1]*C_[1]^[-1]*F_[2]^[1]*x^[2]', '(-1.0)*A_[2]^[1]*B_[2]^[1]*C_[1]^[-1]*E_[1]^[1]*x^[3]', '(-1.0)*B_[2]^[1]*C_[1]^[-1]*D_[2]^[1]*E_[1]^[1]*x^[2]', '(-1.0)*B_[2]^[1]*C_[1]^[-1]*E_[1]^[1]*F_[2]^[1]*x^[1]', '(-1.0)*A_[2]^[1]*B_[1]^[1]*C_[1]^[-1]*E_[2]^[1]*x^[3]', '(-1.0)*B_[1]^[1]*C_[1]^[-1]*D_[2]^[1]*E_[2]^[1]*x^[2]', '(-1.0)*B_[1]^[1]*C_[1]^[-1]*E_[2]^[1]*F_[2]^[1]*x^[1]', '(-1.0)*A_[2]^[1]*C_[1]^[-1]*E_[1]^[1]*E_[2]^[1]*x^[2]', '(-1.0)*C_[1]^[-1]*D_[2]^[1]*E_[1]^[1]*E_[2]^[1]*x^[1]', '(-1.0)*C_[1]^[-1]*E_[1]^[1]*E_[2]^[1]*F_[2]^[1]', '(1)*A_[2]^[2]*x^[4]', '(2)*A_[2]^[1]*D_[2]^[1]*x^[3]', '(2)*A_[2]^[1]*F_[2]^[1]*x^[2]', '(1)*D_[2]^[2]*x^[2]', '(2)*D_[2]^[1]*F_[2]^[1]*x^[1]', '(1)*F_[2]^[2]', '(1.0)*A_[1]^[1]*B_[2]^[2]*C_[1]^[-1]*x^[4]', '(1.0)*B_[2]^[2]*C_[1]^[-1]*D_[1]^[1]*x^[3]', '(1.0)*B_[2]^[2]*C_[1]^[-1]*F_[1]^[1]*x^[2]', '(2.0)*A_[1]^[1]*B_[2]^[1]*C_[1]^[-1]*E_[2]^[1]*x^[3]', '(2.0)*B_[2]^[1]*C_[1]^[-1]*D_[1]^[1]*E_[2]^[1]*x^[2]', '(2.0)*B_[2]^[1]*C_[1]^[-1]*E_[2]^[1]*F_[1]^[1]*x^[1]', '(1.0)*A_[1]^[1]*C_[1]^[-1]*E_[2]^[2]*x^[2]', '(1.0)*C_[1]^[-1]*D_[1]^[1]*E_[2]^[2]*x^[1]', '(1.0)*C_[1]^[-1]*E_[2]^[2]*F_[1]^[1]']; #这整个是一个和为零的多项式 #赋值系数,应该有12个 len_ = len(valueMap); size = len(coefArray); result = []; for i in range(size): s = coefArray[i]; #由于字母排序原因,一般x会排在最后,各系数ABCDEF会排在前面, #这会带来一些方便 index = s.find('x'); if (index != -1): #系数部分 part1 = s[:index-1]; #参数x部分 part2 = s[index-1:]; else: part1 = s; part2 = ''; for j in range(len_): part1 = part1.replace(valueMap[j][0], '('+str(valueMap[j][1])+')'); part1 = part1.replace('^[', '**('); part1 = part1.replace(']', ')'); #print(part1); part1 = '('+str(eval(part1))+')'; result.append(part1+part2); #print(result); result = alg.strcombine(result); #print(result); coef_x = self.coefPoly(result, 'x'); print('系数数组:', coef_x); roots = np.roots(coef_x); print('解: ', roots); return roots; </span>
下面是阿伟用到的测试用例:
<span style="font-size:18px;">#测试 def tmp(): #先化出x^[2]/4 x = alg.strformat(['y^[-1]', '-1']); x2 = alg.strcombine(alg.strpow_n(x, 2)); print(x2); x2 = alg.strscale(x2, '1/4'); print('step1: ', x2); expr = alg.strcombine(alg.stradd(x2, alg.strformat(['0.5y^[2]', '-1']))); print('step2: ', expr); solve = StringAlgSolve(); poly_y = solve.coefPoly(expr, 'y'); print('step3: ', poly_y); roots = np.roots(poly_y); print('step4: ', roots); points = []; for i in range(len(roots)): real = roots[i].real; abs_ = abs(roots[i]); #实数根 if abs(real-abs_) < 0.001: y = roots[i]; points.append([1/y-1, y]); print('step6: ', points); #测试 def tmp2(): solve = StringAlgSolve(); f = alg.strformat(['x^[2]', 'y^[2]', '2xy', '-1']); print('step1: ', f); poly_y_f = solve.coefArray(f, 'y'); print('step2: ', poly_y_f); #以y为参数的二次多项式的系数,消元是消y a1, b1, c1 = poly_y_f[0], poly_y_f[1], poly_y_f[2]; g = alg.strformat(['x^[2]', '4y^[2]', '-1']); print('step1: ', g); poly_y_g = solve.coefArray(g, 'y'); print('step2: ', poly_y_g); #以y为参数的二次多项式的系数,消元是消y a2, b2, c2 = poly_y_g[0], poly_y_g[1], poly_y_g[2]; a1, b1, c1 =solve.str2Array(a1), solve.str2Array(b1),solve.str2Array(c1) a2, b2, c2 =solve.str2Array(a2), solve.str2Array(b2),solve.str2Array(c2) print('step3: ', a1, b1, c1); print('step3: ', a2, b2, c2); poly_x = solve.solveEquationExp2([a1, b1, c1], [a2, b2, c2]); print('step4: ', poly_x); poly_x = solve.coefPoly(poly_x, 'x'); print('step5: ', poly_x); #求得x的根 roots = np.roots(poly_x); print('step6: ', roots); #求方程式<1>的y关于x的表达式 expr_y_root = solve.solvePoly(poly_y_f); print('step7: ', expr_y_root); expr_y_root2 = solve.solvePoly(poly_y_g); print('step7: ', expr_y_root2); #求相交点的坐标对组 points = []; points2 = []; for i in range(len(roots)): real = abs(roots[i].real); abs_ = abs(roots[i]); #实数根 if abs(real-abs_) < 0.001: for j in range(len(expr_y_root)): x = roots[i]; y = solve.strEval(expr_y_root[j], 'x', x); points.append([x, y]); y = solve.strEval(expr_y_root2[j], 'x', x); points2.append([x, y]); print('step8: ', points); print('step8: ', points2); #比较两组点,得出交点[1, 0], [-1, 0] #测试 def tmp3(): part1 = alg.strformat(['b_[1]', 'b_[2]']); part2 = alg.strformat(['b_[1]^[2]', '-4c_[1]']); part3 = alg.strformat(['b_[2]^[2]', '-4c_[2]']); part4 = alg.strpow_n(part1, 2); part5 = alg.stradd(part2, part3); part6= alg.strcombine(alg.stradd(part4, alg.minus(part5))); #print(part6); part7 = alg.strdot(alg.strdot(['(4)'], part2), part3); part7 = alg.strcombine(part7); #print(part7); part8 = alg.strpow_n(part6, 2); part8 = alg.strcombine(part8); #print(part8); result = alg.strcombine(alg.stradd(part8, alg.minus(part7))); #print(result); result = alg.strdot(['(1/16)'], result); print(result); def tmp4(): solve = StringAlgSolve(); a1, b1, c1 =solve.str2Array('(1)'), solve.str2Array('(1)*b_[1]'),solve.str2Array('(1)*c_[1]') a2, b2, c2 =solve.str2Array('(1)'), solve.str2Array('(1)*b_[2]'),solve.str2Array('(1)*c_[2]') print('step3: ', a1, b1, c1); print('step3: ', a2, b2, c2); poly_x = solve.solveEquationExp2([a1, b1, c1], [a2, b2, c2]); print('step4: ', poly_x); #二元二次方程组一般形式 def tmp5(): solve = StringAlgSolve(); #第一个方程 expr_1 = ['A_[1]x^[2]', 'B_[1]xy', 'C_[1]y^[2]', 'D_[1]x', 'E_[1]y', 'F_[1]']; #第二个方程 expr_2 = ['A_[2]x^[2]', 'B_[2]xy', 'C_[2]y^[2]', 'D_[2]x', 'E_[2]y', 'F_[2]']; #系数限定式B_[1]+B_[2]+(A_[1]+D_[1]+A_[2]+D_[2])(C_[1]+C_[2]+E_[1]+E_[2])(A_[1]+A_[2]+C_[1]+C_2]) != 0 g_1 = alg.strformat(['A_[1]', 'A_[2]', 'D_[1]', 'D_[2]']); g_2 = alg.strformat(['C_[1]', 'C_[2]', 'E_[1]', 'E_[2]']); g_3 = alg.strformat(['A_[1]', 'A_[2]', 'C_[1]', 'C_[2]']); g_4 = alg.strformat(['B_[1]', 'B_[2]']); expr_judge = alg.strcombine(alg.stradd(g_4, alg.strdot(alg.strdot(g_1, g_2), g_3))); print('系数表达式', expr_judge, ' != 0'); print(len(expr_judge)); #二元二次方程组一般形式 def tmp6(): solve = StringAlgSolve(); #第一个方程 expr_1 = alg.strformat(['A_[1]x^[2]', 'B_[1]xy', 'C_[1]y^[2]', 'D_[1]x', 'E_[1]y', 'F_[1]']); #第二个方程 expr_2 = alg.strformat(['A_[2]x^[2]', 'B_[2]xy', 'C_[2]y^[2]', 'D_[2]x', 'E_[2]y', 'F_[2]']); #把y用x表示,转换成只含x的二次方程组 expr_1_y = solve.coefArray(expr_1, 'y'); print('step 2: ', expr_1_y); expr_2_y = solve.coefArray(expr_2, 'y'); print('step 2: ', expr_2_y); delta = alg.strformat(['B_[1]^2x^[2]', '2B_[1]E_[1]x', 'E_[1]^2', '-4A_[1]C_[1]x^[2]', '-4C_[1]D_[1]x','-4C_[1]F_[1]']); print('delta = ', delta); #二元二次方程组一般形式 def tmp7(): solve = StringAlgSolve(); #第一个方程 expr_1 = alg.strformat(['A_[1]x^[2]', 'B_[1]xy', 'C_[1]y^[2]', 'D_[1]x', 'E_[1]y', 'F_[1]']); #第二个方程 expr_2 = alg.strformat(['A_[2]x^[2]', 'B_[2]xy', 'C_[2]y^[2]', 'D_[2]x', 'E_[2]y', 'F_[2]']); #此部分为方程(1)中y用x表示的有理部分, 无理部分 coef_y1_real = alg.strformat(['-0.5B_[1]C_[1]^[-1]x', '-0.5E_[1]C_[1]^[-1]']); coef_y1_image = alg.strformat(['0.5C_[1]^[-1]']); delta = alg.strformat(['B_[1]^[2]x^[2]', '2B_[1]E_[1]x', 'E_[1]^[2]', '-4A_[1]C_[1]x^[2]', '-4C_[1]D_[1]x','-4C_[1]F_[1]']); print('delta:'); print(delta); #y^[2]的有理部分, 无理部分,下标系数2作平方理解 coef_y12_real = alg.strcombine(alg.strpow_n(coef_y1_real, 2) +alg.strdot(alg.strpow_n(coef_y1_image, 2), delta)); coef_y12_image = alg.strcombine(alg.strdot(alg.strdot(['(2)'], coef_y1_real), coef_y1_image)); #关于delta^[0.5]的系数,这是一个无理项 #由于代入方程(2)时各次方的系数分别是 p2 = alg.strformat(['C_[2]']); p1 = alg.strformat(['B_[2]x', 'E_[2]']); p0 = alg.strformat(['A_[2]x^[2]', 'D_[2]x', 'F_[2]']); #由此得有理部分,无理部分系数分别是 coef_y2_real = alg.strcombine(alg.strdot(p2, coef_y12_real)+ alg.strdot(p1, coef_y1_real)+ p0); coef_y2_image = alg.strcombine(alg.strdot(p2, coef_y12_image)+ alg.strdot(p1, coef_y1_image)); print('化简至倒数第二步,Δ^[0.5]以外的所有部分'); print(coef_y2_real); print('化简至倒数第二步,Δ^[0.5]的系数部分'); print(coef_y2_image); #向着x的四次方大一统表达式进军, 最后的根式除去 expr_x = alg.strcombine(alg.strpow_n(coef_y2_real, 2)+ alg.minus(alg.strdot(alg.strcombine(alg.strpow_n(coef_y2_image, 2)), delta))); ''' #中间步骤检查 expr_x_0 = alg.strcombine(alg.strpow_n(coef_y2_image, 2));#alg.strcombine(alg.strdot(, delta)); expr_x_1 = alg.strcombine(alg.strdot(expr_x_0, delta)); ''' print('化简成为关于x的四次式'); print(expr_x); coefArray = []; for i in range(len(expr_x)): if (expr_x[i].find('(0.0)')!= -1 or expr_x[i].find('(0)')!=-1): continue; else: coefArray.append(expr_x[i]); print('去除为0的项'); print(coefArray); print(len(coefArray)); #x的四次方式的系数代入数值化简 def tmp8(): solve = StringAlgSolve(); #第一个方程 expr_1 = alg.strformat(['A_[1]x^[2]', 'B_[1]xy', 'C_[1]y^[2]', 'D_[1]x', 'E_[1]y', 'F_[1]']); #第二个方程 expr_2 = alg.strformat(['A_[2]x^[2]', 'B_[2]xy', 'C_[2]y^[2]', 'D_[2]x', 'E_[2]y', 'F_[2]']); valMap = [['A_[1]', 1], ['B_[1]', 2],['C_[1]', 1], ['D_[1]', 0], ['E_[1]', 0],['F_[1]', -1], ['A_[2]', 1], ['B_[2]', 0],['C_[2]', 4], ['D_[2]', 0], ['E_[2]', 0],['F_[2]', -1]]; roots = solve.solveEquationExp2_2(valMap); #两个方程 f = alg.strformat(['x^[2]', 'y^[2]', '2xy', '-1']); print('step1: ', f); poly_y_f = solve.coefArray(f, 'y'); print('step2: ', poly_y_f); g = alg.strformat(['x^[2]', '4y^[2]', '-1']); print('step1: ', g); poly_y_g = solve.coefArray(g, 'y'); print('step2: ', poly_y_g); #求方程式<1>的y关于x的表达式 expr_y_root = solve.solvePoly(poly_y_f); print('step7: ', expr_y_root); expr_y_root2 = solve.solvePoly(poly_y_g); print('step7: ', expr_y_root2); #求相交点的坐标对组 points = []; points2 = []; for i in range(len(roots)): real = abs(roots[i].real); abs_ = abs(roots[i]); #实数根 if abs(real-abs_) < 0.001: for j in range(len(expr_y_root)): x = roots[i]; y = solve.strEval(expr_y_root[j], 'x', x); points.append([x, y]); y = solve.strEval(expr_y_root2[j], 'x', x); points2.append([x, y]); print('step8: '); for i in range(len(points)): if (abs(points[i][0]-points2[i][0]) < 1e-6 and abs(points[i][1]-points2[i][1])<1e-6): print('相交点:[{0}, {1}]'.format(round(points[i][0], 3), round(points[i][1], 3))); </span>
本节到此结束,欲知后事如何,请看下回分解。
时间: 2024-10-14 15:21:09