Skip to content

Commit 6e894ba

Browse files
CharlesRitterpoyea
authored andcommitted
Odd-Even Transposition Sort (TheAlgorithms#769)
* -Added a single-threaded implementation of odd-even transposition sort. This is a modified bubble sort meant to work with multiple processors. Since this is running on a single thread, it has the same running time as bubble sort. * -Added a parallel implementation of Odd-Even Transposition sort This implementation uses multiprocessing to perform the swaps at each step of the algorithm simultaneously.
1 parent ebe227c commit 6e894ba

2 files changed

+159
-0
lines changed
+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
"""
2+
This is an implementation of odd-even transposition sort.
3+
4+
It works by performing a series of parallel swaps between odd and even pairs of
5+
variables in the list.
6+
7+
This implementation represents each variable in the list with a process and
8+
each process communicates with its neighboring processes in the list to perform
9+
comparisons.
10+
They are synchronized with locks and message passing but other forms of
11+
synchronization could be used.
12+
"""
13+
from multiprocessing import Process, Pipe, Lock
14+
15+
#lock used to ensure that two processes do not access a pipe at the same time
16+
processLock = Lock()
17+
18+
"""
19+
The function run by the processes that sorts the list
20+
21+
position = the position in the list the prcoess represents, used to know which
22+
neighbor we pass our value to
23+
value = the initial value at list[position]
24+
LSend, RSend = the pipes we use to send to our left and right neighbors
25+
LRcv, RRcv = the pipes we use to receive from our left and right neighbors
26+
resultPipe = the pipe used to send results back to main
27+
"""
28+
def oeProcess(position, value, LSend, RSend, LRcv, RRcv, resultPipe):
29+
global processLock
30+
31+
#we perform n swaps since after n swaps we know we are sorted
32+
#we *could* stop early if we are sorted already, but it takes as long to
33+
#find out we are sorted as it does to sort the list with this algorithm
34+
for i in range(0, 10):
35+
36+
if( (i + position) % 2 == 0 and RSend != None):
37+
#send your value to your right neighbor
38+
processLock.acquire()
39+
RSend[1].send(value)
40+
processLock.release()
41+
42+
#receive your right neighbor's value
43+
processLock.acquire()
44+
temp = RRcv[0].recv()
45+
processLock.release()
46+
47+
#take the lower value since you are on the left
48+
value = min(value, temp)
49+
elif( (i + position) % 2 != 0 and LSend != None):
50+
#send your value to your left neighbor
51+
processLock.acquire()
52+
LSend[1].send(value)
53+
processLock.release()
54+
55+
#receive your left neighbor's value
56+
processLock.acquire()
57+
temp = LRcv[0].recv()
58+
processLock.release()
59+
60+
#take the higher value since you are on the right
61+
value = max(value, temp)
62+
#after all swaps are performed, send the values back to main
63+
resultPipe[1].send(value)
64+
65+
"""
66+
the function which creates the processes that perform the parallel swaps
67+
68+
arr = the list to be sorted
69+
"""
70+
def OddEvenTransposition(arr):
71+
72+
processArray = []
73+
tempRrcv = None
74+
tempLrcv = None
75+
76+
resultPipe = []
77+
78+
#initialize the list of pipes where the values will be retrieved
79+
for a in arr:
80+
resultPipe.append(Pipe())
81+
82+
#creates the processes
83+
#the first and last process only have one neighbor so they are made outside
84+
#of the loop
85+
tempRs = Pipe()
86+
tempRr = Pipe()
87+
processArray.append(Process(target = oeProcess, args = (0, arr[0], None, tempRs, None, tempRr, resultPipe[0])))
88+
tempLr = tempRs
89+
tempLs = tempRr
90+
91+
for i in range(1, len(arr) - 1):
92+
tempRs = Pipe()
93+
tempRr = Pipe()
94+
processArray.append(Process(target = oeProcess, args = (i, arr[i], tempLs, tempRs, tempLr, tempRr, resultPipe[i])))
95+
tempLr = tempRs
96+
tempLs = tempRr
97+
98+
processArray.append(Process(target = oeProcess, args = (len(arr) - 1, arr[len(arr) - 1], tempLs, None, tempLr, None, resultPipe[len(arr) - 1])))
99+
100+
#start the processes
101+
for p in processArray:
102+
p.start()
103+
104+
#wait for the processes to end and write their values to the list
105+
for p in range(0, len(resultPipe)):
106+
arr[p] = resultPipe[p][0].recv()
107+
processArray[p].join()
108+
109+
return(arr)
110+
111+
112+
#creates a reverse sorted list and sorts it
113+
def main():
114+
arr = []
115+
116+
for i in range(10, 0, -1):
117+
arr.append(i)
118+
print("Initial List")
119+
print(*arr)
120+
121+
list = OddEvenTransposition(arr)
122+
123+
print("Sorted List\n")
124+
print(*arr)
125+
126+
if __name__ == "__main__":
127+
main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
This is a non-parallelized implementation of odd-even transpostiion sort.
3+
4+
Normally the swaps in each set happen simultaneously, without that the algorithm
5+
is no better than bubble sort.
6+
"""
7+
8+
def OddEvenTransposition(arr):
9+
for i in range(0, len(arr)):
10+
for i in range(i % 2, len(arr) - 1, 2):
11+
if arr[i + 1] < arr[i]:
12+
arr[i], arr[i + 1] = arr[i + 1], arr[i]
13+
print(*arr)
14+
15+
return arr
16+
17+
#creates a list and sorts it
18+
def main():
19+
list = []
20+
21+
for i in range(10, 0, -1):
22+
list.append(i)
23+
print("Initial List")
24+
print(*list)
25+
26+
list = OddEvenTransposition(list)
27+
28+
print("Sorted List\n")
29+
print(*list)
30+
31+
if __name__ == "__main__":
32+
main()

0 commit comments

Comments
 (0)