I have a list of lists that I have used to store the distances between objects.
The table looks something like this:
+----------+----------+----------+----------+----------+
| | 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 |
+----------+----------+----------+----------+----------+
The numbers represent the distance between the row & column header.
This was calculated roughly as follows:
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)
This gave me roughly the information in the table above.
What I am looking to do is basically find the closest object to each entity (or vice versa). Each object or entity can only be matched with one other, and it should be based on proximity.
They way I have done this right now is by simply ordering the nested lists by size in distances (in the full code I have a way of determining which object is associated with each distance).
So, in doing that I would create the following associations:
+----------+----------+----------+
| Entity | Object | Distance |
+----------+----------+----------+
| Entity_E | Object_D | 1 |
+----------+----------+----------+
| Entity_F | Object_D | 2 |
+----------+----------+----------+
| Entity_G | Object_B | 1 |
+----------+----------+----------+
This is incorrect because it associates Object_D twice.
The association should be:
+----------+----------+----------+
| Entity | Object | Distance |
+----------+----------+----------+
| Entity_E | Object_D | 1 |
+----------+----------+----------+
| Entity_F | Object_A | 3 |
+----------+----------+----------+
| Entity_G | Object_B | 1 |
+----------+----------+----------+
This is where I am struggling - I can't figure out the best way to code logic for this.
Since Entity_E is closer to Object_D, it should get the association. So, for Entity_F, I need to take the second closest.
I was thinking about doing something where I record which Objects have already been assigned, or trying to do something where I match the min values in each column first, but they all seem to run into problems.
Is there a matrix operation or some kind of matrix math I could use to do this calculation?
Any advice would be much appreciated!
Edit - Added Full Code:
# 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)