CanSum动态规划C#记忆化仍然慢

huangapple go评论64阅读模式
英文:

CanSum Dynamic Programming C# memoization is still slow

问题

我正在尝试学习动态规划,正在跟随来自freecodecamp的5小时教程,但他在使用JavaScript,而JavaScript中的对象易于进行索引,而在C#中,我尝试使用字典,并且必须两次使用.ContainsKey,我认为这会影响性能。

public bool CanSum(int n, int[] numbers, Dictionary<int, bool> memo)
{
    if (memo.ContainsKey(n))
        return memo[n];

    if (n == 0) return true;
    if (n < 0) return false;

    for (var i = 0; i < numbers.Length; i++)
    {
        var sum = n - numbers[i];

        if (CanSum(sum, numbers, memo))
        {
            memo[n] = true;
            return true;
        }
    }

    memo[n] = false;

    return false;
}

如何改进这个?有没有可能使用数组?

编辑:好的,我学到了一些新东西,我可以将Dictionary初始化为空对象,就像这样 new() { }

代码如下:

if (memo.ContainsKey(n))           
     return memo[n];

if (n == 0) return true;
if (n < 0) return false;

for (var i = 0; i < numbers.Length; i++)
{
    var sum = n - numbers[i];

    if (CanSum(sum, numbers, memo))
    {
        memo[n] = true;
        return true;
    }
}

memo[n] = false;

return false;
英文:

I am trying to learn dynamic programming and I am following a 5h tutorial from freecodecamp but he is using js, and obj in js is easy with indexing, in C# I am trying to use dictionary
and I have to use .ContainsKey twice which I think is expensive on the performance.

public bool CanSum(int n, int[] numbers, Dictionary&lt;int, bool&gt; memo)
{
    if (n == 0) return true;
    if (n &lt; 0) return false;

    if (memo.ContainsKey(n))
        if (memo[n]) return true;

    for (var i = 0; i &lt; numbers.Length; i++)
    {
        var sum = n - numbers[i];

        if (CanSum(sum, numbers, memo))
        {
            if (!memo.ContainsKey(sum))
                memo.Add(sum, true);
            return true;
        }
    }

    return false;
}

How can I improve this? Is there a possibility to use an array?

Edit: Ok I did learn something new, I can new Dictionary as an empty object, like this new() { }

And code is like this:

if (memo.ContainsKey(n))           
     return memo[n];

if (n == 0) return true;
if (n &lt; 0) return false;

for (var i = 0; i &lt; numbers.Length; i++)
{
    var sum = n - numbers[i];

    if (CanSum(sum, numbers, memo))
    {
        memo[n] = true;
        return true;
    }
}

memo[n] = false;

return false;

答案1

得分: 0

首先,优化的黄金法则是测量。因此,如果你说像“认为很昂贵”之类的话,你应该首先学会如何实际检查你的假设。因为即使有经验的程序员在假设性能方面的事情时经常是错误的。有几种可能的工具可以进行测量,Stopwatch是最简单和基本的工具,性能分析器会提供最多的数据,而Benchmark .Net应该是最准确的工具。

有可能使用数组吗?

如果数字的范围有限,你可以使用数组。如果n可以是任何int,那么你需要一个大数组。总的来说,数组应该比字典更快,但请参考第一段关于假设的内容。我猜你的数组中的元素需要具有三种状态,即true、false和unknown,也就是三值逻辑

对于像这样的玩具示例,我也会有一些疑虑。首先,因为我认为它们不太能很好地代表常见的问题。其次,像“不要重新进行昂贵的计算”这样的技术应该适用于许多问题。第三,类似字典与数组的比较是一种微优化(即它们都具有恒定的访问时间),但这本身就是一个庞大且复杂的话题,我认为比“动态规划”更具一般适用性。

英文:

First of all, the golden rule of optimization is to measure. So if you say things like "think is expensive" you should first learn how to actually check your assumptions. Because even experienced programmers are often wrong when they assume things about performance. There are several possible tools for doing measurements, Stopwatch is the simplest and most basic one, a performance profiler would give you the most data, and Benchmark .Net should be the most accurate one.

> Is there a possibility to use an array?

If the range of numbers are limited you can use an array. If n can be any int you would need a large array. Arrays should in general be faster than dictionaries, but se the first paragraph about assumptions. I'm guessing elements in your array need to have three states, true, false and unknown, aka trilean or ternary.

I would also be a bit wary about toy examples like this. First of all because I do not think they represent common problems very well. Second because techniques like "don't redo expensive calculations" should be applicable to many problems. And third, things like dictionary vs array is a type of micro-optimization (i.e. both have constant access time), but this is a large and complex topic in itself, and I would argue, more generally applicable than "dynamic programming".

huangapple
  • 本文由 发表于 2023年3月8日 17:08:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75671149.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定