Algorithm 如何进行d-平滑序列算法的研究

Algorithm 如何进行d-平滑序列算法的研究,algorithm,sorting,sequence,seq,Algorithm,Sorting,Sequence,Seq,我真的很难设计一个算法来找到d,这是一个最小的值,可以加或减(最多),使给定的序列严格递增 例如。。说seq[]=[2,4,8,3,1,12] 给定这个序列,算法应该返回“5”作为d,因为每个元素最多可以加或减5,这样函数就严格递增了 我尝试过几种方法,但似乎无法获得可靠的技术 我已经试过在序列中循环。并检查seq[i]

我真的很难设计一个算法来找到d,这是一个最小的值,可以加或减(最多),使给定的序列严格递增

例如。。说seq[]=[2,4,8,3,1,12]

给定这个序列,算法应该返回“5”作为d,因为每个元素最多可以加或减5,这样函数就严格递增了

我尝试过几种方法,但似乎无法获得可靠的技术

我已经试过在序列中循环。并检查seq[i] 但我不能让它保持稳定,就像我一直在添加if语句一样,对于唯一的输入序列来说,if语句更“特殊”。人们建议使用二进制搜索方法,但我无法理解将其应用于这个问题

任何提示和建议都将不胜感激。谢谢


下面是我正在编写的代码-使用Python-v4 ~z~注意~ 我从1开始,而不是从0开始,因为第一个元素是键

public static int ComputeMaxDelta(int[] aItems, out int[] fixes)
{
    // Create a copy to speed up comparison on modified values
    aItems = (int[])aItems.Clone();
    // Will store the fix values for every item
    fixes = new int[aItems.Length];

    // Loop until no more fixes get applied
    var bNeedFix = true;
    while (bNeedFix)
    {
        // Hope will have no fix this turn
        bNeedFix = false;

        // loop all subsequent item pairs
        for (int ixItem = 0; ixItem < aItems.Length - 1; ixItem++)
        {
            // Left item
            var item1 = aItems[ixItem];
            // right item
            var item2 = aItems[ixItem + 1];

            // Compute delta between left and right item
            // We remember that (right >= left + 1)
            var nDelta = item2 - (item1 + 1);
            if (nDelta < 0)
            {
                // Fix the right item
                fixes[ixItem + 1] -= nDelta;
                aItems[ixItem + 1] -= nDelta;
                //Need another loop
                bNeedFix = true;
            }
        }
    }

    // Compute the fix size (rounded up)
    var nFix = (fixes.Max() + 1) / 2;

    // Balance all fixes
    for (int ixItem = 0; ixItem < aItems.Length; ixItem++)
        fixes[ixItem] -= nFix;

    return nFix;
}
def ComputeMaxDelta(aItems):
    # Create a copy to speed up comparison on modified values
    aItems = aItems[:]
    # Will store the fix values for every item
    # this should allocate 'length' times the 0 value
    fixes = [0] * len(aItems)

    # Loop until no more fixes get applied
    bNeedFix = True
    while(bNeedFix):
        # Hope will have no fix this turn
        bNeedFix = False

        # loop all subsequent item pairs (i should run from 0 to length - 2)
        for i in range(0,len(aItems)-1):
            # Left item
            item1 = aItems[i]
            # right item
            item2 = aItems[i+1]

            # Compute delta between left and right item
            # We remember that (right >= left + 1
            nDelta = item2 - (item1 + 1)
            if(nDelta < 0):
                # Fix the right item
                fixes[i+1] -= nDelta
                aItems[i+1] -= nDelta
                # Need another loop
                bNeedFix = True

    # Compute the fix size (rounded up)
    # max(s) should be int and the division should produce an int
    nFix = (max(fixes)+1)/2 # corrected from **(max(s)+1)/2**

    # Balance all fixes
    for i in range(len(s)):
        fixes[i] -= nFix

    print("d:",nFix) # corrected from **print("d:",nDelta)**
    print("s:",fixes)

    return
