我有以下情况:
n
个随机数sum == x
(x是用户设置的数字)sum != x
然后继续运行循环sum == x
,则显示总计为x
的随机数列表基于这个逻辑,我能够做到这一点,但实现结果需要永远,有没有更好的方法来解决这个问题?
static void Main(string[] args)
{
Console.WriteLine("starting...");
List<int> checkList = generate(5);
while(!checkSum(checkList, 100))
{
checkList = generate(5)
}
Console.WriteLine("done!");
}
private static bool checkSum(List<int> n, int sum)
{
if(n.Sum() == sum)
{
return true;
}
else
{
return false;
}
}
public static List<int> generate(int n)
{
Random rng = new Random();
List<int> list = new List<int>();
for (int i = 0; i < 5; i++)
{
//int ran = some random number
list.Add(ran);
}
return list;
}
修改
我的方案是获取总计为100的随机整数的n
组合。组合的数量取自用户的输入。因此,该程序将提供n
个可能的组合,总计最多100个。
可能的组合:
答案 0 :(得分:2)
如果您有固定的金额和固定数量的元素,请将问题视为分区。例如:
#hot_news .active{
background-color: #034121;
}
示例输出:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PartitionAndAllocateTEst
{
class Program
{
static void Main(string[] args)
{
var rand = new Random();
int desiredTotal = 100;
int partitions = 5;
for (int i = 0; i < 10; i++)
{
List<int> result = GetRandomCollection(rand, desiredTotal, partitions);
Console.WriteLine(string.Join(", ", result.Select(r => r.ToString()).ToArray()));
}
}
private static List<int> GetRandomCollection(Random rand, int desiredTotal, int partitions)
{
// calculate the weights
var weights = new List<double>();
for (int i = 0; i < partitions; i++)
{
weights.Add(rand.NextDouble());
}
var totalWeight = weights.Sum();
// allocate the integer total by weight
// http://softwareengineering.stackexchange.com/questions/340393/allocating-an-integer-sum-proportionally-to-a-set-of-reals/340394#340394
var result = new List<int>();
double allocatedWeight = 0;
int allocatedCount = 0;
foreach (var weight in weights)
{
var newAllocatedWeight = allocatedWeight + weight;
var newAllocatedCount = (int)(desiredTotal * (newAllocatedWeight / totalWeight));
var thisAllocatedCount = newAllocatedCount - allocatedCount;
allocatedCount = newAllocatedCount;
allocatedWeight = newAllocatedWeight;
result.Add(thisAllocatedCount);
}
return result;
}
}
}
答案 1 :(得分:0)
您可以尝试使用遗传算法。从一组人口开始,例如,100组五个随机整数。总结每一组。选择50个更好的集合,其中总和更接近100.保持更好的50,转储其他50并用最佳50的调整版本替换它们。调整用另一个随机整数替换集合中的一个整数。
只要总体中的一个成员总和为100,就将其拉出到输出数组中,并使用新生成的五个整数集组成总体。
遗传算法比蛮力更快地工作。
答案 2 :(得分:-1)
我不明白为什么你会被投票。你的问题很清楚,你已经知道你的算法很糟糕。
我会在两次传球中解决这个问题。第1遍通过确定从每个部分点到达最终答案的方式有多少。第2遍正在选择一条随机路径。
对于第1遍,您将构建一个数组数组。根据您需要他们总结的数量,可以通过多少种方式获得答案? (有关如何执行此操作的更多信息,请搜索动态编程。)
在第2阶段,你继续前进。您知道每个步骤有多少种方法可以完成您的任务,以及您可以选择的每个值的数量。因此,您知道选择每个值的概率。因此,在(0, 1)
中选择一个随机值,浏览答案,选择下一个数字,然后继续。
这个一般策略不仅适用于数字。它可以用于生成任何可以使用动态编程技术计算的随机样本。