I have a class and some functions. In the 'check_reflexive()' function, there is a variable called reflexive_list. I want to use this variable also in the 'antisymmetric' function.
I checked some examples about class but didn't find a specific example to solve this problem.
I'll be waiting for your advice. Hope you have a nice day
class MyClass():
def __init__(self):
def checkif_pair(k):
for a in k:
if a%2 == 0:
None
else:
return False
return True
def check_reflexive(k):
j = 0
z = 0
reflexive_list = []
while j < len(k):
i = 0
while i < len(k):
if k[i] == k[j]:
tup = k[j],k[i]
reflexive_list.append(tup)
i += 1
else:
None
j = j + 1
else:
None
print(reflexive_list)
if len(reflexive_list) == len(self.list1):
return True
else:
return False
def antisymmetric(k):
antisymettric_list = []
for b in k:
swap1 = b[0]
swap2 = b[1]
newtuple = (swap2, swap1)
antisymettric_list.append(newtuple)
for ü in reflexive_list:
if ü in antisymettric_list:
antisymettric_list.remove(ü)
else:
None
print(antisymettric_list)
for q in antisymettric_list:
if q in k:
print("The system is not Anti-Symmetric.")
break
print("The system is Anti-Symmetric.")
def transitive(k):
result = {}
for first, second in k:
result.setdefault(first, []).append(second)
print(result)
for a, b in k:
for x in result[b]:
if x in result[a]:
None
else:
print("There is no {} in the {}".format(x, result[a]))
return False
return True
You can just use reflexive_list as an instance variable. Just add a constructor where the variable is defined:
class MyClass():
def __init__(self):
self.reflexive_list = []
And everytime you want to use it inside the function, you use self.reflexive_list
This is the python code which uses A* algorithm for finding solution for 8 puzzle problems, I got some error messages, how can I fix it?(The error message is under the code)
There are several object-oriented programming concepts for Problems class, Node class that are implemented to express the problem solution search that you need to understand in order to make the Python program complete. The priority queue is to make the nodes to be explored to be sorted according to their f-evaluation function score and return the min one as the first node to be searched next.
There is also a memorize function to memorize the heuristic value of state as a look-up table so that you don’t need to calculate the redundant computing of heuristic estimation value, so you can ignore it at this point if you don’t understand.
The components you need to implement is to make the abstract part of the program realizable for 8 -puzzle with the successor methods attached to a problem class which consists of initial state and goal state. Make sure the program can run correctly to generate the solution sequence that move the empty tile so that the 8-puzzle can move "Up", "Down", "Left", "Right", from initial state to goal state.
import math
infinity = math.inf
from itertools import chain
import numpy as np
import bisect
class memoize:
def __init__(self, f, memo={}):
self.f = f
self.memo = {}
def __call__(self, *args):
if not str(args) in self.memo:
self.memo[str(args)] = self.f(*args)
return self.memo[str(args)]
def coordinate(state):
index_state = {}
index = [[0,0], [0,1], [0,2], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]]
for i in range(len(state)):
index_state[state[i]] = index[i]
return index_state
def getInvCount(arr):
inv_count = 0
empty_value = -1
for i in range(0, 9):
for j in range(i + 1, 9):
if arr[j] != empty_value and arr[i] != empty_value and arr[i] > arr[j]:
inv_count += 1
return inv_count
def isSolvable(puzzle) :
inv_count = getInvCount([j for sub in puzzle for j in sub])
return (inv_count % 2 == 0)
def linear(state):
return sum([1 if state[i] != goal[i] else 0 for i in range(9)])
#memoize
def manhattan(state):
index_goal = coordinate(goal)
index_state = coordinate(state)
mhd = 0
for i in range(9):
for j in range(2):
mhd = abs(index_goal[i][j] - index_state[i][j]) + mhd
return mhd
#memoize
def sqrt_manhattan(state):
index_goal = coordinate(goal)
index_state = coordinate(state)
mhd = 0
for i in range(9):
for j in range(2):
mhd = (index_goal[i][j] - index_state[i][j])**2 + mhd
return math.sqrt(mhd)
#memoize
def max_heuristic(state):
score1 = manhattan(state)
score2 = linear(state)
return max(score1, score2)
class PriorityQueueElmt:
def __init__(self,val,e):
self.val = val
self.e = e
def __lt__(self,other):
return self.val < other.val
def value(self):
return self.val
def elem(self):
return self.e
class Queue:
def __init__(self):
pass
def extend(self, items):
for item in items: self.append(item)
class PriorityQueue(Queue):
def __init__(self, order=min, f=None):
self.A=[]
self.order=order
self.f=f
def append(self, item):
queueElmt = PriorityQueueElmt(self.f(item),item)
bisect.insort(self.A, queueElmt)
def __len__(self):
return len(self.A)
def pop(self):
if self.order == min:
return self.A.pop(0).elem()
else:
return self.A.pop().elem()
# Heuristics for 8 Puzzle Problem
class Problem:
def __init__(self, initial, goal=None):
self.initial = initial; self.goal = goal
def successor(self, state):
reachable = []
def get_key(val):
for key, value in index_state.items():
if val == value:
return key
return -1
def candidate(state, Position):
state = state.copy()
zero_index = state.index(0)
swap_index = state.index(get_key(Position))
state[zero_index], state[swap_index] = state[swap_index], state[zero_index]
return state
index_state = coordinate(state)
zero_position = index_state[0]
move_pair = {"left":[zero_position[0], zero_position[1] - 1],
"right":[zero_position[0], zero_position[1] + 1],
"up":[zero_position[0] - 1, zero_position[1]],
"down":[zero_position[0] + 1, zero_position[1]]
}
for action, position in move_pair.items():
#print(action, position)
if get_key(position) != -1:
reachable.append((action, candidate(state, position)))
#print(reachable)
return reachable
def goal_test(self, state):
return state == self.goal
def path_cost(self, c, state1, action, state2):
return c + 1
def value(self):
abstract
class Node:
def __init__(self, state, parent=None, action=None, path_cost=0, depth =0):
self.parent = parent
if parent:
self.depth = parent.depth + 1
else:
self.depth = 0
self.path_cost = path_cost
self.state = state
if action:
self.action = action
else: self.action = "init"
def __repr__(self):
return "Node state:\n " + str(np.array(self.state).reshape(3,3)) +"\n -> action: " + self.action + "\n -> depth: " + str(self.depth)
def path(self):
x, result = self, [self]
while x.parent:
result.append(x.parent)
x = x.parent
return result
def expand(self, problem):
for (act,n) in problem.successor(self.state):
if n not in [node.state for node in self.path()]:
yield Node(n, self, act,
problem.path_cost(self.path_cost, self.state, act, n))
def graph_search(problem, fringe):
closed = {}
fringe.append(Node(problem.initial,depth=0))
while fringe:
node = fringe.pop()
if problem.goal_test(node.state):
return node
if str(node.state) not in closed:
closed[str(node.state)] = True
fringe.extend(node.expand(problem))
return None
def best_first_graph_search(problem, f):
return graph_search(problem, PriorityQueue(min, f))
def astar_search(problem, h = None):
h = h or problem.h
def f(n):
return max(getattr(n, 'f', -infinity), n.path_cost + h(n.state))
return best_first_graph_search(problem, f)
def print_path(path, method):
print("*" * 30)
print("\nPath: (%s distance)" % method)
for i in range(len(path)-1, -1, -1):
print("-" * 15)
print(path[i])
goal = [1, 2, 3, 4, 5, 6, 7, 8, 0]
# Solving the puzzle
puzzle = [7, 2, 4, 5, 0, 6, 8, 3, 1]
if(isSolvable(np.array(puzzle).reshape(3,3))): # even true
# checks whether the initialized configuration is solvable or not
print("Solvable!")
problem = Problem(puzzle,goal)
path = astar_search(problem, manhattan).path()
print_path(path, "manhattan")
path = astar_search(problem, linear).path()
print_path(path, "linear")
path = astar_search(problem, sqrt_manhattan).path()
print_path(path, "sqrt_manhattan")
path = astar_search(problem, max_heuristic).path()
print_path(path, "max_heuristic")
else :
print("Not Solvable!") # non-even false
TypeError Traceback (most recent call last)
<ipython-input-124-2a60ddc8c009> in <module>
9 problem = Problem(puzzle,goal)
10
---> 11 path = astar_search(problem, manhattan).path()
12 print_path(path, "manhattan")
13
<ipython-input-123-caa97275712e> in astar_search(problem, h)
18 def f(n):
19 return max(getattr(n, 'f', -infinity), n.path_cost + h(n.state))
---> 20 return best_first_graph_search(problem, f)
21
22 def print_path(path, method):
<ipython-input-123-caa97275712e> in best_first_graph_search(problem, f)
12
13 def best_first_graph_search(problem, f):
---> 14 return graph_search(problem, PriorityQueue(min, f))
15
16 def astar_search(problem, h = None):
<ipython-input-123-caa97275712e> in graph_search(problem, fringe)
8 if str(node.state) not in closed:
9 closed[str(node.state)] = True
---> 10 fringe.extend(node.expand(problem))
11 return None
12
<ipython-input-121-e5a968bd54f0> in extend(self, items)
18
19 def extend(self, items):
---> 20 for item in items: self.append(item)
21
22 class PriorityQueue(Queue):
<ipython-input-122-db21613469b9> in expand(self, problem)
69
70 def expand(self, problem):
---> 71 for (act,n) in problem.successor(self.state):
72 if n not in [node.state for node in self.path()]:
73 yield Node(n, self, act,
TypeError: cannot unpack non-iterable int object
I got some error messages, how can I fix it?
There is one error message, The pieces of codes you get in the error message are the stack trace, which might help you to know how the execution got at the final point where the error occurred. In this case that is not so important. The essence of the error is this:
for (act,n) in problem.successor(self.state)
TypeError: cannot unpack non-iterable int object
So this means that the successor method returned an int instead of a list.
Looking at the code for successor, I notice that it intends to return a list called reachable, but there is a return statement right in the middle of the code, leaving the largest part of that code unexecuted (so-called "dead code"):
return state
This statement makes no sense where it is positioned. It seems to be an indentation problem: that return belongs inside the function just above it, like this:
def candidate(state, Position):
state = state.copy()
zero_index = state.index(0)
swap_index = state.index(get_key(Position))
state[zero_index], state[swap_index] = state[swap_index], state[zero_index]
return state # <-- indentation!
I have a python program in which I have a class called Vector and an empty list inside of that class which is being populated runtime.
Here is the init:
def __init__(self,n):
self.vector = [];
self.n = n;
for x in range(n):
self.vector.append(False);
And here is the eq:
def __eq__(self, other):
t = True
for x in range(self.n):
if self.vector[x] != other.vector[x]:
t = False;
return t
however, when I try to check if 2 objects of this type are equal, I always get true, even though I changed values inside of vector in Vector class.
Here is the code where I do the above:
vectors = []
n = tmp.size();
k = calculateCombinationCount(n,int(n/2))
for i in range(k):
for j in range(0,n-1):
if (tmp.vector[j] != tmp.vector[j+1]):
t = True
for x in vectors:
if x == tmp:
t = False;
if t:
vectors.append(tmp)
tmp.printVector();
tmp.swap(j,j+1);
I would appreciate any help that you can provide. Thank you :)
EDIT:
def swap(self,i,j):
tmp = self.vector[i]
self.vector[i] = self.vector[j]
self.vector[j] = tmp
def calculateCombinationCount(n,r):
k = factorial(n)/(factorial(int(r))*factorial(int(n-r)))
return int(k)
Right so I've updated your code to be much more pythonic (I can tell you come from another language, Java?).
from math import factorial
class Vector:
def __init__(self, size):
self.size = size
self.vector = [False] * size
def __eq__(self, other):
"""
Same if self.size == other.size
"""
assert self.size == other.size, (self.size, other.size)
return self.vector == other.vector
def print_vector(self):
print(self.vector)
def swap(self, i, j):
"""
More efficient and pythonic
"""
self.vector[i], self.vector[j] = self.vector[j], self.vector[i]
def calculate_combination_count(n, r):
"""
This is slow, I'd replace it with scipy.special.comb
https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.comb.html#scipy.special.comb
"""
return factorial(n) // (factorial(r) * factorial(n-r))
tmp = Vector(10)
vectors = []
n = tmp.size
k = calculate_combination_count(n, n // 2)
for i in range(k):
for j in range(0, n-1):
if tmp.vector[j] != tmp.vector[j + 1]:
if not any(vec == tmp for vec in vectors): # much more efficient
vectors.append(tmp)
tmp.print_vector()
tmp.swap(j, j + 1)
else: # Just to prove why it doesn't work
print('tmp.vector is all False: {}'.format(not all(tmp.vector)))
This prints out tmp.vector is all False: True repeatedly. I think this is your problem.
If you
I built a disjoint-set data structure for use with Kruskal's MST algorithm. I need to load and then union a graph with 200k interconnected nodes and I think my data structure implementation is a bottleneck.
Do you have an suggestions for how to improve performance? I think my find method might be problematic.
class partition(object):
def __init__(self, element=None):
self.size = 0
if element == None:
self.contents = set()
self.representative = None
else:
self.contents = {element}
self.representative = element
self.size = 1
def find(self, element):
return element in self.contents
def add(self, partition):
self.contents = self.contents.union(partition)
self.size = len(self.contents)
def show(self):
return self.contents
def __repr__(self):
return str(self.contents)
class disjoint_set(object):
def __init__(self):
self.partitions_count = 0
self.forest = {}
def make_set(self, element):
if self.find(element) == False:
new_partition = partition(element)
self.forest[new_partition.representative] = new_partition
self.partitions_count += 1
def union(self, x, y):
if x != y:
if self.forest[x].size < self.forest[y].size:
self.forest[y].add(self.forest[x].show())
self.delete(x)
else:
self.forest[x].add(self.forest[y].show())
self.delete(y)
def find(self, element):
for partition in self.forest.keys():
if self.forest[partition].find(element):
return self.forest[partition].representative
return False
def delete(self, partition):
del self.forest[partition]
self.partitions_count -= 1
if __name__ == '__main__':
t = disjoint_set()
t.make_set(1)
t.make_set(2)
t.make_set(3)
print("Create 3 singleton partitions:")
print(t.partitions_count)
print(t.forest)
print("Union two into a single partition:")
t.union(1,2)
print(t.forest)
print(t.partitions_count)
EDIT:
After reading the comments and doing additional research I realized how poorly designed my original algorithm was. I started over from scratch and put this together. I put all the partitions into a single hash table and used path compression in the find(). How does this look and are there any glaring problems I should address?
class disjoint_set(object):
def __init__(self):
self.partitions_count = 0
self.size = {}
self.parent = {}
def make_set(self, element):
if self.find(element) == False:
self.parent[element] = element
self.size[element] = 1
self.partitions_count += 1
def union(self, x, y):
xParent = self.find(x)
yParent = self.find(y)
if xParent != yParent:
if self.size[xParent] < self.size[yParent]:
self.parent[xParent] = yParent
self.size[yParent] += self.size[xParent]
self.partitions_count -= 1
else:
self.parent[yParent] = xParent
self.size[xParent] += self.size[yParent]
self.partitions_count -= 1
def find(self, element):
if element in self.parent:
if element == self.parent[element]:
return element
root = self.parent[element]
while self.parent[root] != root:
root = self.find(self.parent[root])
self.parent[element] = root
return root
return False
if __name__ == '__main__':
t = disjoint_set()
t.make_set(1)
t.make_set(2)
t.make_set(3)
t.make_set(4)
t.make_set(5)
print("Create 5 singleton partitions")
print(t.partitions_count)
print("Union two singletons into a single partition")
t.union(1,2)
print("Union three singletones into a single partition")
t.union(3,4)
t.union(5,4)
print("Union a single partition")
t.union(2,4)
print("Parent List: %s" % t.parent)
print("Partition Count: %s" % t.partitions_count)
print("Parent of element 2: %s" % t.find(2))
print("Parent List: %s" % t.parent)
I guess your find implementation is not running effienctly, which it supposed to be.
Following changes may help.
class disjoint_set(object):
def __init__(self):
self.partitions_count = 0
self.forest = {}
self.parent = {}
def make_set(self, element):
if not self.find(element):
new_partition = partition(element)
self.parent[element] = element
self.forest[new_partition.representative] = new_partition
self.partitions_count += 1
def union(self, x, y):
if x != y:
if self.forest[x].size < self.forest[y].size:
self.forest[y].add(self.forest[x].show())
#Update parent details
self.parent[self.forest[x].representative] = self.forest[y].representative
self.delete(x)
else:
self.forest[x].add(self.forest[y].show())
#Update parent details
self.parent[self.forest[y].representative] = self.forest[x].representative
self.delete(y)
def find(self, element):
if self.parent[element] == element:
return element
else:
return find(element)
The code can be still optimized with path-compression to have disjoint_set.find to run in O(1). I guess O(log n) still is good for big numbers.
Another bottleneck could be your union function. Especially the add function implementation.
def add(self, partition):
self.contents = self.contents.union(partition)
Try using an update method of set (which is an inplace union). I think is causing lot of memory overhead for huge no.of nodes. Something like
self.contents.update(partition)
There is a nice discussion on set union and update functions here.
Hope it helps!
I'm learning Python OOP and trying to convert a Java class to a Python class
See page 15 in this PDF for Java code google doc link
class QuickFindUF:
"""docstring for QuickFindUF"""
def __init__(self, n):
self.id = []
for e in range(n):
self.id.append(e)
def connected(self,p,q):
return self.id[p]==self.id[q]
def union(self,p,q):
self.pid = self.id[p]
self.qid = self.id[q]
for i in range(len(self.id)):
if(self.id[i]==self.pid):
self.id[i]=self.qid
quf = QuickFindUF(9)
quf.union(3,4)
print quf.connected(3,4)
There are 16 self keywords in this class. Is there a better way to write this class?
Yea, you don't want to assign these variables to self, these are local variables:
def union(self,p,q):
self.pid = self.id[p]
self.qid = self.id[q]
for i in range(len(self.id)):
if(self.id[i]==self.pid):
self.id[i]=self.qid
Should be:
def union(self,p,q):
pid = self.id[p]
qid = self.id[q]
for i in range(len(self.id)):
if self.id[i] == pid:
self.id[i] = qid
You only use self when referring to instance variables, not to any variable inside of a method.
You could use some shortcuts:
class QuickFindUF:
"""docstring for QuickFindUF"""
def __init__(self, n):
self.id = range(n)
def connected(self,p,q):
_id = self.id
return _id[p]==_id[q]
def union(self,p,q):
_id = self.id
pid = _id[p]
qid = _id[q]
for (k, _i) in enumerate(_id):
if (_i == pid):
_id[k]=qid
Note the simplification in __init__, as pointed by #katrielalex, and the use of enumerate instead of looping on range(len(self.id)).
Using shortcuts can be a bit more efficient (as you save a call to __getattr__), but should not impair readability.
Make use of list(range()) and enumerate like so:
class QuickFindUF:
def __init__(self, n):
self.id = list(range(n))
def connected(self, i, j):
return self.id[i] == self.id[j]
def union(self, i, j):
x = self.id[i]
y = self.id[j]
for index, elem in enumerate(self.id):
if elem == x:
self.id[index] = y
But even better: Don't forget that Python is multi-paradigm. If methods have generic aspects, then outsource these to pure functions:
def map_each_x_to_y(array, x, y):
for i, elem in enumerate(array):
if elem == x:
array[i] = y
return array
def map_ith_values_to_jth(array, i, j):
x = array[i]
y = array[j]
return map_each_x_to_y(array, x, y)
This more declarative style might seem verbose, but it makes the desired behaviour of the union method's intent easier to understand:
def union(self, i, j):
self.id = map_ith_values_to_jth(self.id, i, j)
And makes your code more re-usable for other things.