Skip to content
Snippets Groups Projects
Commit f666539d authored by Maxime MORGE's avatar Maxime MORGE
Browse files

Start implementing CBAA

parent 4b2f88c7
No related branches found
No related tags found
No related merge requests found
## What is SMASTA+ ? ## What is SCATA ?
SCATA is a Scala implementation of the Consensus-Based Algorithms for Task Allocation. SCATA is a Scala implementation of the Consensus-Based Algorithms for Task Allocation.
......
// Copyright (C) Maxime MORGE, 2024 // Copyright (C) Maxime MORGE, 2024
package org.scata.algorithm package org.scata.algorithm
import org.scata.core.{SingleAssignmentProblem, Task, Worker} import org.scata.core._
/** /**
* The Consensus-Based Auction Algorithm (CBAA) is * The Consensus-Based Auction Algorithm (CBAA) is
...@@ -9,28 +9,32 @@ import org.scata.core.{SingleAssignmentProblem, Task, Worker} ...@@ -9,28 +9,32 @@ import org.scata.core.{SingleAssignmentProblem, Task, Worker}
*/ */
class CBAA(pb : SingleAssignmentProblem) { class CBAA(pb : SingleAssignmentProblem) {
var neighbours : Map[Worker, List[Worker]] = fullyConnected() var neighbours : Map[Worker, List[Worker]] = Map[Worker, List[Worker]]()
/* pb.workers.foreach{ worker =>
neighbours = neighbours.updated(worker, pb.workers.toList)
}*/
var workerTaskList: Map[(Worker, Task), Boolean] = Map[(Worker, Task), Boolean]() private var workerTaskList: Map[Worker, Map[Task, Boolean]] = pb.workers.toList.map { worker =>
var winningBid : Map[(Worker, Task), Int] = Map[(Worker, Task), Int]() worker -> pb.tasks.toList.map { task =>
task -> false
}.toMap
}.toMap
pb.workers.foreach{ worker=> private var winningBid: Map[Worker, Map[Task, (Worker, Int)]] = pb.workers.toList.map { worker =>
pb.tasks.foreach{ task => worker -> pb.tasks.toList.map { task =>
workerTaskList = workerTaskList.updated((worker, task), false) task -> (NoWorker, 0)
winningBid = winningBid.updated((worker, task), 0) }.toMap
} }.toMap
}
/** /**
* Generate a fully connect communication network * Generate a fully connect communication network
*/ */
private def fullyConnected() : Map[Worker, List[Worker]] = { //private def fullyConnected : Map[Worker, List[Worker]] =
var neighbour = Map[Worker, List[Worker]]()
pb.workers.foreach{ worker => /**
neighbour = neighbour.updated(worker, pb.workers.toList) * Returns true if the worker has no task assigned
} */
neighbour private def isFree(worker : Worker) : Boolean = !pb.tasks.exists(task => workerTaskList(worker)(task))
}
/** /**
* Checks if two workers are neighbors * Checks if two workers are neighbors
...@@ -38,8 +42,7 @@ class CBAA(pb : SingleAssignmentProblem) { ...@@ -38,8 +42,7 @@ class CBAA(pb : SingleAssignmentProblem) {
* @param worker2 the second worker * @param worker2 the second worker
* @return true if they are neighbors, false otherwise * @return true if they are neighbors, false otherwise
*/ */
def isNeighbor(worker1: Worker, worker2: Worker): Boolean = neighbours(worker1).contains(worker2) private def isNeighbor(worker1: Worker, worker2: Worker): Boolean = neighbours(worker1).contains(worker2)
/** /**
* CBAA Phase 1 for worker i * CBAA Phase 1 for worker i
...@@ -49,12 +52,12 @@ class CBAA(pb : SingleAssignmentProblem) { ...@@ -49,12 +52,12 @@ class CBAA(pb : SingleAssignmentProblem) {
def selectTask(i : Int) : Unit = { def selectTask(i : Int) : Unit = {
val worker = pb.workers.toIndexedSeq(i) val worker = pb.workers.toIndexedSeq(i)
// Check if the worker has no tasks assigned // Check if the worker has no tasks assigned
if (!pb.tasks.exists(task => workerTaskList((worker, task)))) { if (isFree(worker)) {
// Determine valid tasks based on cost comparison // Determine valid tasks based on cost comparison
var validTasks: Map[Task, Boolean] = Map[Task, Boolean]() var validTasks: Map[Task, Boolean] = Map[Task, Boolean]()
pb.tasks.foreach { task => pb.tasks.foreach { task =>
if (pb.cost(worker, task) <= winningBid(worker, task)) { if (pb.cost(worker, task) < winningBid(worker)(task)._2) {
validTasks = validTasks.updated(task, true) validTasks = validTasks.updated(task, true)
} else { } else {
validTasks = validTasks.updated(task, false) validTasks = validTasks.updated(task, false)
...@@ -63,8 +66,8 @@ class CBAA(pb : SingleAssignmentProblem) { ...@@ -63,8 +66,8 @@ class CBAA(pb : SingleAssignmentProblem) {
// If there are valid tasks, select the one with the minimum cost // If there are valid tasks, select the one with the minimum cost
if (pb.tasks.exists(task => validTasks(task))) { if (pb.tasks.exists(task => validTasks(task))) {
val bestTask = validTasks.filter(_._2).keys.minBy(task => pb.cost(worker, task)) val bestTask = validTasks.filter(_._2).keys.minBy(task => pb.cost(worker, task))
workerTaskList = workerTaskList.updated((worker, bestTask), true) workerTaskList(worker) = workerTaskList(worker).updated(bestTask, true)
winningBid = winningBid.updated((worker, bestTask), pb.cost(worker, bestTask)) winningBid(worker) = winningBid(worker).updated(bestTask, (worker, pb.cost(worker, bestTask)))
} }
} }
} }
......
...@@ -5,7 +5,7 @@ package org.scata.core ...@@ -5,7 +5,7 @@ package org.scata.core
* Class representing a worker * Class representing a worker
* @param name of the worker * @param name of the worker
*/ */
final class Worker(val name : String) extends Ordered[Worker]{ class Worker(val name : String) extends Ordered[Worker]{
override def toString: String = name override def toString: String = name
...@@ -27,3 +27,9 @@ final class Worker(val name : String) extends Ordered[Worker]{ ...@@ -27,3 +27,9 @@ final class Worker(val name : String) extends Ordered[Worker]{
} }
} }
/**
* The default worker
*/
object NoWorker extends Worker("NoWorker"){
override def toString: String = "NoWorker"
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment