2017-11-17 118 views
3

我有一個列表,我用它來存儲對象之間的距離。確定一個NxN數組的行和列的最低值

表看起來是這樣的:

+----------+----------+----------+----------+----------+ 
|   | Object_A | Object_B | Object_C | Object_D | 
+----------+----------+----------+----------+----------+ 
| Entity_E |  2 |  3 |  6 |  1 | 
+----------+----------+----------+----------+----------+ 
| Entity_F |  3 |  4 |  7 |  2 | 
+----------+----------+----------+----------+----------+ 
| Entity_G |  9 |  1 |  2 |  3 | 
+----------+----------+----------+----------+----------+ 

的數字表示該行&列標題之間的距離。

這是粗略計算如下:

entites = [Entity_E, Entity_F, Entity_G] 
objects = [Object_A, Object_B, Object_C, Obhect_D] 
distances = [] 

for object in objects: 

    distanceEntry = [] 

    for entity in entities: 
     distance = getDistance(entity, object) 

     distanceEntry.append(distance) 
    distances.append(distanceEntry) 

這給了我大約在上表中的信息。

我在尋找的是基本上找到每個實體的最接近的對象(反之亦然)。每個對象或實體只能與另一個對象匹配,並且應該基於鄰近性。

他們這樣做的方式現在是通過按距離大小排序嵌套列表(在完整的代碼中,我有一種確定每個距離與哪個對象關聯的方式)。

所以,在這樣做,我將創建下列協會:

+----------+----------+----------+ 
| Entity | Object | Distance | 
+----------+----------+----------+ 
| Entity_E | Object_D |  1 | 
+----------+----------+----------+ 
| Entity_F | Object_D |  2 | 
+----------+----------+----------+ 
| Entity_G | Object_B |  1 | 
+----------+----------+----------+ 

這是不正確,因爲這兩次關聯Object_D。

該協會應該是:

+----------+----------+----------+ 
| Entity | Object | Distance | 
+----------+----------+----------+ 
| Entity_E | Object_D |  1 | 
+----------+----------+----------+ 
| Entity_F | Object_A |  3 | 
+----------+----------+----------+ 
| Entity_G | Object_B |  1 | 
+----------+----------+----------+ 

這是我掙扎 - 我不是最好的方法找出該代碼邏輯這一點。

由於Entity_E更接近Object_D,它應該獲得關聯。所以,對於Entity_F,我需要排在第二位。

我正在考慮做一些事情,我會記錄哪些對象已被分配,或者嘗試做一些事情,首先匹配每列中的最小值,但它們似乎都會遇到問題。

是否有矩陣運算或某種矩陣運算可用於計算?

任何意見將不勝感激!

編輯 - 添加全碼:

# Create an array that stores the distances between each label and symbol. Only calculate the distance for label that 
# are "in front" of the symbol. 
# Example Table: 
# +---------------+--------------+--------------+--------------+--------------+ 
# |    | Label_1 | Label_2 | Label_3 | Label_4 | 
# +---------------+--------------+--------------+--------------+--------------+ 
# | Measurement_1 |  2  |  3  | Not_in_front |  1  | 
# +---------------+--------------+--------------+--------------+--------------+ 
# | Measurement_2 |  3  |  4  |  1  | Not_in_front | 
# +---------------+--------------+--------------+--------------+--------------+ 
# | Measurement_3 | Not_in_front | Not_in_front |  2  |  1  | 
# +---------------+--------------+--------------+--------------+--------------+ 

# Data Structures: 
# measurementsDictionary = {['Type', 'Handle', 'X-Coord', 'Y-Coord', 'Z-Coord', 'Rotation', 'True Strike']} 
# dipsDictionary = {['Handle', 'Text', 'Unit', 'X-Coord', 'Y-Coord', 'Z-Coord']} 

#The two functions below grab the information from a csv-like file. 
measurementsDictionary = getMeasurementsInformationFromFile() 
dipsDictionary = getDipsInformationFromFile() 


exportHeaders = [" "] 
exportArray = [] 

for measurementSymbol in measurementsDictionary: 

    measurementEntry = measurementsDictionary[measurementSymbol] 
    measurementCoord = [measurementEntry[2], measurementEntry[3]] 
    measurementDistance = [] 
    measurementDistance.append(measurementEntry[1]) 
    measurementCartesianAngle = getCartesianAngle(measurementEntry[6]) 
    measurementLineEquation = generateLineEquation(measurementCoord,measurementCartesianAngle) 

    for dip in dipsDictionary: 
     dipEntry = dipsDictionary[dip] 
     dipCoord = [dipEntry[3],dipEntry[4]] 
     isPointInFrontOfLineTest = isPointInFrontOfLine(measurementCartesianAngle, measurementLineEquation, dipCoord) 

     if isPointInFrontOfLineTest == 1: 
      measurementSymbolDistance = calculateDistance(measurementCoord, dipCoord) 
      # string = dipEntry[0] +":" + str(measurementSymbolDistance) 
      # measurementDistance.append(string) 
      measurementDistance.append(measurementSymbolDistance) 
     elif isPointInFrontOfLineTest == 0: 
      string = "" 
      measurementDistance.append(string) 
    exportArray.append(measurementDistance) 

