我有一份需要打印的徽标列表(最多4种颜色)。每个徽标都需要设置时间来混合该徽标所需的颜料。如果我可以对数据进行排序,以便使用相同颜色的两个徽标背靠背,那么我们就不必混合尽可能多的颜色来节省金钱和时间。涂料混合后的使用寿命有限。
我正在寻找像这样的数据集......
Red | (Other Color) Red | Black (Other Color) | Black
它需要以该顺序结束。这是唯一允许我制作1个红色和1个黑色的顺序。我尝试了一些事情,例如为每种常见颜色指定一个值,但无论如何,我似乎无法正确地对其进行排序。
我使用了以下根据TSP问题编写的SQL过程。 (http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=172154)
使用以下测试数据,我收到了正确的输出
delete from routes delete from cities insert into cities values ('Black|Red') insert into cities values ('Red') insert into cities values ('Blue') insert into cities values ('Black') insert into cities values ('Blue|Red') -- Numeric Value is Colors not Matching insert into routes values ('Black|Red', 'Red', 3) insert into routes values ('Black|Red', 'Black', 3) insert into routes values ('Red', 'Black', 4) insert into routes values ('Blue|Red', 'Red', 3) insert into routes values ('Blue|Red', 'Black', 4) insert into routes values ('Blue', 'Red', 4) insert into routes values ('Blue', 'Black|Red', 4) insert into routes values ('Blue', 'Black', 4) insert into routes values ('Blue', 'Blue|Red', 3) exec getTSPRoute 'Black' Results: Black->Black|Red->Red->Blue|Red->Blue->Black
唯一的问题是回到原来的城市" (黑色返回开始和结束)我必须选择一个"开始城市。"如果选择了错误的选项,我不会得到最优化的路线。
答案 0 :(得分:4)
看起来像travelling salesman problem (TSP)。让我解释一下。
首先,请考虑一个示例,其中包含四个城市A
,B
,C
和D
的地图。 (我在示例中使用了4但它与颜色数无关)。你想找到城市之间的路线,这样你(1)只访问每个城市一次,(2)路线最短。 [D,C,A,B]
可能比[B,A,D,C]
更短,而您想要的是最短的。{/ p>
现在,您有四个徽标,而不是城市。您希望找到徽标的这种排序,从而在混色方面产生最低成本。如果您想象您的每个徽标都是一个点(城市),并且徽标之间的距离是在一个颜色集与另一个颜色集之间切换的“成本”,那么您需要找到这些点之间的最短“路线”。一旦你有这条最短的路线,它会告诉你如何订购这些标志。例如,可以将两个标识L1和L2之间的“距离”定义为L2中不在L1中的多种颜色。
TSP这是一个众所周知的算法问题。这很难(实际上,NP-hard)。 如果您的输入很小,您可以找到最佳解决方案。如果是4个徽标,则有24个可能的组合。对于10个徽标,您有360万个组合,对于20个徽标,您将获得2432902008176640000组合(如何阅读?)。因此,对于大于10-15的输入,您需要使用一些启发式找到近似解,我相信这对您来说已经足够了。
我要做的是创建一个混色成本图并将其提供给某些TSP solver
修改强>:
答案 1 :(得分:1)
对于合理数量的徽标和颜色,一种简单的方法是强力方法,在这种方法中,您需要经历所有组合并在每次需要混合时增加计数器。之后,您按该计数器对组合进行排序,并选择具有最低值的组合。
伪代码
foreach combination
foreach print
foreeach color
if not previous_print.contains(color)
cost++
order combination by cost (ascending)
您没有提及您是否正在使用(或即将)任何您打算执行此类操作的工具(电子表格,编程语言......)。
编辑:
这是VB.NET中的一个快速实现。请注意,有意留下代码,以便于阅读和理解。
Private Sub GoGoGo()
' Adds some logos
' This is where you add them from the database or text file or wherever
Dim logos() =
{
New String() {"Black", "Magenta", "Orange"},
New String() {"Red", "Green", "Blue"},
New String() {"Orange", "Violet", "Pink"},
New String() {"Blue", "Yellow", "Pink"}
}
' Used to store the best combination
Dim minimumPermutation
Dim minimumCost = Integer.MaxValue
' Calculate all permutations of the logos
Dim permutations = GetPermutations(logos)
' For each permutation
For i As Integer = 0 To permutations.Count() - 1
Dim permutation = permutations(i)
Dim cost = 0
' For each logo in permutation
For j As Integer = 0 To permutation.Count() - 1
Dim logo = permutation(j)
' Check whether the previous logo contains one or more colors of this logo
For Each color In logo
If (j > 0) Then
If Not permutation(j - 1).Contains(color) Then
cost += 1
End If
Else
cost += 1
End If
Next
Next
' Save the best permutation
If (i = 0 Or cost < minimumCost) Then
minimumCost = cost
minimumPermutation = permutation.Clone()
End If
Next
' Output the best permutation
For Each logo In minimumPermutation
Console.Write(logo(0) + " " + logo(1) + " " + logo(2))
Next
End Sub
Public Shared Iterator Function GetPermutations(Of T)(values As T(), Optional fromInd As Integer = 0) As IEnumerable(Of T())
If fromInd + 1 = values.Length Then
Yield values
Else
For Each v In GetPermutations(values, fromInd + 1)
Yield v
Next
For i = fromInd + 1 To values.Length - 1
SwapValues(values, fromInd, i)
For Each v In GetPermutations(values, fromInd + 1)
Yield v
Next
SwapValues(values, fromInd, i)
Next
End If
End Function
Private Shared Sub SwapValues(Of T)(values As T(), pos1 As Integer, pos2 As Integer)
If pos1 <> pos2 Then
Dim tmp As T = values(pos1)
values(pos1) = values(pos2)
values(pos2) = tmp
End If
End Sub
答案 2 :(得分:1)
我怀疑遗传算法对此有好处。如果你有很多徽标,蛮力解决方案可能需要一段时间,贪婪不太可能产生良好的效果。