docs: def random(self, numnodes = 10, degree_range = (2, 4), length_range = (1, 10),
                 density = None, edge_format = None, node_format = None,
                 Euclidean = False, seedInput = 0, add_labels = True,
                 parallel_allowed = False, node_selection = 'closest',
                 scale = 10, scale_cost = 5):
          '''
          API:
              random(self, numnodes = 10, degree_range = None, length_range = None,
                 density = None, edge_format = None, node_format = None,
                 Euclidean = False, seedInput = 0)
          Description:
              Populates graph with random edges and nodes.
          Input:
              numnodes: Number of nodes to add.
              degree_range: A tuple that has lower and upper bounds of degree for
              a node.
              length_range: A tuple that has lower and upper bounds for 'cost'
              attribute of edges.
              density: Density of edges, ie. 0.5 indicates a node will
              approximately have edge to half of the other nodes.
              edge_format: Dictionary that specifies attribute values for edges.
              node_format: Dictionary that specifies attribute values for nodes.
              Euclidean: Creates an Euclidean graph (Euclidean distance between
              nodes) if True.
              seedInput: Seed that will be used for random number generation.
          Pre:
              It is recommended to call this method on empty Graph objects.
          Post:
              Graph will be populated by nodes and edges.
          '''
          random.seed(seedInput)
          if edge_format == None:
              edge_format = {'fontsize':10,
                             'fontcolor':'blue'}
          if node_format == None:
              node_format = {'height':0.5,
                             'width':0.5,
                             'fixedsize':'true',
                             'fontsize':10,
                             'fontcolor':'red',
                             'shape':'circle',
                             }
          if Euclidean == False:
              for m in range(numnodes):
                  self.add_node(m, **node_format)
              if degree_range is not None and density is None:
                  for m in range(numnodes):
                      degree = random.randint(degree_range[0], degree_range[1])
                      i = 0
                      while i < degree:
                          n = random.randint(1, numnodes-1)
                          if (((m,n) not in self.edge_attr and m != n) and
                              (parallel_allowed or (n, m) not in self.edge_attr)):
                              if length_range is not None:
                                  length = random.randint(length_range[0],
                                                          length_range[1])
                                  self.add_edge(m, n, cost = length, **edge_format)
                                  if add_labels:
                                      self.set_edge_attr(m, n, 'label', str(length))
                                  else:
                                      self.add_edge(m, n, **edge_format)
                          i += 1
              elif density != None:
                  for m in range(numnodes):
                      if self.graph_type == DIRECTED_GRAPH:
                          numnodes2 = numnodes
                      else:
                          numnodes2 = m
                      for n in range(numnodes2):
                          if ((parallel_allowed or (n, m) not in self.edge_attr)
                              and m != n):
                              if random.random() < density:
                                  if length_range is not None:
                                      length = random.randint(length_range[0],
                                                       length_range[1])
                                      self.add_edge(m, n, cost = length,
                                                    **edge_format)
                                      if add_labels:
                                          self.set_edge_attr(m, n, 'label', str(length))
                                  else:
                                      self.add_edge(m, n, **edge_format)
              else:
                  print("Must set either degree range or density")
          else:
              for m in range(numnodes):
                  ''' Assigns random coordinates (between 1 and 20) to the nodes
                  '''
                  x = random.random()*scale
                  y = random.random()*scale
                  self.add_node(m, locationx = x, locationy = y,
                                pos = '"'+str(x) + "," + str(y)+'!"',
                                **node_format)
              if degree_range is not None and density is None:
                  for m in range(numnodes):
                      degree = random.randint(degree_range[0], degree_range[1])
                      i = 0
                      neighbors = []
                      if node_selection is 'random':
                          while i < degree:
                              length = round((((self.get_node(n).get_attr('locationx') -
                                                self.get_node(m).get_attr('locationx')) ** 2 +
                                               (self.get_node(n).get_attr('locationy') -
                                                self.get_node(m).get_attr('locationy')) ** 2) ** 0.5)*scale_cost,
                                             0)
                              if (((m,n) not in self.edge_attr and m != n) and
                                  (parallel_allowed or (n, m) not in self.edge_attr)):
                                  neighbors.append(random.randint(0, numnodes-1))
                                  self.add_edge(m, n, cost = int(length), **edge_format)
                                  if add_labels:
                                      self.set_edge_attr(m, n, 'label', str(int(length)))
                                  i += 1
                      elif node_selection is 'closest':
                          lengths = []
                          for n in range(numnodes):
                              lengths.append((n, round((((self.get_node(n).get_attr('locationx') -
                                                          self.get_node(m).get_attr('locationx')) ** 2 +
                                                         (self.get_node(n).get_attr('locationy') -
                                                          self.get_node(m).get_attr('locationy')) ** 2) ** 0.5)*scale_cost,
                                                       0)))
                          lengths.sort(key = lambda l : l[1])
                          for i in range(degree+1):
                              if not (lengths[i][0] == m or self.check_edge(m, lengths[i][0])):
                                  self.add_edge(m, lengths[i][0], cost = int(lengths[i][1]), **edge_format)
                                  if add_labels:
                                      self.set_edge_attr(m, lengths[i][0], 'label', str(int(lengths[i][1])))
                      else:
                          print("Unknown node selection rule...exiting")
                          return
              elif density != None:
                  for m in range(numnodes):
                      if self.graph_type == DIRECTED_GRAPH:
                          numnodes2 = numnodes
                      else:
                          numnodes2 = m
                      for n in range(numnodes2):
                          if ((parallel_allowed or (n, m) not in self.edge_attr)
                              and m != n):
                              if random.random() < density:
                                  if length_range is None:
                                      ''' calculates the euclidean norm and round it
                                      to an integer '''
                                      length = round((((self.get_node(n).get_attr('locationx') -
                                                        self.get_node(m).get_attr('locationx')) ** 2 +
                                                       (self.get_node(n).get_attr('locationy') -
                                                        self.get_node(m).get_attr('locationy')) ** 2) ** 0.5), 0)
                                      self.add_edge(m, n, cost = int(length), **edge_format)
                                      if add_labels:
                                          self.set_edge_attr(m, n, 'label', str(int(length)))
                                  else:
                                      self.add_edge(m, n, **edge_format)
              else:
                  print("Must set either degree range or density")