diff --git a/README.md b/README.md index 53f0fb2f7f729ba26d221ac5c85719bd32c06767..41e842c4d4c53d0e2f81a70a5d924b22960916e2 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## What is SMASTA+ ? +## What is SCATA ? SCATA is a Scala implementation of the Consensus-Based Algorithms for Task Allocation. diff --git a/src/main/scala/org/scata/algorithm/CBAA.scala b/src/main/scala/org/scata/algorithm/CBAA.scala index ad01422a30d8b53729cd2246aeff0d04213d687b..b11eb46b3343015c380c8d3918e62164a2f06023 100644 --- a/src/main/scala/org/scata/algorithm/CBAA.scala +++ b/src/main/scala/org/scata/algorithm/CBAA.scala @@ -1,7 +1,7 @@ // Copyright (C) Maxime MORGE, 2024 package org.scata.algorithm -import org.scata.core.{SingleAssignmentProblem, Task, Worker} +import org.scata.core._ /** * The Consensus-Based Auction Algorithm (CBAA) is @@ -9,28 +9,32 @@ import org.scata.core.{SingleAssignmentProblem, Task, Worker} */ 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]() - var winningBid : Map[(Worker, Task), Int] = Map[(Worker, Task), Int]() + private var workerTaskList: Map[Worker, Map[Task, Boolean]] = pb.workers.toList.map { worker => + worker -> pb.tasks.toList.map { task => + task -> false + }.toMap + }.toMap - pb.workers.foreach{ worker=> - pb.tasks.foreach{ task => - workerTaskList = workerTaskList.updated((worker, task), false) - winningBid = winningBid.updated((worker, task), 0) - } - } + private var winningBid: Map[Worker, Map[Task, (Worker, Int)]] = pb.workers.toList.map { worker => + worker -> pb.tasks.toList.map { task => + task -> (NoWorker, 0) + }.toMap + }.toMap /** * Generate a fully connect communication network */ - private def fullyConnected() : Map[Worker, List[Worker]] = { - var neighbour = Map[Worker, List[Worker]]() - pb.workers.foreach{ worker => - neighbour = neighbour.updated(worker, pb.workers.toList) - } - neighbour - } + //private def fullyConnected : Map[Worker, List[Worker]] = + + /** + * Returns true if the worker has no task assigned + */ + private def isFree(worker : Worker) : Boolean = !pb.tasks.exists(task => workerTaskList(worker)(task)) /** * Checks if two workers are neighbors @@ -38,8 +42,7 @@ class CBAA(pb : SingleAssignmentProblem) { * @param worker2 the second worker * @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 @@ -49,12 +52,12 @@ class CBAA(pb : SingleAssignmentProblem) { def selectTask(i : Int) : Unit = { val worker = pb.workers.toIndexedSeq(i) // 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 var validTasks: Map[Task, Boolean] = Map[Task, Boolean]() 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) } else { validTasks = validTasks.updated(task, false) @@ -63,8 +66,8 @@ class CBAA(pb : SingleAssignmentProblem) { // If there are valid tasks, select the one with the minimum cost if (pb.tasks.exists(task => validTasks(task))) { val bestTask = validTasks.filter(_._2).keys.minBy(task => pb.cost(worker, task)) - workerTaskList = workerTaskList.updated((worker, bestTask), true) - winningBid = winningBid.updated((worker, bestTask), pb.cost(worker, bestTask)) + workerTaskList(worker) = workerTaskList(worker).updated(bestTask, true) + winningBid(worker) = winningBid(worker).updated(bestTask, (worker, pb.cost(worker, bestTask))) } } } diff --git a/src/main/scala/org/scata/core/Worker.scala b/src/main/scala/org/scata/core/Worker.scala index d05a470a9f372f46ef7a6ecd6f4213f36c3d31d3..5f73ebbb38f76c5f6513ed1bb08579183d7fff06 100644 --- a/src/main/scala/org/scata/core/Worker.scala +++ b/src/main/scala/org/scata/core/Worker.scala @@ -5,7 +5,7 @@ package org.scata.core * Class representing a 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 @@ -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" +}