使用JAVA的forkjoin框架计算给定函数 y=1/x 在定义域 [1,100]上与X轴围成的面积,计算步长0.01

5 篇文章 0 订阅
package ThreadTest.com.jk.ForkJoinTask;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 计算给定函数 y=1/x 在定义域 [1,100]上与X轴围成的面积,计算步长0.01
 * Created by lizq on 2019/5/16.
 */
public class AreaCalc {

    private static final double MAX = 0.01;

    static class MyForkJoinTask extends RecursiveTask<Double> {

        private static AtomicInteger num = new AtomicInteger();
        private static final int step = 10;
        // 子任务开始计算的值
        private double startValue;

        // 子任务结束计算的值
        private double endValue;

        public MyForkJoinTask(double startValue, double endValue) {
            this.startValue = startValue;
            this.endValue = endValue;
        }

        @Override
        protected Double compute() {
            // 如果条件成立,说明这个任务所需要计算的数值分为足够小了
            double totalValue = 0;
            if (endValue - startValue <= MAX) {
                totalValue = (endValue - startValue) * (2.0 / (startValue + endValue));
                System.out.println(num.incrementAndGet() + " : 开始计算的部分:startValue = " + startValue + ";endValue = " + endValue + "; sum = " + totalValue);
                return totalValue;
            }
            // 否则再进行任务拆分,拆分成10个子任务
            else {
                double stepVal = (endValue - startValue) / step;

                for (int i = 0; i < step; i++) {
                    MyForkJoinTask subTask1 = new MyForkJoinTask(startValue + i * stepVal, startValue + (i + 1) * stepVal);
                    subTask1.fork();
                    totalValue += subTask1.join();
                }
                return totalValue;
            }
        }
    }

    public static void main(String[] args) {
        // 这是Fork/Join框架的线程池
        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinTask<Double> taskFuture = pool.submit(new MyForkJoinTask(1, 100));
        try {
            Double result = taskFuture.get();
            System.out.println("result = " + result + "  count " + MyForkJoinTask.num.get());

        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace(System.out);
        }

    }
}

运行结果:
二分法通常用于连续区间上搜索特定函数的极值,例如最大值或最小值。在C语言中,由于我们无法直接对函数进行操作,需要通过循环和条件判断模拟这个过程。对于函数f(x) = x^2 - 3x + 1,这是一个二次函数,其图形是一个开口向上的抛物线,对称为x=3/2。因此,最小值会出现在对称处。 下面是一个简单的二分查找算法示例,假设我们已经定义了`f(x)`的函数指针: ```c #include <stdio.h> #include <math.h> // 定义函数f(x) double f(double x) { return pow(x, 2) - 3 * x + 1; } // 二分查找辅助函数,找到给定函数在指定区间的最小值 double binary_search_min(double a, double b) { if (a > b) { printf("Error: Invalid interval.\n"); return 0; // 或者抛出错误 } double precision = 1e-6; // 设置精度 while (b - a >= precision) { double mid = (a + b) / 2.0; if (f(mid) < f(mid + 1)) { // 如果左部点更优,缩小搜索范围至右半部分 a = mid + 1; } else { // 否则,缩小搜索范围至左半部分 b = mid; } } return f(a); // 返回近似最小值 } int main() { double min_val = binary_search_min(0, 4); // 可以尝试更大范围,比如从负无穷到正无穷,但这里为了简单起见设为0到4 printf("The minimum value of f(x) within the given range is approximately %.4lf\n", min_val); return 0; } ``` 请注意,因为此问题是理论性质的,实际应用中可能需要先确定函数f(x)的定义域,并且在没有导数的情况下,二分法并非最高效的选择。在本例中,计算f'(x) = 2x - 3并设置等于0来找出精确的根,然后验证附近的f值可以更准确地找到最小值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值