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")