Advertisement
Guest User

Untitled

a guest
Nov 17th, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.13 KB | None | 0 0
  1. package dijkstra
  2.  
  3. import kotlinx.atomicfu.atomic
  4. import java.lang.Math.abs
  5. import java.util.*
  6. import java.util.Collections.swap
  7. import java.util.concurrent.Phaser
  8. import java.util.concurrent.locks.ReentrantLock
  9. import kotlin.Comparator
  10. import kotlin.collections.ArrayList
  11. import kotlin.collections.RandomAccess
  12. import kotlin.concurrent.thread
  13.  
  14. private val NODE_DISTANCE_COMPARATOR = Comparator<Node> { o1, o2 -> Integer.compare(o1!!.distance, o2!!.distance) }
  15.  
  16. // Returns `Integer.MAX_VALUE` if a path has not been found.
  17.  
  18. class MyQueue(workers: Int, comparator: Comparator<Node> ){
  19.     val workers : Int
  20.     val queueSzie = atomic(0)
  21.     val sizeLock : ReentrantLock
  22.     val arr  = IntArray(workers)
  23.     val myList : List<Int>
  24.  
  25.     val qu : ArrayList<PriorityQueue<Node>> = ArrayList()
  26.     val loksStatus : ArrayList<ReentrantLock> = ArrayList()
  27.     init{
  28.         this.workers = workers
  29.         for(i in 0..workers -1){
  30.             arr[i] = i
  31.         }
  32.         myList = arr.toList()
  33.         sizeLock = ReentrantLock()
  34.         for (i in 1..this.workers) {
  35.             qu.add(PriorityQueue(1, comparator))
  36.             loksStatus.add(ReentrantLock())
  37.         }
  38.     }
  39.  
  40.     fun pop(): Node? {
  41.         var i = 0
  42.         var deletedSomethink : Boolean = false
  43.         var ans : Node = Node()
  44.         while (!isEmpty()){
  45.  
  46.             i = abs(Random().nextInt()) % workers
  47.             if (loksStatus[i].tryLock()) {
  48.                 try {
  49.                     if (qu[i].size > 0) {
  50.                         ans = qu[i].remove()
  51.                         deletedSomethink = true
  52.                         queueSzie.decrementAndGet()
  53.                     }
  54.                 } finally {
  55.                     loksStatus[i].unlock()
  56.                 }
  57.             }
  58.             if (deletedSomethink)
  59.                 return ans
  60.         }
  61.  
  62.         return null
  63.     }
  64.  
  65.     fun add(x : Node){
  66.         var i = 0
  67.         var flag = true
  68.         while (flag){
  69.             i = abs(Random().nextInt()) % workers
  70.             if (loksStatus[i].tryLock()) {
  71.                 try {
  72.                     queueSzie.incrementAndGet()
  73.                     qu[i].add(x)
  74.                     flag = false
  75.                 } finally {
  76.                     loksStatus[i].unlock()
  77.  
  78.                 }
  79.             }
  80.         }
  81.     }
  82.  
  83.     fun isEmpty() : Boolean {
  84.         var result : Boolean
  85.         result = true
  86.         if(queueSzie.value > 0) {
  87.             result = false
  88.         }
  89.         return result
  90.     }
  91. }
  92.  
  93. fun shortestPathParallel(start: Node) {
  94.     val workers = Runtime.getRuntime().availableProcessors()
  95.     //val workers = 1
  96.  
  97.  
  98.  
  99.     start.distance = 0
  100.     // Create a priority (by distance) queue and add the start node into it
  101.     //val q = PriorityQueue(workers, NODE_DISTANCE_COMPARATOR) // TODO replace me with a multi-queue based PQ!
  102.     val q = MyQueue(workers, NODE_DISTANCE_COMPARATOR)
  103.     q.add(start)
  104.     // Run worker threads and wait until the total work is done
  105.     val onFinish = Phaser(workers + 1) // `arrive()` should be invoked at the end by each worker
  106.     repeat(workers) {
  107.         thread {
  108.             while (!q.isEmpty()) {
  109.                 val cur: Node? = q.pop()
  110.                 if (cur == null) {
  111.                     continue
  112.                 }
  113.                 for (e in cur.outgoingEdges) {
  114.                     while (true) {
  115.                         val olde = e.to.distance
  116.                         val oldcur = cur.distance
  117.                         if(olde > oldcur + e.weight) {
  118.                             if (e.to.casDistance(olde, oldcur + e.weight)) {
  119.                                 q.add(e.to)
  120.                                 break
  121.                             }
  122.                             continue
  123.                         }
  124.                         break
  125.                     }
  126.                 }
  127.             }
  128.             // TODO Write the required algorithm here,
  129.             // TODO break from this loop when there is no more node to process.
  130.             // TODO Be careful, "empty queue" != "all nodes are processed".
  131.             onFinish.arrive()
  132.         }
  133.     }
  134.     onFinish.arriveAndAwaitAdvance()
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement