Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I want to know how can i implement a weighted undirected graph in python for map. Map have cities and some road, which link between citiies and have respective weight.
If you don't want to just use one of the available graph libraries…
A standard way of representing graphs is an adjacency list. You can implement this as a dictionary where the keys are node names (or some other ID to lookup nodes) and the values are a list of edges. The edges can be some data structure that gives you the connecting node name and a weight — anything from a tuple to a NamedTuple to a full edge class. For example here is a minimal weighted graph:
places = {
'A': set([('B', 10), ('C', 5)]),
'B': set([('D', 3), ('A', 10)]),
'C': set([('F', 20), ('G', 9), ('A', 5)]),
'D': set([('B', 3)]),
'F': set([('C', 20)]),
'G': set([('C', 9)])
}
You can tell it's undirected because each edge appears twice — in the source and the destination node's list.
This format will support the primary graph algorithms like DFS, BFS, Dijkstra...
Here's a quick and dirty depth first search:
places = {
'A': set([('B', 10), ('C', 5)]),
'B': set([('D', 3), ('A', 10)]),
'C': set([('F', 20), ('G', 9), ('A', 5)]),
'D': set([('B', 3)]),
'F': set([('C', 20)]),
'G': set([('C', 9)])
}
def findARoute(start, end, places, visited = None):
if visited is None:
visited = set()
visited.add(start)
try:
edges = places[start]
except KeyError:
return # node not in graph
for edge in edges:
node, wieght = edge
if node not in visited:
print(f'Trying {start} -> {node}')
if node == end:
print(f'Found: {end}')
return
findARoute(node, end, places, visited)
findARoute('A', 'G', places)
Prints:
Trying A -> B
Trying B -> D
Trying A -> C
Trying C -> F
Trying C -> G
Found: G
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 days ago.
Improve this question
I want to make a restriction so that distances between two notes that are > 10 not to be selected . THIS CODE IS NOT MINE
This is the website from wich i found the code https://www.vtupulse.com/artificial-intelligence/implementation-of-a-star-search-algorithm-in-python/
def aStarAlgo(start_node, stop_node):
open_set = set(start_node)
closed_set = set()
g = {} #store distance from starting node
parents = {}
# parents contains an adjacency map of all nodes
#distance of starting node from itself is zero
g[start_node] = 0
#start_node is root node i.e it has no parent nodes
#so start_node is set to its own parent node
parents[start_node] = start_node
while 0 < len(open_set) :
n = None
#node with lowest f() is found
for v in open_set:
if n == None or g[v] + heuristic(v) < g[n] + heuristic(n):
n = v
if n == stop_node or Graph_nodes[n] == None:
pass
else:
for (m, weight) in get_neighbors(n):
#nodes 'm' not in first and last set are added to first
#n is set its parent
if m not in open_set and m not in closed_set:
open_set.add(m)
parents[m] = n
g[m] = g[n] + weight
#for each node m,compare its distance from start i.e g(m) to the
#from start through n node
else:
if g[m] > g[n] + weight:
#update g(m)
g[m] = g[n] + weight
#change parent of m to n
parents[m] = n
#if m in closed set,remove and add to open
if m in closed_set:
closed_set.remove(m)
open_set.add(m)
if n == None:
print('Path does not exist!')
return None
# if the current node is the stop_node
# then we begin reconstructin the path from it to the start_node
if n == stop_node :
path = []
while parents[n] != n:
path.append(n)
n = parents[n]
path.append(start_node)
path.reverse()
print('Path found: {}'.format(path))
return path
# remove n from the open_list, and add it to closed_list
# because all of his neighbors were inspected
open_set.remove(n)
closed_set.add(n)
print('Path does not exist!')
return None
#define fuction to return neighbor and its distance
#from the passed node
def get_neighbors(v):
if v in Graph_nodes:
return Graph_nodes[v]
else:
return None
#for simplicity we ll consider heuristic distances given
#and this function returns heuristic distance for all nodes
def heuristic(n):
H_dist = {
'A': 1,
'B': 1,
'C': 1,
'D': 1,
'E': 1,
'G': 1,
}
return H_dist[n]
#Describe your graph here
Graph_nodes = {
'A': [('B', 1), ('E', 5)],
'B': [('A', 1), ('C', 3), ('G', 11)],
'C': [('B', 3)],
'D': [('E', 7), ('G', 7)],
'E': [('A', 5), ('D', 7)],
'G': [('B', 9), ('D', 7)]
}
aStarAlgo('A', 'G')
This is the website from wich i found the code https://www.vtupulse.com/artificial-intelligence/implementation-of-a-star-search-algorithm-in-python/`your text``
I have the following dictionary with the first number being the node, followed by a tuple consisting of a neighbor and then the edge weight (some nodes have multiple neighbors and weights):
dictionary = {1: [(2, 3), (4, 5), (6, 2)], 2: [(3, -4)], 3: [(8, 4)], 4: [(5, 6)], 5: [(4, -3), (8, 8)], 6: [(7, 3)], 7: [(6, -6), (8, 7)]}
How would I use Depth First Search (DFS) to detect if there is a cycle or not? The dictionary will be changed frequently for testing purposes, so some may have cycles and some may not. I am new to python and do not understand how to implement DFS to check for a cycle or not. I have the following DFS code:
visited = set() # Set to keep track of visited nodes of graph.
def dfs(visited, dictionary, node): #function for dfs
if node not in visited:
print (node)
visited.add(node)
for neighbour in dictionary[node]:
dfs(visited, dictionary, neighbour)
and then I call the function: dfs(visited, dictionary, '1').
But I get the error KeyError: '1'. I also am unsure how to use this code to detect for a cycle or not.
First we consider the base cases. In this instance, we wish to evaluate whether the graph has a cycle or not. The function should return true when a cycle is detected, and false if no such cycle exists after all edges have been examined.
dictionary = {1: [(2, 3)], 2: [], 3: [(4, 4)], 4: [(3, 6)]}
def DFS(visited, dictionary, node):
if node in visited:
return True
else:
for neighbour, weight in dictionary[node]:
if DFS(visited | {node}, dictionary, neighbour):
return True
return False
print(f"{DFS(set(), dictionary, 1)=}") # False
Depth first search will examine all paths from a single node, going exploring as far as it can before backtracking. If it encounters a node it has seen before, the search will stop and the function returns true. If all paths from the starting node have been exhausted, it returns false. This will only detect whether node 1 is involved in any cycles.
However, this approach is not enough to detect cycles which does not involve the starting node. In the above example, the DFS will not find the cycle between nodes 3 and 4, as it starts its search from 1.
To fix this, we can write another function which examines all the nodes with the DFS.
def containsCycle(dictionary):
for node in dictionary.keys():
if DFS(set(), dictionary, node):
return True
return False
print(f"{containsCycle(dictionary)=}") # True
dictionary = {1: [(2, 3), (4, 5), (6, 2)], 2: [(3, -4)],
3: [(8, 4)], 4: [(5, 6)], 5: [(4, -3), (8, 8)],
6: [(7, 3)], 7: [(6, -6), (8, 7)]}
The dictionary above has a edges to a node 8, without an entry for that node in the dictionary. This will cause an error. To resolve this, we can add a guard clause to our recursive function.
def DFS(visited, dictionary, node):
if node in visited:
return True
elif node not in dictionary: # Guard clause
return False
else:
for neighbour, weight in dictionary[node]:
if DFS(visited | {node}, dictionary, neighbour):
return True
return False
i have a vector (it is the results of a classification )
which it means i and s[i] , are in the same class
for example:
S=(2,1,1,3,6,7,5,9,6,13,12,14,12,11)
(( `s[1]=2 `so node 1 and 2 are in same class
and `s[2]=1` same information
s[3]=1` so all 1,2,3 are in same class))
now i have to find a way to get a membership vector from s:
to see which nodes are in same class together
mVC=[1,1,1,1,2,2,2,2,2,3,3,3,3,3]
(here 1,2,3,4 are in one class)
The vector S looks like it represents a parent relationship, although it may contain cycles. So, if you consider this vector as if it is an adjacency list of a directed graph, and ran depth-first search (DFS) on this data structure, you would find the connected components of this graph, each of which would belong to the same class, by your terminology. You can also fill mVC while running the DFS, and obtain the data in the format you desire.
As opposed to the default DFS, though, you need to keep an eye out for a back edge or a cross edge, and update the classification of the nodes that are currently being explored, whenever one of those types of edges is encountered.
A sample implementation is below. When a back edge or a cross edge is encountered, the algorithm stops the recursion and bubbles up the component (i.e. classification info) of the destination of that edge, to the vertices that are currently being explored.
def dfs(S, u, mVC, currentComponent):
mVC[u] = currentComponent
if mVC[ S[u] ] == 0:
mVC[u] = dfs(S, S[u], mVC, currentComponent)
else:
mVC[u] = mVC[S[u]]
return mVC[u]
S = [0] + list(S) # to handle the 1-indexing of the content in S
mVC = [0] * len(S)
currentComponent = 1
for i in range(1, len(S)):
if mVC[ i ] == 0:
componentAssigned = dfs(S, i, mVC, currentComponent)
if componentAssigned == currentComponent:
currentComponent += 1
mVC = mVC[1:] # Gets rid of the dummy 0th element added above
# at this point, mVC contains the class relationship in the desired format
This is a connected components problem. Here's one approach:
S=(2,1,1,3,6,7,5,9,6,13,12,14,12,11)
Build a list of tuples, each of them representing edges in the graph, and consisting on the index of a given value in S and the value itself:
edges = [(ix+1, i) for ix, i in enumerate(S)]
# [(1, 2), (2, 1), (3, 1), (4, 3), (5, 6), (6, 7), (7, 5), (8,....
Build a network using networkx and extract its connected_components. This will group nodes "in the same class" together:
import networkx as nx
G=nx.Graph()
G.add_edges_from(edges)
list(nx.connected_components(G))
Output
[{1, 2, 3, 4}, {5, 6, 7, 8, 9}, {10, 11, 12, 13, 14}]
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
The task is to create a spam filter using machine learning. In order to do feature selection I have implemented a method that calculates MI for each word but then I want to return N words that have a high MI and choose between them based on how many times they appear in the spam email.
The reason for the additional requirement is that we are using the small lingspam set and there is little difference between the results and there are about 3000 words that share the same top MI value.
We are required to do this in Python and I have currently implemented this using dictionaries but I can't find a container type that would let me do what I need.
You can sort the items of a dictionary (you'll have to use a custom key), where the items are stored as a list.
>>> some_dictionary = {"a": 1, "b": 5, "c": 0, "e": 2}
>>> sorted(some_dictionary.items())
[('a', 1), ('b', 5), ('c', 0), ('e', 2)]
>>> sorted(some_dictionary.items(), key=lambda i:i[1])
[('c', 0), ('a', 1), ('e', 2), ('b', 5)]
>>>
Where .items() lets you get the items in the dictionary (in an arbitrary order):
>>> some_dictionary.items()
dict_items([('a', 1), ('b', 5), ('e', 2), ('c', 0)])
Note that dict_items is an iterable, which just wraps a list in this case.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Using python, I am trying to figure out how to extract unique keys from a list of tuple pairs, with the highest, lowest and average values, as well as a count of how many keys, for example with this list:
[('a', 1), ('b', 3,), ('a', 9), ('b', 0), ('b', 9), ('a', 10), ('c', 2)]
I need to extract this information:
a: max = 10, min = 1, avg = 7 count = 3
b: max = 9, min = 0, avg = 4 count = 3
c: max = 2, min = 2, avg = 2, count = 1
You can use a defaultdict to gather the information.
from collections import defaultdict
data = [('a', 1), ('b', 3,), ('a', 9), ('b', 0), ('b', 9), ('a', 10), ('c', 2)]
pool = defaultdict(list)
for key, value in data:
pool[key].append(value)
print(pool)
You should have no problem to implement the calculation of min, max and average (sum/len) for yourself.
Your target looks like a dictionary of dictionaries. So build dictionary taking the 1st element of each tuple as a key. Iterate through the tuples and build up the values for each.
You should end up with something like:
tally = {'a': {'count': 3, 'max': 10, 'avg': 7, 'min': 1}, ... etc.}