- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
更新 1:
下面提供的一些解决方案看起来不错。但是,我只知道循环在其父循环的迭代确定后迭代的次数。所以我不能事先计算所有的迭代。
原问题:
我在一个类似的程序中嵌入了循环:
程序 1:
using System;
using System.Threading;
namespace time_remaining_loop_strip
{
class Program
{
static void Main(string[] args)
{
var random = new Random();
Console.Clear();
// Simulate initiation delay
Console.WriteLine("initiate");
Thread.Sleep(random.Next(100, 1000));
int intCount = random.Next(1, 10);
for (int loop1 = 0; loop1 <= intCount; loop1++)
{
// Simulate loop1 delay
Console.WriteLine("\tloop1");
Thread.Sleep(random.Next(100, 1000));
for (int loop2 = 0; loop2 <= random.Next(1, 10); loop2++)
{
// Simulate loop2 delay
Console.WriteLine("\t\tloop2");
Thread.Sleep(random.Next(100, 1000));
for (int loop3 = 0; loop3 <= random.Next(1, 10); loop3++)
{
// Simulate loop3 delay
Console.WriteLine("\t\t\tloop3");
Thread.Sleep(random.Next(100, 1000));
for (int loop4 = 0; loop4 <= random.Next(1, 10); loop4++)
{
// Simulate loop4 delay
Console.WriteLine("\t\t\t\tloop4");
Thread.Sleep(random.Next(100, 1000));
}
}
}
}
}
}
}
我正在尝试显示剩余处理时间 (ETA),因此我可以看到对上述循环序列完成之前剩余时间的粗略估计
using System;
using System.Threading;
namespace time_remaining
{
class Program
{
public static TimeSpan ComputeRemaining((int count, DateTime time) start, (int count, DateTime time) current, int end) =>
current.count - start.count == 0
? TimeSpan.MaxValue
: TimeSpan.FromSeconds((end - current.count) * current.time.Subtract(start.time).TotalSeconds / (current.count - start.count));
static void Main(string[] args)
{
Console.Clear();
var random = new Random();
int Count = random.Next(10, 60);
DateTime startTime = DateTime.Now;
for (int i = 0; i <= Count; i++)
{
Thread.Sleep(random.Next(100, 2000));
TimeSpan timeRemaining = ComputeRemaining((0, startTime), (i, DateTime.Now), Count);
Console.SetCursorPosition(0,0);
Console.Write("ETA: ");
Console.Write(String.Format("{0} Days, {1} Hours, {2} Minutes, {3} Seconds", timeRemaining.Days.ToString().PadLeft(3,'0'), timeRemaining.Hours.ToString().PadLeft(2,'0'), timeRemaining.Minutes.ToString().PadLeft(2,'0'), timeRemaining.Seconds.ToString().PadLeft(2,'0')));
}
}
}
}
当我尝试将 Prog1 的 ETA 方面合并到 Prog2 中时,它似乎效果不佳:
using System;
using System.Threading;
namespace time_remaining_loop_strip
{
class Program
{
public static TimeSpan ComputeRemaining((int count, DateTime time) start, (int count, DateTime time) current, int end) =>
current.count - start.count == 0
? TimeSpan.MaxValue
: TimeSpan.FromSeconds((end - current.count) * current.time.Subtract(start.time).TotalSeconds / (current.count - start.count));
static void Main(string[] args)
{
DateTime startTime = DateTime.Now;
var random = new Random();
Console.Clear();
// Simulate initiation delay
//Console.WriteLine("initiate");
Thread.Sleep(random.Next(100, 1000));
int intCount = random.Next(1, 10);
for (int loop1 = 0; loop1 <= intCount; loop1++)
{
// Simulate loop1 delay
//Console.WriteLine("\tloop1");
Thread.Sleep(random.Next(100, 1000));
for (int loop2 = 0; loop2 <= random.Next(1, 10); loop2++)
{
// Simulate loop2 delay
//Console.WriteLine("\t\tloop2");
Thread.Sleep(random.Next(100, 1000));
for (int loop3 = 0; loop3 <= random.Next(1, 10); loop3++)
{
// Simulate loop3 delay
//Console.WriteLine("\t\t\tloop3");
Thread.Sleep(random.Next(100, 1000));
for (int loop4 = 0; loop4 <= random.Next(1, 10); loop4++)
{
// Simulate loop4 delay
//Console.WriteLine("\t\t\t\tloop4");
Thread.Sleep(random.Next(100, 1000));
}
}
}
TimeSpan timeRemaining = ComputeRemaining((0, startTime), (loop1, DateTime.Now), intCount);
Console.SetCursorPosition(0,0);
Console.Write("ETA: ");
Console.Write(String.Format("{0} Days, {1} Hours, {2} Minutes, {3} Seconds", timeRemaining.Days.ToString().PadLeft(3,'0'), timeRemaining.Hours.ToString().PadLeft(2,'0'), timeRemaining.Minutes.ToString().PadLeft(2,'0'), timeRemaining.Seconds.ToString().PadLeft(2,'0')));
}
}
}
}
这似乎根本不起作用。它确实显示了 ETA,但由于循环的结构方式,它在显示任何内容之前有很长时间的延迟。
最佳答案
由于您刚刚构建了一个实际发生的简单模型的让步(您有一系列可变延迟和计数的嵌套过程,甚至在运行时才能确定),您目前要求的是一个随机数预测器。n
之间会有& m
o
之间的周期(在您的示例中为 1 和 10) & p
持续时间(100 和 1000 毫秒),但仍然是随机的……好吧,随机量化为频段。您编写它的方式是随机掷骰子(骰子没有内存),尽管在实践中似乎更有可能一个周期的持续时间必须在某种程度上暗示下一个周期的持续时间(这就是您的方式写作 ComputeRemaining
)并且在一个波段内,一个循环的计数必须有助于下一个循环的计数。
因此,尽管它看起来很简单 Prog2
涵盖我们的示例.. 给定一个已知的循环计数,其中每个循环需要一个随机持续时间(实际上是 pick(n,m)^3*pick(o,p)
.. 但这仍然只是一个随机数) - 预测结束。出于报告目的,您还需要重构它以考虑内部循环,但这实际上是相同的过程。 (^3是简化,实际上是一系列独立的pick相乘)
好的,所以我们不需要谈论时间/延迟(我的意思是......你显然想要那个,但它只是代表 future 的一些数字 - TimeSpan
是 long
从一段时间以来 x 滴答的计数...完成时间只是 Now + x*tick
)。所以我们可以将其简化为 long
预测器。
设置
interface IAvger
{
public double Avg { get; }
}
interface IAdder
{
void Add(long value);
}
class Mean
{
private int _count = 0;
public double Total { get; private set; } = 0;
public double? Avg => _count == 0 ? null : (double?)(Total / _count);
public void Add(double val)
{
Total += val;
_count++;
}
}
您可以忽略接口(interface)(我在切换潜在解决方案时使用了它们)。类(class)
Mean
应该很熟悉......它计算多个值的平均平均值,随着发现更多值而缩放/适应。
/// <summary>
/// Equivalent to your ComputeRemaining
/// </summary>
class RunningAvg : IAvger, IAdder
{
private Mean _mean = new Mean();
private readonly double _guess;
public RunningAvg(double guess)
{
_guess = guess;
}
public double Avg => _mean.Avg ?? _guess;
public void Add(long value) => _mean.Add(value);
}
这相当于您的
ComputeRemaining
.
guess
的值有助于在没有其他信息时进行早期预测(与
TimeSpan.Max
等效)
/// <summary>
/// Drop the lowest and highest value
/// - Fairly typical in stats, however note this is only one biggest/smallest
/// (will work best when the standard devation is low, and outliers
/// are rare)
/// </summary>
class IgnoreExtremes : IAvger, IAdder
{
private long? _worst;
private long? _best;
private Mean _mean = new Mean();
private readonly int _wt;
private readonly double _guess;
public IgnoreExtremes(double guess, int weight = 4)
{
_wt = weight;
_guess = guess;
}
public long Best => _best ?? (long)Math.Round(_guess);
public long Worst => _worst ?? (long)Math.Round(_guess);
public double Avg
{
get
{
var avg = _mean.Avg;
if (!avg.HasValue) return _guess;
return (Best + _wt * avg.Value + Worst) / (2 + _wt);
}
}
public void Add(long value)
{
if (!_best.HasValue)
{
_best = value;
}
else if (value < _best)
{
_mean.Add(_best.Value);
_best = value;
}
else if (!_worst.HasValue)
{
_worst = value;
}
else if (value > _worst)
{
_mean.Add(_worst.Value);
_worst = value;
}
else
{
_mean.Add(value);
}
}
}
终于有数据了!
IgnoreExtremes
抑制最高和最低(单个)值。在科学抽样中,忽略这些是相当典型的,但是对于数字的真实随机分布(例如掷骰子或
random.Next
),只会丢弃一个极端。这应该比
RunningAvg
预测出更好的数字.请注意,这是一种加权平均形式,您可以通过提供
weight
对其进行(略微)调整构建时的值(value)(
wt=4
相当常见),或搭售
_wt
至
_mean.count
(需要更改一些代码)
class IgnoreStdDevOutlier : IAvger, IAdder
{
private const int AT_LEAST = 5;
private Mean _mean = new Mean();
private readonly List<long> _vals = new List<long>();
private readonly double _guess;
//private long _tot;
private readonly double _outlierStdDevMulti;
public IgnoreStdDevOutlier(double guess, double outlierStdDevMulti = 2)
{
_guess = guess;
_outlierStdDevMulti = outlierStdDevMulti;
}
private double StdDev()
{
var avg = Avg;
double tot = 0;
foreach (var item in _vals)
tot += (item - avg) * (item - avg);
return Math.Sqrt(tot / (_vals.Count - 1));
}
public void Add(long value)
{
_vals.Add(value);
if (_vals.Count > AT_LEAST)
{
var avg = Avg;
var sd = StdDev();
var min = avg - _outlierStdDevMulti * sd;
var max = avg + _outlierStdDevMulti * sd;
//Ignore outliers
if (value < min || value > max) return;
}
_mean.Add(value);
}
public double Avg => _mean.Avg ?? 0;
}
另一种统计方法是忽略大于
n*StandardDeviation
的值。从平均值,其中
n
通常是 2 或 3(你会发现相互矛盾的意见)。看到的所有值都是标准偏差的一部分,但只有那些不是异常值的值才被视为平均值的一部分。这最终就像一个抑制因子,防止估计摆动太大。
class Performance
{
private readonly List<long> _set = new List<long>();
private long _actual;
public void Add(long item) => _set.Add(item);
public void SetFinal(long final) => _actual = final;
public void Report()
{
foreach (var item in _set)
{
Console.WriteLine("{0} {1} = {2}", item, _actual, (item / (double)_actual - 1) * 100);
}
}
}
真正的猜测无法知道最终的 (
_actual
) 值,但是这个类允许我们看到到目前为止猜测是如何进行的。
class Program
{
const int MIN_MSEC = 100;
const int MAX_MSEC = 1000;
const int MIN_LOOP = 10;
const int MAX_LOOP = 50;
static void C(Random random)
{
int nm = random.Next(MAX_LOOP, MAX_LOOP);
var guess = (double)((MAX_LOOP + MIN_LOOP) / 2 * (MAX_MSEC + MIN_MSEC) / 2);
var predict = new RunningAvg(guess);
//var predict = new IgnoreExtremes(guess);
//var predict = new IgnoreStdDevOutlier(guess,3);
var per = new Performance();
long tot = 0;
for (int i = 0; i <= nm; i++)
{
var op = random.Next(MIN_MSEC, MAX_MSEC);
predict.Add(op);
per.Add((long)Math.Round(predict.Avg * nm));
tot += op;
}
per.SetFinal(tot);
per.Report();
}
static void Main(string[] args)
{
var random = new Random();
C(random);
}
}
您可以忽略在名为
C
的方法中完成的工作。 (只是代码的一个副作用 -
A
是您的 Prog1,而
B
是 Prog2)。内
C
尝试更改
RunningAvg
中的哪一个,
IgnoreExtremes
或
IgnoreStdDevOutlier
未注释。因为,同样,写的是骰子随机,你不能把单次运行作为一个好的基准。下一阶段是将其包装在重复运行中并取预测的标准偏差的平均值(或者可能只是后期预测 - 用户可能不介意早期估计是否相距甚远,只要结束它没有跳来跳去) - 但我没时间了。我找到
IgnoreStdDevOutlier
,平均而言,到最后会很快收敛到正确的答案,偏离了 0-1%。
IgnoreExtremes
由于只忽略了一个极端(在每个方向上),所以它是
IgnoreStdDevOutlier
的轻量版本。 .如果您的数据不是随机的,并且只是偶尔出现极端情况 - 它会做得很好。
RunningAvg
在某些时候实际上并没有表现得非常糟糕,其他时候它一直以两位数的百分比下降。随机数,如果它们很容易预测就好了。
Timespan.Ticks
是长。所有这些都是为了预测一个长期的,这可以认为是当时和现在的区别。直接切换使用 new Timespan(long ticks)
构建跨度,以及 DateTime.Now.Subtract(startTime).Ticks
从跨度中获得长。显然,所有这些类都可以为 TimeSpan
重写。而不是 long
.. 不幸的是,没有一个简单的通用 where
包含 long
的约束和 TimeSpan
关于c# - 将 ETA 添加到嵌入式循环序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63457313/
我是 PHP 新手。我一直在脚本中使用 for 循环、while 循环、foreach 循环。我想知道 哪个性能更好? 选择循环的标准是什么? 当我们在另一个循环中循环时应该使用哪个? 我一直想知道要
我在高中的编程课上,我的作业是制作一个基本的小计和顶级计算器,但我在一家餐馆工作,所以制作一个只能让你在一种食物中读到。因此,我尝试让它能够接收多种食品并将它们添加到一个价格变量中。抱歉,如果某些代码
这是我正在学习的一本教科书。 var ingredients = ["eggs", "milk", "flour", "sugar", "baking soda", "baking powder",
我正在从字符串中提取数字并将其传递给函数。我想给它加 1,然后返回字符串,同时保留前导零。我可以使用 while 循环来完成此操作,但不能使用 for 循环。 for 循环只是跳过零。 var add
编辑:我已经在程序的输出中进行了编辑。 该程序要求估计给定值 mu。用户给出一个值 mu,同时还提供了四个不等于 1 的不同数字(称为 w、x、y、z)。然后,程序尝试使用 de Jaeger 公式找
我正在编写一个算法,该算法对一个整数数组从末尾到开头执行一个大循环,其中包含一个 if 条件。第一次条件为假时,循环可以终止。 因此,对于 for 循环,如果条件为假,它会继续迭代并进行简单的变量更改
现在我已经习惯了在内存非常有限的情况下进行编程,但我没有答案的一个问题是:哪个内存效率更高;- for(;;) 或 while() ?还是它们可以平等互换?如果有的话,还要对效率问题发表评论! 最佳答
这个问题已经有答案了: How do I compare strings in Java? (23 个回答) 已关闭 8 年前。 我正在尝试创建一个小程序,我可以在其中读取该程序的单词。如果单词有 6
这个问题在这里已经有了答案: python : list index out of range error while iteratively popping elements (12 个答案) 关
我正在尝试向用户请求 4 到 10 之间的整数。如果他们回答超出该范围,它将进入循环。当用户第一次正确输入数字时,它不会中断并继续执行 else 语句。如果用户在 else 语句中正确输入数字,它将正
我尝试创建一个带有嵌套 foreach 循环的列表。第一个循环是循环一些数字,第二个循环是循环日期。我想给一个日期写一个数字。所以还有另一个功能来检查它。但结果是数字多次写入日期。 Out 是这样的:
我想要做的事情是使用循环创建一个数组,然后在另一个类中调用该数组,这不会做,也可能永远不会做。解决这个问题最好的方法是什么?我已经寻找了所有解决方案,但它们无法编译。感谢您的帮助。 import ja
我尝试创建一个带有嵌套 foreach 循环的列表。第一个循环是循环一些数字,第二个循环是循环日期。我想给一个日期写一个数字。所以还有另一个功能来检查它。但结果是数字多次写入日期。 Out 是这样的:
我正在模拟一家快餐店三个多小时。这三个小时分为 18 个间隔,每个间隔 600 秒。每个间隔都会输出有关这 600 秒内发生的情况的统计信息。 我原来的结构是这样的: int i; for (i=0;
这个问题已经有答案了: IE8 for...in enumerator (3 个回答) How do I check if an object has a specific property in J
哪个对性能更好?这可能与其他编程语言不一致,所以如果它们不同,或者如果你能用你对特定语言的知识回答我的问题,请解释。 我将使用 c++ 作为示例,但我想知道它在 java、c 或任何其他主流语言中的工
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我是 C 编程和编写代码的新手,以确定 M 测试用例的质因数分解。如果我一次只扫描一次,该功能本身就可以工作,但是当我尝试执行 M 次时却惨遭失败。 我不知道为什么 scanf() 循环有问题。 in
这个问题已经有答案了: JavaScript by reference vs. by value [duplicate] (4 个回答) 已关闭 3 年前。 我在使用 TSlint 时遇到问题,并且理
我尝试在下面的代码中添加 foreach 或 for 循环,以便为 Charts.js 创建多个数据集。这将允许我在此折线图上创建多条线。 我有一个 PHP 对象,我可以对其进行编码以稍后填充变量,但
我是一名优秀的程序员,十分优秀!