英文:
Merge arrays with optimisation
问题
我有一个优化问题。
我有多个带有id的数组。
例子:
productArray1 = '{64, 56, 33, 12, 10}'
productArray2 = '{64, 33, 12, 99}'
productArray3 = '{64, 56, 99}'
productArray4 = '{56, 64, 99}'
理解:每个数组id代表一个制造产品的processId。因此,一个数组表示一个产品的制造过程方案,因此id的顺序是不可改变的。
我想要编写一个函数来同步它们,使用'pauses'(null),
示例解决方案如下:
productArraySync1 = '{null, 64, 56, 33, 12, null, 10}'
productArraySync2 = '{null, 64, null, 33, 12, 99, null}'
productArraySync3 = '{null, 64, 56, null, null, 99, null}'
productArraySync4 = '{56, 64, null, null, null, 99, null}'
我在这张图片中标记了列,这样你就可以看到我想要实现的目标。
在productArraySync
的一列中,我需要尽量减少null值,但是我需要遵守原始顺序。
以64(绿色)为例,表示钻孔过程。正如前面提到的,每个数组代表一个制造产品的工序顺序。
在第4个数组中,有另一种方法(56(黄色)居中处理过程)在这个64之前。所以它必须在64之前完成,因此你必须将第1、2、3个数组添加到第一列的null中,这样在第2列中你就得到了最小的null值。
这意味着第2列是有效的,因为在一个'工作站'中,你可以在一个设置中处理尽可能多的产品。
我不需要代码,也不需要解决方案,这个问题更加复杂,我可以理解。
我需要一些思路来解决这个问题,目前我没有任何想法。
我的当前方法是计算所有可能的组合,然后选择最好的,但这不好,因为它是指数级的,无法处理更大的数组。
英文:
I have an optimisation problem.
I have multiple arrays, with id-s.
Example:
productArray1 = '{64, 56, 33, 12, 10}'
productArray2 = '{64, 33, 12, 99}'
productArray3 = '{64, 56, 99}'
productArray4 = '{56, 64, 99}'
To understand: Each array id is representing a processId of a manufactured product.
So basically an array is representing the manufacturing process scheme of a product, because of that, the order of id-s is not changeable.
I want to make a function that synchronise those, using 'pauses' (null),
The example resolution is this:
productArraySync1 = '{null, 64, 56, 33, 12, null, 10}'
productArraySync2 = '{null, 64, null, 33, 12, 99, null}'
productArraySync3 = '{null, 64, 56, null, null, 99, null}'
productArraySync4 = '{56, 64, null, null, null, 99, null}'
I painted the columns in this picture so you can see what I want to achieve.
In a column in productArraySync
I need to get to minimise the null values, but I need to respect the original order.
For an example 64(green) means a drilling process. And as mentioned, each array represent an order of processes of a manufactured product.
In the 4. array there is an another method (56(yellow) centering process)
before this 64. so it has to be done before 64, so you have to add 1.,2.,3. arrays to a null in the first column, so in the 2. column you get the minimal null values.
This means the 2. column is effective because in a 'workstation' you can process as many product in one setup as possible.
I don't need code, I don't need a solution, this is far more complicated, I can understand.
I need some ideas how to approach this problem, at this point I have no idea.
my current approach is to calculate all possible combinations, and then select the
best, but this is not good becasue its exponential, and can not work with larger arrays
答案1
得分: 1
这是使用你的帮助在C#中编写的方法。它完美地工作,但我稍后会运行一些测试
public static void Main()
{
var sequences = new int[][]
{
new[] {64, 56, 33, 12, 10},
new[] {64, 33, 12, 99},
new[] {64, 56, 99},
new[] {56, 64, 99}
};
ShortestCommonSuperDP(sequences, out var sCsSequenceArray);
foreach (var result in sCsSequenceArray.Select(arr => arr.Select(x => x == null ? "null" : $"{x}").ToArray()))
{
Console.WriteLine(string.Join("\t", result));
}
Console.ReadLine();
}
private static int[] ShortestCommonSuperDP(IReadOnlyList<int[]> sequenceArray, out List<int?[]> sCsSequenceArray)
{
var resultSequence = sequenceArray[0];
for (var i = 0; i < sequenceArray.Count - 1; i++)
{
var nextSequence = sequenceArray[i + 1];
var result = ShortestCommonSuperDP(resultSequence, nextSequence, out _, out _);
resultSequence = result;
}
sCsSequenceArray = new List<int?[]>();
foreach (var sequence in sequenceArray)
{
ShortestCommonSuperDP(resultSequence, sequence, out _, out var resultArr2);
sCsSequenceArray.Add(resultArr2);
}
return resultSequence.Select(x => x).ToArray();
}
private static int[] ShortestCommonSuperDP(IReadOnlyList<int> sequence1, IReadOnlyList<int> sequence2, out int?[] sequenceScs1, out int?[] sequenceScs2)
{
var dynamicTable = new int[sequence1.Count + 1, sequence2.Count + 1];
for (var i = 0; i <= sequence1.Count; i++)
{
for (var j = 0; j <= sequence2.Count; j++)
if (i == 0)
dynamicTable[i, j] = j;
else if (j == 0)
dynamicTable[i, j] = i;
else if (sequence1[i - 1] == sequence2[j - 1])
dynamicTable[i, j] = dynamicTable[i - 1, j - 1] + 1;
else
dynamicTable[i, j] = 1 + Math.Min(dynamicTable[i - 1, j], dynamicTable[i, j - 1]);
}
var scsLength = dynamicTable[sequence1.Count, sequence2.Count];
var commonScs = new int[scsLength];
int x = sequence1.Count, y = sequence2.Count;
sequenceScs1 = new int?[scsLength];
sequenceScs2 = new int?[scsLength];
while (x > 0 && y > 0)
if (sequence1[x - 1] == sequence2[y - 1])
{
commonScs[--scsLength] = sequence1[x - 1];
x--;
y--;
sequenceScs1[scsLength] = commonScs[scsLength];
sequenceScs2[scsLength] = commonScs[scsLength];
}
else if (dynamicTable[x, y - 1] < dynamicTable[x - 1, y])
{
commonScs[--scsLength] = sequence2[y - 1];
sequenceScs1[scsLength] = null;
sequenceScs2[scsLength] = commonScs[scsLength];
y--;
}
else
{
commonScs[--scsLength] = sequence1[x - 1];
sequenceScs1[scsLength] = commonScs[scsLength];
sequenceScs2[scsLength] = null;
x--;
}
while (x > 0)
{
commonScs[--scsLength] = sequence1[x - 1];
x--;
}
while (y > 0)
{
commonScs[--scsLength] = sequence2[y - 1];
y--;
}
return commonScs;
}
希望对你有帮助!
英文:
So finally I coded this method in C# with your help. It's working perfectly, but I run some test later
public static void Main()
{
var sequences = new int[][]
{
new[] {64, 56, 33, 12, 10},
new[] {64, 33, 12, 99},
new[] {64, 56, 99},
new[] {56, 64, 99}
};
ShortestCommonSuperDP(sequences, out var sCsSequenceArray);
foreach (var result in sCsSequenceArray.Select(arr => arr.Select(x => x == null ? "null" : $"{x}").ToArray()))
{
Console.WriteLine(string.Join("\t", result));
}
Console.ReadLine();
}
private static int[] ShortestCommonSuperDP(IReadOnlyList<int[]> sequenceArray, out List<int?[]> sCsSequenceArray)
{
var resultSequence = sequenceArray[0];
for (var i = 0; i < sequenceArray.Count - 1; i++)
{
var nextSequence = sequenceArray[i + 1];
var result = ShortestCommonSuperDP(resultSequence, nextSequence, out _, out _);
resultSequence = result;
}
sCsSequenceArray = new List<int?[]>();
foreach (var sequence in sequenceArray)
{
ShortestCommonSuperDP(resultSequence, sequence, out _, out var resultArr2);
sCsSequenceArray.Add(resultArr2);
}
return resultSequence.Select(x => x).ToArray();
}
private static int[] ShortestCommonSuperDP(IReadOnlyList<int> sequence1, IReadOnlyList<int> sequence2, out int?[] sequenceScs1, out int?[] sequenceScs2)
{
var dynamicTable = new int[sequence1.Count + 1, sequence2.Count + 1];
for (var i = 0; i <= sequence1.Count; i++)
{
for (var j = 0; j <= sequence2.Count; j++)
if (i == 0)
dynamicTable[i, j] = j;
else if (j == 0)
dynamicTable[i, j] = i;
else if (sequence1[i - 1] == sequence2[j - 1])
dynamicTable[i, j] = dynamicTable[i - 1, j - 1] + 1;
else
dynamicTable[i, j] = 1 + Math.Min(dynamicTable[i - 1, j], dynamicTable[i, j - 1]);
}
var scsLength = dynamicTable[sequence1.Count, sequence2.Count];
var commonScs = new int[scsLength];
int x = sequence1.Count, y = sequence2.Count;
sequenceScs1 = new int?[scsLength];
sequenceScs2 = new int?[scsLength];
while (x > 0 && y > 0)
if (sequence1[x - 1] == sequence2[y - 1])
{
commonScs[--scsLength] = sequence1[x - 1];
x--;
y--;
sequenceScs1[scsLength] = commonScs[scsLength];
sequenceScs2[scsLength] = commonScs[scsLength];
}
else if (dynamicTable[x, y - 1] < dynamicTable[x - 1, y])
{
commonScs[--scsLength] = sequence2[y - 1];
sequenceScs1[scsLength] = null;
sequenceScs2[scsLength] = commonScs[scsLength];
y--;
}
else
{
commonScs[--scsLength] = sequence1[x - 1];
sequenceScs1[scsLength] = commonScs[scsLength];
sequenceScs2[scsLength] = null;
x--;
}
while (x > 0)
{
commonScs[--scsLength] = sequence1[x - 1];
x--;
}
while (y > 0)
{
commonScs[--scsLength] = sequence2[y - 1];
y--;
}
return commonScs;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论