Algorithm 哪些算法可以用来解决这个相似性最小化平衡问题?
我到处都找过了,但显然我找不到正确的关键字来搜索合适的解决方案,所以问题来了:Algorithm 哪些算法可以用来解决这个相似性最小化平衡问题?,algorithm,sorting,grouping,partitioning,minimization,Algorithm,Sorting,Grouping,Partitioning,Minimization,我到处都找过了,但显然我找不到正确的关键字来搜索合适的解决方案,所以问题来了: * 我有一组p元素[a,B…Y,Z],和一个PxP值矩阵 表示每对元素之间的相似性(因此 主对角线为100%,每隔一个单元格有一个介于0%和0%之间的数字 100%). 我想把这个集合分成N个元素的组,这样 该解决方案倾向于最小化组的平均内部相似性 * 你们能告诉我怎么做吗?我曾尝试研究过标准的划分算法,但大多数算法都不适用,因为权重取决于对,而不是个体 谢谢 不幸的是,这个问题是NP难的,这意味着不太可能有一个
* 我有一组p元素[a,B…Y,Z],和一个PxP值矩阵 表示每对元素之间的相似性(因此 主对角线为100%,每隔一个单元格有一个介于0%和0%之间的数字 100%). 我想把这个集合分成N个元素的组,这样 该解决方案倾向于最小化组的平均内部相似性 *
你们能告诉我怎么做吗?我曾尝试研究过标准的划分算法,但大多数算法都不适用,因为权重取决于对,而不是个体
谢谢 不幸的是,这个问题是NP难的,这意味着不太可能有一个多项式时间算法来解决每个实例的最优性。我将从最大二等分中减去。在这个问题的决策问题变体中,我们给出了一个图G和一个数字k,并要求将G的顶点划分为两个大小相等的部分,以便两部分之间的边数至少为k。通过对更一般的最大割问题的简化,证明了最大二分法是NP难的,其中两个部分不需要有相同数量的顶点 给定一个图G=(V,E)和数字k,则缩减为:
- 如果(i,j)是G中的边,则创建一个矩阵X,其中X[i][j]=X[j][i]=1,否则为0
- 选择N=| V |/2。(这将导致输出2个组。)
这意味着,给定任何多项式时间算法来解决你的问题,以及NP-难最大对分问题的任何实例,我们可以在多项式时间内构造你的问题的一个实例,解决它,并将解决方案转换为原始最大对分问题的解——即,这意味着我们可以在多项式时间内解决一个NP难问题。这意味着你的问题本身就是NP难问题。如果我没有完全误解你的问题,而你想要一个糟糕的解决方法,那就是: 暴力手段:
def getValues(matrix):
values=[]
count=1
while ((len(matrix)- count)>0):
j= count
for i in range(len(matrix)- count ):
values.append(matrix[count-1][j ] )
j+=1
count+=1
return values
def c(arr, curr, end,k ,n , comb=[]):
"""get combinations for list length n and choose k elem"""
if comb is None:
comb = []
elif n ==1 :
comb = []
if ((arr.count(1) is not k) and (curr < end)):
tmparr= [ i for i in arr]
tmparr[curr]= 1
c(tmparr, curr+ 1 , end,k ,n + 1 , comb)
tmparr[curr]= 0
c(tmparr, curr+ 1 , end,k ,n + 1 , comb)
if arr.count(1) ==k :
comb.append(arr)
if n is 1:
return comb
def combos(l, choose):
"""
use this w/ c() to get combinations
"""
arr = [1 for i in l]
return c(arr,0 , len(l), choose,1 )
def getComb(combos, elem):
"""
EX. combos=[0,1,1] elem=["A","B","C"]
return ["B","C"]
"""
result= [ ]
for i in combos:
tmp= ""
for j in range(len(i)):
if i[j] is 1:
tmp+= elem[j]
result.append(tmp)
return result
def subSum(sub,d):
"""
EX. sub = "abc" then return value d["ab"]+d["ac"]+d["bc"]
sub -- list of string elements
d -- dictionary
"""
if( len(sub) is 2):
return d[sub[0]+ sub [1]]
sum=0
for i in range(len(sub)-1) :
sum+=d [ sub[0]+ sub [i+1] ]
return sum+ subSum(sub[1:],d)
def contains(a,b):
for i in a:
if i in b:
return True
return False
#**************INPUT HERE**************#
# elements
e = ["A","B", "C", "D", "E", "F"] # partition set into N
N = 2
matrix =[ [100,2,3,4,5,6],
[ 2, 100,9,16,23 ,30] ,
[ 44,22,100,11,5 ,2] ,
[ 11 ,22,33,100, 44, 55],
[1 ,6,7,13,100, 20 ],
[1 ,1,2,3,5,100 ] ]
#**************************************#
if len(matrix) is len(e):
p = getComb(combos(e,(int)(len( matrix)/N)),e)
q = getComb(combos(e,2),e)
values = getValues(matrix)
# make lookup for subSum()
d = {}
for i in range(len(q)):
d[q[i]]=values[i]
result=[]
for i in range(N):
sums = [subSum(i, d) for i in p]
m = min(sums)
s = p[sums.index(m)]
result.append(s)
for i in p:
if contains(s, i):
p.remove(i)
print(result) # this is the answer
def getValues(矩阵):
值=[]
计数=1
而((len(矩阵)-计数)>0):
j=计数
对于范围内的i(len(矩阵)-计数):
附加值(矩阵[count-1][j])
j+=1
计数+=1
返回值
def c(阵列、当前、结束、k、n、梳=[]):
“”“获取列表长度n的组合并选择k元素”“”
如果comb为None:
梳=[]
elif n==1:
梳=[]
如果((arr.count(1)不是k)和(curr