for dip in dipsDictionary: 
    dipEntry = dipsDictionary[dip] 
    exportHeaders.append(dipEntry[0]) 

exportedArray = [exportHeaders] + exportArray 
export = np.array(exportedArray) 
np.savetxt("exportArray2.csv", export, fmt='%5s', delimiter=",") 
print(exportHeaders) 
+0

你能添加完整的代碼嗎? – sera

+0

盡我所能編輯和添加儘可能多的代碼! – labourday

回答

1

我做了一些代碼來解決類似的問題,這個一會兒回來PE345。我將使用我自己的陣列:

[[1,2,3], 
[4,5,6], 
[7,8,9]] 

你想要做的是獲得選擇特定元素的成本。通過查找選擇行的成本,添加選擇列的成本,然後減去選擇元素本身的成本來做到這一點。所以在我的數組中,選擇元素[0][0]的成本是(1+2+3)+(1+4+7)-3*(1)。我總結了0行,總結了0列,然後減去了元素本身。

現在你有選擇每個元素的成本。找到成本最高的元素。這將是網格中的最低值。選擇它並確保行或列中沒有其他值可以選擇。重複,直到選擇每行和每列的值。

這裏是我的項目的源代碼。請注意,它會找到最高值,而不是最低值。

from random import randint 
from itertools import permutations 
def make_a_grid(radius=5,min_val=0,max_val=999): 
    """Return a radius x radius grid of numbers ranging from min_val to max_val. 
    Syntax: make_a_grid(radius=5,min_val=0,max_val=999 
    """ 
    return [[randint(min_val,max_val) for i in xrange(radius)] for j in xrange(radius)] 
def print_grid(grid,rjustify = 4): 
    """Print a n x m grid of numbers, justified to a column. 
    Syntax: print_grid(grid,rjustify = 4) 
    """ 
    for i in grid: 
    outstr = '' 
    for j in i: 
     outstr += str(j).rjust(rjustify) 
    print outstr 
def brute_search(grid): 
    """Brute force a grid to find the maximum sum in the grid.""" 
    mx_sum = 0 
    for r in permutations('',5): 
    mx_sum = max(sum([grid[i][int(r[i])] for i in xrange(5)]),mx_sum) 
    return mx_sum 
def choose(initial_grid,row,col): 
    """Return a grid with a given row and column zeroed except where they intersect.""" 
    grid = [sub[:] for sub in initial_grid] #We don't actually want to alter initial_grid 
    Special_value = grid[row][col] #This is where they intersect. 
    grid[row] = [0]*len(grid[row]) #zeroes the row. 
    for i in xrange(len(grid)): 
    grid[i][col] = 0 
    grid[row][col] = Special_value 
    print_grid(grid) 
    return grid 
def smart_solve(grid): 
    """Solve the grid intelligently. 
    """ 
    rowsum = [sum(row) for row in grid] #This is the cost for any element in a given row. 
    print rowsum 
    colsum = [sum(row) for row in [[grid[i][j] for i in xrange(len(grid))] for j in xrange(len(grid[0]))]] #Cost for any element in a given column 
    print colsum,"\n" 
    total_cost = [map(lambda x: x+i,rowsum) for i in colsum] #This adds rowsum and colsum together, yielding the cost at a given index. 
    print_grid(total_cost,5) 
    print "\n" 
    #Total_cost has a flaw: It counts the value of the cell twice. It needs to count it -1 times, subtracting its value from the cost. 
    for i in xrange(len(grid)): #For each row 
    for j in xrange(len(grid[0])): #For each column 
     total_cost[i][j] -= 3*(grid[i][j]) #Remove the double addition and subtract once. 
    ###Can I turn ^^that into a list comprehension? Maybe use zip or something?### 
    print_grid(total_cost,5) 
    return total_cost 
def min_value(grid): 
    """return the minimum value (And it's index) such that value>0. 
    Output is: (value,col,row)""" 
    min_value,row,col = grid[0][0],0,0 
    for row_index,check_row in enumerate(grid): 
    for col_index,check_val in enumerate(check_row): 
     #print "Min_value: %d\n Check_Val: %d\n Location: (%d,%d)"%(min_value,check_val,row_index,col_index) 
     if min_value>check_val>0: 
     min_value = check_val 
     row = row_index 
     col = col_index 
    return (min_value,row,col) 
+0

非常感謝!這很有意義。但是,我有兩個後續問題:1.爲什麼你減去3 *(1)?我假設1是[0] [0]處數組的值? 2.你是如何提出「選擇元素的代價」的想法的?有沒有我可以研究的來源變得更加熟悉?再次感謝!! – labourday

+0

除了我的經濟學教科書外,我無法真正引用任何資料。這是機會成本的一個例子。我減去三次是因爲兩個原因:其中一次,當我抓住行和列時,我增加了兩次。二,當你想要做某件事的成本時,好處可以抵消成本,所以你減去了價值。 –

相關問題