From f666539d28a1208c9b82134e4d5f915b2e2c2846 Mon Sep 17 00:00:00 2001 From: Maxime MORGE <maxime.morge@univ-lille.fr> Date: Thu, 24 Oct 2024 16:24:00 +0200 Subject: [PATCH] Start implementing CBAA --- README.md | 2 +- src/main/scala/org/scata/algorithm/CBAA.scala | 49 ++++++++++--------- src/main/scala/org/scata/core/Worker.scala | 8 ++- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 53f0fb2..41e842c 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 ad01422..b11eb46 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 d05a470..5f73ebb 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" +} -- GitLab