gpt4 book ai didi

algorithm - 确定是否有任何 double 组合从设定总和到目标值

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:10:46 27 4
gpt4 key购买 nike

我在工作中遇到了一个让我有点难过的问题。我需要验证给定剂量的药物是否可以由药丸剂量大小的任意组合构成。

例如

dose = 400.0
sizes= [15.0, 30.0, 45.0]

400 不能由这些值的任何总和创建(至少我认为这是真的)。但是,如果变量更改为:

dose = 400.0 
sizes = [10.0, 15.0, 30.0]

我希望结果为真,因为 10x40 = 400。或者如果这是 senario:

dose = 405.0
sizes = [2.5, 15.0, 30.0, 100.0]

我还希望得到一个真实的结果,因为 4x100 + 2X2.5 = 405。

您将如何编写此算法?它似乎与一个Subset Sum有关算法,但在我的例子中,我希望允许多次出现任何设置项作为解决方案的一部分。

最佳答案

以下 Java 实现解决了 double 值的问题。

备注 - Java is known for its inaccuracy在处理基于 double / float 的算术时。但是,对于较低的精度,此解决方案应该足够了。自然地,该算法可以用不太受精度问题影响的编码语言实现,例如 C++。使用公差阈值检查更新算法。这意味着现在也可以处理更精细的精度。感谢aschepler用于指出有问题的精度用例。

已经使用 coin change problem 实现了两种算法(基于经典的 an online java compiler ) :

  • 一个简单地返回一个 bool 值,指示是否存在提供给定总和的子集
  • 第一个算法的扩展,列出了子集中使用的值

代码如下:

import java.util.*;

public class MyClass {
public static void main(String args[]) {

double set[] = {2.5, 15.0, 30.0, 100.0};
double sum = 405.0;
int n = set.length;
if (count(set, n, sum))
System.out.println("Found a subset with given sum");
else
System.out.println("No subset with given sum");

List<Double> listing = new ArrayList<Double>();
if (countList(set, n, sum,listing))
System.out.println("Found a subset with given sum: " + listing);
else
System.out.println("No subset with given sum");
}

public static boolean count( double S[], int m, double n)
{
// If n is near 0 then there is 1 solution
// (do not include any coin)
if (n >= -0.00001 && n <= 0.00001)
return true;

// If n is less than 0 then no
// solution exists
if (n < 0)
return false;

// If there are no coins and n
// is greater than 0, then no
// solution exist
if (m <=0 && n > 0)
return false;

// count is true if one of the solutions (i) including S[m-1] (ii) excluding S[m-1] is true
return count( S, m - 1, n ) ||
count( S, m, n-S[m-1] );
}
public static boolean countList( double S[], int m, double n, List<Double> listing)
{
// If n is near 0 then there is 1 solution
// (do not include any coin)
if (n >= -0.00001 && n <= 0.00001)
return true;

// If n is less than 0 then no
// solution exists
if (n < 0)
return false;

// If there are no coins and n
// is greater than 0, then no
// solution exist
if (m <=0 && n > 0)
return false;

// count is true if one of the solutions (i) including S[m-1] (ii) excluding S[m-1] is true
List<Double> with = new ArrayList<>();
with.add(S[m-1]);
List<Double> without = new ArrayList<>();
boolean withResult = countList( S, m, n-S[m-1], with );
boolean withoutResult = countList( S, m - 1, n, without );
if(withResult) {
listing.addAll(with);
}
else if (withoutResult) {
listing.addAll(without);
}
return withResult || withoutResult;
}
}

输出:

Found a subset with given sum
Found a subset with given sum: [100.0, 100.0, 100.0, 100.0, 2.5, 2.5]

这是一个更具挑战性的输入:

double set[] = {2.5, 15.0, 30.0, 100.0, 0.2, 0.3};
double sum = 165.9;
Found a subset with given sum
Found a subset with given sum: [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 100.0, 2.5, 2.5, 2.5, 2.5, 2.5]

还有:

double set[] = {0.2, 0.3, 2.5, 15.0, 30.0, 100.0};
double sum = 148.6;
Found a subset with given sum
Found a subset with given sum: [100.0, 30.0, 15.0, 2.5, 0.3, 0.3, 0.3, 0.2]

以下精度修复:

double set[] = {0.05, 0.012, 0.008};
double sum = 0.1;
Found a subset with given sum
Found a subset with given sum: [0.008, 0.008, 0.008, 0.008, 0.008, 0.008, 0.008, 0.008, 0.008, 0.008, 0.008, 0.012]

引用资料:

关于algorithm - 确定是否有任何 double 组合从设定总和到目标值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50848128/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com