剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第八转的修炼。设想一个场景:
如果允许你带一台不连网的计算机去参加高考,你会放弃选择一个手拿计算器和草稿本吗
?阿伟决定和小伟来尝试一下用计算机算高考题会是怎样的感觉。
正剧开始:
星历2016年05月25日 17:14:22, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起做着2013年的江苏省数学高考题]。
上面这句话确实在本文而言是名不符实的,因为这张卷子阿伟和[机器小伟]
谁也没做,纯粹贴题了。
粗略看了一下,难度还是5.5环,也就是属于很难的那个行列。试想你每次
为了取得一件宝物都不得不受到5.5次调戏的那种感觉吧,就是这样。
当年阿伟从来没敢交过白卷,现在胆也肥了,也敢交白卷了,真是非常潇洒的感觉。
这次呢,阿伟和[机器小伟]主要在研究怎样解二元二次方程组,先看这个测试题吧:
这两条曲线就是这么个图:
之所以能解二元二次方程组,是因为它们系数之中满足这样的关系:
<span style="font-size:18px;">>>> ['(0)', '(2)*b_[1]^[1]*b_[2]^[1]', '(0)', '(4)*c_[1]^[1]', '(4)*c_[2]^[1]'] ['(4)*b_[1]^[2]*b_[2]^[2]', '(-16)*b_[1]^[2]*c_[2]^[1]', '(-16)*b_[2]^[2]*c_[1]^[1]', '(64)*c_[1]^[1]*c_[2]^[1]'] ['(0)', '(0)', '(0)', '(0)', '(4)*b_[1]^[2]*b_[2]^[2]', '(16)*b_[1]^[1]*b_[2]^[1]*c_[1]^[1]', '(16)*b_[1]^[1]*b_[2]^[1]*c_[2]^[1]', '(16)*c_[1]^[2]', '(32)*c_[1]^[1]*c_[2]^[1]', '(16)*c_[2]^[2]'] ['(0)', '(0)', '(16)*b_[1]^[1]*b_[2]^[1]*c_[1]^[1]', '(16)*b_[1]^[1]*b_[2]^[1]*c_[2]^[1]', '(16)*c_[1]^[2]', '(-32)*c_[1]^[1]*c_[2]^[1]', '(16)*c_[2]^[2]', '(16)*b_[1]^[2]*c_[2]^[1]', '(16)*b_[2]^[2]*c_[1]^[1]'] #测试,二元二次方程组的根的恒等式,已消去一元 #先要保证两个方程的消去的那个元的最高次项系数为1 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); >>> ['(0.0)', '(0.0)', '(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]']</span>
<span style="font-size:18px;"> var s = [ '在a_[1] == a_[2] == 1时', '((b_[1]-b_[2])^[2]-(b_[1]^[2]-4c_[1]+b_[2]^[2]-4c_[2]))^[2]', '== 4(b_[1]^[2]-4c_[1])(b_[2]^[2]-4c_[2])', ' ', '这个恒等式可以化为:', '(1)*b_[1]*b_[2]*c_[1]+(1)*b_[1]*b_[2]*c_[2]', '+(1)*c_[1]^[2]-(2)*c_[1]*c_[2]+(1)*c_[2]^[2]', '+(1)*b_[1]^[2]*c_[2]+(1)*b_[2]^[2]*c_[1]', ' = 0' ];</span>
再给工具中新添两个方法:
<span style="font-size:18px;"> #把一个只包括+号的多项式字符串拆分成多项式数组 #如'(1)*x^[2]+(-1)' => ['(1)*x^[2]', '(-1)'] def str2Array(self, str1): array = []; #加号位置 signIndex = str1.find('+'); print(signIndex); start = 0; count = 0; 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; >>> 9 ['(1)*x^[2]', '(-1)'] #解二元二次方程组 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; </span>
这样就可以进行套路化的解题了:
<span style="font-size:18px;">>>> step1: ['(1)*x^[2]', '(1)*y^[2]', '(2)*x*y', '(-1)'] step2: ['(1)', '(2)*x', '(1)*x^[2]+(-1)'] step1: ['(1)*x^[2]', '(4)*y^[2]', '(-1)'] step2: ['(4)', '0', '(1)*x^[2]+(-1)'] step3: ['(1)'] ['(2)*x'] ['(1)*x^[2]', '(-1)'] step3: ['(4)'] ['0'] ['(1)*x^[2]', '(-1)'] step4: ['(0)', '(4)*x^[4]', '(-4)*x^[2]'] step5: [4, 0, -4, 0, 0] step6: [ 1. -1. 0. 0.] step7: ['(((-((2)*x)))+(((((2)*x)^[2])+((-4)*(((1))*((1)*x^[2]+(-1)))))^[0.5]))/((2)*((1)))', '(((-((2)*x)))-(((((2)*x)^[2])+((-4)*(((1))*((1)*x^[2]+(-1)))))^[0.5]))/((2)*((1)))'] step8: [[1.0, 0.0], [1.0, -2.0], [0.0, 1.0], [0.0, -1.0], [0.0, 1.0], [0.0, -1.0]] #测试 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]</span>
解答到此结束,下面是一些过程产物,可忽略。
<span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0,180); //坐标轴设定 var scaleX = 2*r, scaleY = 2*r; var spaceX = 0.4, spaceY = 0.4; var xS = -10, xE = 10; var yS = -10, yE = 10; config.axisSpacing(xS, xE, spaceX, scaleX, 'X'); config.axisSpacing(yS, yE, spaceY, scaleY, 'Y'); var transform = new Transform(); //存放函数图像上的点 var a = [], b = [], c = [], d = []; //需要显示的函数说明 //希腊字母表(存此用于Ctrl C/V //ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ //αβγδεζηθικλμνξοπρστυφχψω var f1 = 'x+y = 1', f2 = 'x+y=-1', f3 = 'x^[2]+4y^[2] = 1', f4 = ''; //函数描点 //参数方程 var x, y; var pointA = []; for (var thita = 0; thita < Math.PI*2; thita +=Math.PI/48) { x = Math.cos(thita); a.push([x, 1-x]); b.push([x, -1-x]); c.push([Math.cos(thita), 0.5*Math.sin(thita)]); } //存放临时数组 var tmp = []; //显示变换 if (a.length > 0) { a = transform.scale(transform.translate(a, 0, 0), scaleX/spaceX, scaleY/spaceY); //函数1 tmp = [].concat(a); shape.pointDraw(tmp, 'red'); tmp = [].concat(a); shape.multiLineDraw(tmp, 'pink'); plot.setFillStyle('red'); plot.fillText(f1, 100, -90, 200); } //显示变换 if (b.length > 0) { b = transform.scale(transform.translate(b, 0, 0), scaleX/spaceX, scaleY/spaceY); //函数1 tmp = [].concat(b); shape.pointDraw(tmp, 'red'); tmp = [].concat(b); shape.multiLineDraw(tmp, 'green'); plot.setFillStyle('green'); plot.fillText(f2, 100, -120, 200); } //显示变换 if (c.length > 0) { c = transform.scale(transform.translate(c, 0, 0), scaleX/spaceX, scaleY/spaceY); //函数1 tmp = [].concat(c); shape.pointDraw(tmp, 'blue'); tmp = [].concat(c); shape.multiLineDraw(tmp, '#0088FF'); plot.setFillStyle('blue'); plot.fillText(f3, 100, -150, 200); } } </span>
<span style="font-size:18px;"> //测试 if (1) { var mathText = new MathText(); //希腊字母表(存此用于Ctrl C/V //ΑΒΓΔΕΖΗ ΘΙΚΛΜΝΞ ΟΠΡ ΣΤΥ ΦΧΨ Ω //αβγδεζη θικλμνξ οπρ στυ φχψ ω //希腊大小写字母 var Gc = 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ'; var Gs = 'αβγδεζηθικλμνξοπρστυφχψω'; var s = [ /* '测试题:求交点', 'x^[2]+2xy+y^[2]=1 _[(1)]', 'x^[2]+4y^[2] = 1 _[(2)]', ' ', 'step1: 两曲线的多项式', 'step2: 消去y元', 'step3: 将两组二次系数导入方程恒等式', 'step4: 得到方程恒等式,这是关于元x的四次恒等式,不含根号', 'step5: 导出恒等式的系数阵列。',*/ 'step6: 解恒等式的根,有四个根。', 'step7: 求得曲线方程中y元关于x元的根的代数式。', 'step8: 把代数式求值,得到交点坐标' ];</span>
从此以后,[机器小伟]就可以纵横圆锥曲线了。
留个快照吧:
现在阿伟真的很爽,觉得外边的风景也漂亮起来了。
本节到此结束,欲知后事如何,请看下回分解。
注:本节中的解法虽然没错,但最后结果却是错的,原因出在那个恒等式不够强大,
由于时间不够,虽然阿伟意识到解错了,也没办法,在下一节中会给出正确的解法
以及结果,大家可以去查看。当然,知道这样解是得不出正确结果,也是一种收获。
时间: 2024-10-31 18:11:47