2015-03-30 34 views
4

我想用这个方法计算这个方程中x的值为小数点后四位数,并输入p,q,r,s,t,u的值。如何做到这一点?用d&c方法求解一个方程

时间限制:1秒

内存限制:64 MB

enter image description here

float results[10000]; 
int n = 0; 
for(float step = 0; i < 1; i+=0.00001) 
{ 
    results[n] = callProblem(i); 
} 
some divide and conquer approach 

float x = 0; 
float diff = 1;//Startvalue 
while() 
{ 
    result = callProblem(x); 
    if(result > 0) 
    { 
     x -= diff; 
     diff = diff/2; 
     result = callProblem(x); 
    } 
    else 
    { 
     x += diff; 
     diff = diff/2; 
     result = callProblem(x); 
    } 
} 
+0

我们能否看到您在编写算法时的尝试? – 2015-03-30 18:38:20

+0

@Cyber​​neticTwerkGuruOrc:我编辑它。 – sarina 2015-03-30 18:57:29

+0

为什么你想要使用这种二进制搜索?二进制搜索需要排序的数据。给定的函数不一定是单调的。也可能有多个根。 – 2015-03-30 19:27:17

回答

1

我已经广义二分法成未测试递归多段方法:

#include <math.h> 
#include <stdio.h> 
#include <time.h> 

#define P 1.0 
#define q 2.0 
#define r 3.0 
#define s 1.0 
#define t 5.0 
#define u -6.0 

// number of sub-intervals in search interval 
#define INTERVALS 10 
// accuracy limit for recursion 
#define EPSILON 1.0e-4 

double f(double x) { 
    double y = P * exp(-x) + q*sin(x) + r*cos(x) + s*tan(x) + t*x*x + u; 

    return y; 
} 

// sign macro: -1 for val < 0, +1 for val > 0 
#define SGN(val) ((0.0 < val) - (val < 0.0)) 

// return approximate x for function(x)==0.0 
// "function" points to the function to be solved 
double solve(double xMin, double xMax, double (*function)(double)) { 
    double arguments[INTERVALS + 1]; 
    double values[INTERVALS + 1]; 
    int prevSign; 
    int sign; 

    if (fabs(xMax - xMin) < EPSILON) { 
     // interval quite tight already 
     return (xMax + xMin)/2.0; 
    } 

    // split the interval into sub-intervals 
    // evaluate the function for INTERVALS+1 equidistant points 
    // across our search interval 
    for (int i = 0; i <= INTERVALS; i++) { 
     double x = xMin + i*((xMax - xMin)/INTERVALS); 

     arguments[i] = x; 
     values[i] = function(x); 
    } 

    // look for adjacent intervals with opposite function value signs 
    // if f(Xi) and f(Xi+1) have different signs, the root must be 
    // between Xi and Xi+1 
    prevSign = SGN(values[0]); 
    for (int i = 1; i <= INTERVALS; i++) { 
     sign = SGN(values[i]); 

     if (sign * prevSign == -1) { 
      // different signs! There must be a solution 
      // Shrink search interval to the detected sub-interval 
      double x = solve(arguments[i - 1], arguments[i], function); 

      return x; 
     } 
     // remember sign for next round 
     prevSign = sign; 
    } 

    // no solution found: return not-a-number 
    return NAN; 
    } 

int main(unsigned argc, char **argv) { 
    clock_t started = clock(); 
    clock_t stopped; 
    double x = solve(0.0, 1.0, &f); 

    if (isnan(x)) { 
     printf("\nSorry! No solution found.\n"); 
    } else { 
     printf("\nOK! Solution found at f(%f)=%f\n", x, f(x)); 
    } 

    stopped = clock(); 
    printf("\nElapsed: %gs", (stopped - started)/(double)CLOCKS_PER_SEC); 

    // wait for user input 
    getchar(); 
} 
+0

我用一些示例测试你的代码,但程序说“找不到解决方案”。输入:5-5-3-10-15-1,12-15-18-9-4-19,0-0-0-0-1-1,输出应为:0.2879,0.2879,1.0000(另外此功能在0 <= x <= 1时递减) – sarina 2015-03-31 06:18:47

+0

尝试增加INTERVALS参数。查看“值”数组(从调试会话中)。除非有相反的标志,否则该程序无法找到解决方案。 – 2015-03-31 07:08:10

+0

你能告诉我这段代码的算法吗?我的意思是这个代码如何工作?你能更清楚地解释你的算法吗? – sarina 2015-03-31 18:14:12