英文:
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(绿色)表示钻孔过程。正如前面提到的,每个数组都代表一个制造产品的工序顺序。
在第四个数组中,有另一种方法(56(黄色)中心化过程)在此之前,所以必须在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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论