1

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'
Eric Inclan
  • 327
  • 1
  • 5
  • 14

1 Answers1

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.

heltonbiker
  • 26,657
  • 28
  • 137
  • 252
  • Thank you for going into detail. In this case, it seems like I should have two sets of graphs. The current SAR graph, and a second graph G = disjoint_union_all(SAR.nodes()), then go back and forth for different calculations and edge definitions. Is that correct? If so, is it even possible to have edges between nodes AND groups of nodes all in one graph? This makes it seem as though it's impossible in Networkx, but @Joel from the linked question made it seem it was possible. Maybe I misread his answer.... Also, what about in iGraph or graph_tool? – Eric Inclan Aug 17 '18 at 19:24
  • I think that your interpretation is correct. You could not, as far as I know, have two graphs and add an edge between a node in one and a node in other. That wouldn't make sense. You should then create another graph. Notice that you could have an object and insert it as a node in more than one graph. That way, you could have a set of objects that exist independently, and one or more graphs that represent the mapping (the edges) between those objects. – heltonbiker Aug 18 '18 at 18:23