【问题标题】:Minimum distance between two sets of points两组点之间的最小距离
【发布时间】:2021-10-24 20:42:57
【问题描述】:

我在度量空间中有一组 n 个点。这些点都是蓝色的。我在空间中有另一组 n 点。这些点都是红色的。我想以这样一种方式连接这些点,即每个蓝点都连接到一个红点,每个红点都连接到一个蓝点。 (显然有 n! 种方法。)我希望找到最小化连接总长度的连接集。这个问题叫什么?

【问题讨论】:

标签: algorithm


【解决方案1】:

问题叫Min weight perfect matching on complete bipartite graph,或者Assignment problem

通常表述如下:

问题实例有许多代理和许多任务。可以分配任何代理来执行任何任务,产生的成本可能会因代理任务分配而异。要求执行尽可能多的任务,每个任务最多分配一个代理,每个代理最多分配一个任务,以使分配的总成本最小化。

问题可以通过Hungarian algorithm解决,复杂度为O(n^3)。

【讨论】:

    【解决方案2】:

    Thr 下面的代码(Edmonds-Karp 算法)解决了一个类似的问题:两组(男孩和女孩)之间的最优婚姻。 O(n^3) 也是。

    # each boy would accept marriage with some
    # of the girl. What wedding would maximize
    # happiness ?
    MensN=["Brad","John","Chrid","Tom","Zack","Moe","Yim","Tim","Eric","Don"]
    WomN=["Olivia","Jenny","Michelle","Kate","Jude","Sonia","Yin","Zoe","Amy","Nat"]
           # O J M K J S Y Z A N
    MensP=[[ 0,0,1,0,1,0,0,1,0,0],  # Brad
           [ 1,1,0,0,0,1,1,0,1,0],  # John
           [ 0,0,0,1,1,0,0,1,0,1],  # Chris
           [ 0,1,1,0,0,0,1,0,0,0],  # Tom
           [ 0,0,1,0,0,1,0,1,1,1],  # Zack
           [ 1,0,1,0,1,0,0,1,0,0],  # Moe
           [ 0,0,1,0,0,0,0,0,1,1],  # Yim
           [ 0,1,1,0,0,1,0,0,1,0],  # Tim
           [ 0,0,1,1,1,0,1,0,0,0],  # Eric
           [ 1,0,0,0,1,0,0,1,0,1]]  # Don 
           
    #Edmonds-Karp Algorithm for optimal matching
    
    def max_flow(C, s, t):
     F,path=[[0]*len(C) for c in C],s!=t
     while path:
      [path,flow]=bfs(C,F,s,t)
      for u,v in path:
       F[u][v],F[v][u]=F[u][v]+flow,F[v][u]-flow
     return F,sum(F[s])
    
    #find path by using BFS
    def bfs(C,F,s,t,f=999999):
     queue,paths=[s],{s:[]}
     while queue: 
      u=queue.pop(0)
      for v in range(len(C)):
        if C[u][v]>F[u][v] and v not in paths:
         paths[v]=paths[u]+[(u,v)]
         f=min(f,C[u][v]-F[u][v])
         if v==t:  return [paths[v],f]
         queue.append(v)
     return([[],999999])    
    
    # make a capacity graph
    C=[[0]+[1]*len(MensN)+[0]*len(WomN)+[0]]+[ # Source leads to men
    [0]*(1+len(MensN))+p+[0] for p in MensP]+[ # Men lead to women with respective prefs
    [0]*(1+len(MensN)+len(WomN))+[1] for w in WomN]+[ # Women lead to target
    [0]*(1+len(MensN))+[0]*len(WomN)+[0]]  # Target leads nowhere
    [F,n]=max_flow(C,0,len(C[0])-1)
    print("It is possible to do",n,"marriage(s)")
    for i in enumerate(MensN):
        print (i[1]," chooses ",",".join(WomN[j] for j in range(len(WomN)) if F[1+i[0]][1+len(MensN)+j] ))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-17
      • 1970-01-01
      • 2021-01-30
      • 1970-01-01
      相关资源
      最近更新 更多