Follow-up: add edge connecting nodes of two separa

2019-08-13 19:06发布

问题:

I am fairly proficient in C++, but I am learning python, NetworkX, and about pythonic code all at the same time. After reading various websites and the reference my question is the same as this question. The difference is the approach I am taking to implement my task. Please note this question is about adding an edge, not drawing. I have a graph (SAR), whose nodes are also graphs (Boat, and Adrift),

import networkx as nx
import math

# User Inputs
Num_Adrift = 4

# Cluster Definition
Boat = nx.Graph(P_Weight=7000,P_Vol=9*29*60,P_MPG=1,P_Speed=20,P_Crew_Lim=5,P_Asset=1,P_Count=1)
Adrift = nx.Graph(P_Distance=2,P_Time_Lim=30,P_DriftSpeed=1,P_Asset=0,P_Count=Num_Adrift)
SAR = nx.Graph(P_Success = 0)

# SAR Graph
SAR.add_node(Boat)
SAR.add_node(Adrift)

This is the approach introduced in the comments to the above question. I can connect Boat to Adrift using,

SAR.add_edge(Boat,Adrift,weight=1)

Suppose Boat has a node:

Boat.add_node("embark",P_Material=1,C_supply=1)

and Adrift has the node,

Adrift.add_node("embark",P_lock=1,P_Material=1,C_supply=0)

They have the same names (on purpose, to automate node connections and calculations later).

Question 1: Why doesn't this syntax work, and how do I fix it? Is it because they are not nodes within SAR per-se?

SAR.add_edge(Boat.node["embark"],Adrift.node["embark"],weight=1)

Question 2: Is NetworkX capable of distinguishing between Boat.node["embark"] and Adrift.node["embark"] or will it think I am trying to make an edge from a node to itself?

The error I get is:

---> 76                         SAR.add_edge(Boat.node["embark"],Adrift.node["embark"],weight=1) #<--- this part of code = problem :(

/anaconda3/lib/python3.6/site-packages/networkx/classes/graph.py in add_edge(self, u_of_edge, v_of_edge, **attr)
    873         u, v = u_of_edge, v_of_edge
    874         # add nodes
--> 875         if u not in self._node:
    876             self._adj[u] = self.adjlist_inner_dict_factory()
    877             self._node[u] = {}

TypeError: unhashable type: 'dict'

回答1:

TypeError: unhashable type: 'dict'

NetworkX uses python dicts as a data structure. So when you add a node, the node is the key to a given value in the dict, for example its list of edges.

For an object to be a key, it must be unique. To compare uniqueness between keys, the object must be hashable.

Since dictionaries are not hashable, you cannot use a dictionary as a key, therefore you cannot use a dictionary as a node.

What you can do is to map, say, integers to your dictionaries and store that in another dictionary. Then, you could have the integers as nodes, and get the actual values from the other dict.