publicstaticintcomputemaxdelta(int[]aItems,out int[]fixes)
{
//创建副本以加快对修改值的比较
aItems=(int[])aItems.Clone();
//将存储每个项目的固定值
fixes=新整数[aItems.Length];
//循环,直到不再应用修复程序
var bNeedFix=true;
while(bNeedFix)
{
//希望在这一轮没有解决办法
bNeedFix=false;
//循环所有后续项对
对于(int ixItem=0;ixItem=左+1)
var nDelta=项目2-(项目1+1);
如果(nDelta<0)
{
//修复正确的项目
固定点[ixItem+1]-=nDelta;
aItems[ixItem+1]=nDelta;
//需要另一个循环吗
bNeedFix=true;
}
}
}
//计算固定大小(四舍五入)
var nFix=(fixes.Max()+1)/2;
//平衡所有修复
对于(int ixItem=0;ixItem
该函数返回计算出的最大固定间隙。 作为bounus,参数fixes将接收每个项目的修复。这些是应用于每个源值的增量,以确保它们按升序排列:可以减少一些修复,但需要一些分析循环来实现优化


下面是测试该算法的代码。如果在循环结束时设置断点,则可以检查示例中提供的序列的结果

var random = new Random((int)Stopwatch.GetTimestamp());
for (int ixLoop = -1; ixLoop < 100; ixLoop++)
{
    int nCount;
    int[] aItems;

    // special case as the provided sample sequence
    if (ixLoop == -1)
    {
        aItems = new[] { 2, 4, 8, 3, 1, 12 };
        nCount = aItems.Length;
    }
    else
    {
        // Generates a random amount of items based on my screen's width
        nCount = 4 + random.Next(21);
        aItems = new int[nCount];
        for (int ixItem = 0; ixItem < nCount; ixItem++)
        {
            // Keep the generated numbers below 30 for easier human analysis
            aItems[ixItem] = random.Next(30);
        }
    }

    Console.WriteLine("***");
    Console.WriteLine("  # " + GetText(Enumerable.Range(0, nCount).ToArray()));
    Console.WriteLine("    " + GetText(aItems));

    int[] aFixes;
    var nFix = ComputeMaxDelta(aItems, out aFixes);

    // Computes the new values, that will be always in ascending order
    var aNew = new int[aItems.Length];
    for (int ixItem = 0; ixItem < aItems.Length; ixItem++)
    {
        aNew[ixItem] = aItems[ixItem] + aFixes[ixItem];
    }

    Console.WriteLine("  = " + nFix.ToString());
    Console.WriteLine("  ! " + GetText(aFixes));
    Console.WriteLine("  > " + GetText(aNew));
}
var random=new random((int)Stopwatch.GetTimestamp());
for(int-ixLoop=-1;ixLoop<100;ixLoop++)
{
int-nCount;
int[]aItems;
//特殊情况作为提供的样本序列
if(ixLoop==-1)
{
aItems=new[]{2,4,8,3,1,12};
nCount=aItems.长度;
}
其他的
{
//根据我的屏幕宽度生成随机数量的项目
n计数=4+随机。下一个(21);
aItems=新整数[n计数];
对于(int ixItem=0;ixItem”+GetText(新));
}

问候,
Daniele。

正如预期的那样,以下是(或应该是)我的初始解决方案的Python版本:

public static int ComputeMaxDelta(int[] aItems, out int[] fixes)
{
    // Create a copy to speed up comparison on modified values
    aItems = (int[])aItems.Clone();
    // Will store the fix values for every item
    fixes = new int[aItems.Length];

    // Loop until no more fixes get applied
    var bNeedFix = true;
    while (bNeedFix)
    {
        // Hope will have no fix this turn
        bNeedFix = false;

        // loop all subsequent item pairs
        for (int ixItem = 0; ixItem < aItems.Length - 1; ixItem++)
        {
            // Left item
            var item1 = aItems[ixItem];
            // right item
            var item2 = aItems[ixItem + 1];

            // Compute delta between left and right item
            // We remember that (right >= left + 1)
            var nDelta = item2 - (item1 + 1);
            if (nDelta < 0)
            {
                // Fix the right item
                fixes[ixItem + 1] -= nDelta;
                aItems[ixItem + 1] -= nDelta;
                //Need another loop
                bNeedFix = true;
            }
        }
    }

    // Compute the fix size (rounded up)
    var nFix = (fixes.Max() + 1) / 2;

    // Balance all fixes
    for (int ixItem = 0; ixItem < aItems.Length; ixItem++)
        fixes[ixItem] -= nFix;

    return nFix;
}
def ComputeMaxDelta(aItems):
    # Create a copy to speed up comparison on modified values
    aItems = aItems[:]
    # Will store the fix values for every item
    # this should allocate 'length' times the 0 value
    fixes = [0] * len(aItems)

    # Loop until no more fixes get applied
    bNeedFix = True
    while(bNeedFix):
        # Hope will have no fix this turn
        bNeedFix = False

        # loop all subsequent item pairs (i should run from 0 to length - 2)
        for i in range(0,len(aItems)-1):
            # Left item
            item1 = aItems[i]
            # right item
            item2 = aItems[i+1]

            # Compute delta between left and right item
            # We remember that (right >= left + 1
            nDelta = item2 - (item1 + 1)
            if(nDelta < 0):
                # Fix the right item
                fixes[i+1] -= nDelta
                aItems[i+1] -= nDelta
                # Need another loop
                bNeedFix = True

    # Compute the fix size (rounded up)
    # max(s) should be int and the division should produce an int
    nFix = (max(fixes)+1)/2 # corrected from **(max(s)+1)/2**

    # Balance all fixes
    for i in range(len(s)):
        fixes[i] -= nFix

    print("d:",nFix) # corrected from **print("d:",nDelta)**
    print("s:",fixes)

    return
def ComputeMaxDelta(aItems):
#创建副本以加快对修改值的比较
aItems=aItems[:]
#将存储每个项目的固定值
#这应分配“长度”乘以0值
fixes=[0]*len(aItems)
#循环,直到不再应用修复程序
bNeedFix=True
while(bNeedFix):
#希望在这一轮没有解决办法
bNeedFix=False
#循环所有后续项对(我应该从0运行到长度-2)
对于范围(0,len(aItems)-1)内的i:
#左项
项目1=aItems[i]
#正确的项目
项目2=aItems[i+1]
#计算左右项之间的增量
#我们记得(右>=左+1
nDelta=项目2-(项目1+1)
如果(nDelta<0):
#修复正确的项目
修复[i+1]-=nDelta
aItems[i+1]-=nDelta
#需要另一个循环吗
bNeedFix=True
#计算固定大小(四舍五入)
#max(s)应为int,除法应产生int
nFix=(最大值)+1)/2#由**(最大值)+1)/2修正**
#平衡所有修复
对于范围内的i(len(s)):
fixes[i]=nFix
打印(“d:,nFix)#根据**打印(“d:,nDelta”)更正**
打印(“s:”,修复)
返回
我使用了您的Python并进行了修复,以便完全按照我的C#解决方案进行操作。 我不懂Python,但在web上寻找一些参考资料时,我应该已经找到了您的移植