С

问题描述 投票:0回答:1

T=s1/(v1+k)+s2/(v2+k)+s3/(v3+k)..+vn/(sn+k) 如果我知道除了 k 之外的所有内容,我怎样才能找到它? n (1 ≤ n ≤ 1000) t (1 ≤ t ≤ 10^6) s (1 ≤ s ≤ 1000) v (|v| ≤ 1000) 如果我知道 T 应该是什么并且 k 是 float 类型,我应该如何编写代码以便它选择 k。

我尝试了限制为-2000 2000的二分搜索,但我不知道什么时候上限应该是平均值,什么时候应该是平均值下限

c math floating-point double mathematical-optimization
1个回答
0
投票
#include <stdio.h>
#include <stdlib.h>

#define UNUSED(v) ((void) (v))

float find_k(int n, float s[], float v[], float T) {
    float low = -2000;  // Adjust initial bounds if needed
    float high = 2000;
    float mid;
    float calculatedT;

    while (high - low >= 0.0001) {  // Adjust tolerance as needed
        mid = (low + high) / 2;
        calculatedT = 0;

        for (int i = 0; i < n; i++) {
            calculatedT += s[i] / (v[i] + mid);
        }

        if (calculatedT == T) {
            return mid;
        } else if (calculatedT < T) {
            high = mid;
        } else {
            low = mid;
        }
    }

    return mid;  // Return approximate value if exact match not found
}

int
main(int argc, char **argv)
{
    int n = ...;  // Assign your values for n, s[], v[], and T
    float s[n];
    float v[n];
    float T = ...;

    UNUSED(argc);
    UNUSED(argv);

    float k = find_k(n, s, v, T);

    printf("The value of k is: %.4f\n", k);

    return EXIT_SUCCESS;
}

如果您对 k 的可能范围没有任何先验知识,那么在这种情况下确定二分搜索的绝对边界是很困难的。

  1. 指数搜索:
    • k
      的较小正值开始。
    • 在每次迭代中将
      k
      的值加倍,直到计算出的
      T
      变得大于所需的
      T
    • 一旦超出所需的
      T
      ,请在最后一个
      k
      值(其中
      T
      较小)和当前
      k
      值(其中
      T
      变大)的范围内使用二分搜索。
  2. 迭代细化:
    • k
      的较小正值开始。
    • 继续以特定增量(例如,
      k
      )增加
      1
      ,直到计算出的
      T
      变得更接近(在公差范围内)所需的
      T
    • 一旦足够接近,请使用较小的增量(例如,
      0.1
      )进行进一步细化。
  3. 混合方法:
    • 将指数搜索的初始猜测与迭代细化相结合。
    • 执行几次指数搜索迭代以获得
      k
      范围的粗略估计。
    • 然后,在估计范围内切换到二分搜索以获得更精细的精度。
© www.soinside.com 2019 - 2024. All rights reserved.