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