All Downloads are FREE. Search and download functionalities are using the official Maven repository.

protelis.coord.sparsechoice.pt Maven / Gradle / Ivy

There is a newer version: 17.6.0
Show newest version
module protelis:coord:sparsechoice
import protelis:coord:spreading
import java.lang.Double.POSITIVE_INFINITY

def default() {
    [POSITIVE_INFINITY, POSITIVE_INFINITY]
}

def breakUsingUids(uid, grain, metric) {
    share (lead, nbrLead <- uid) {
        distanceCompetition(distanceToWithMetric(uid == lead, metric), nbrLead, uid, grain, metric)
    } == uid
}

def distanceCompetition(d, nbrLead, uid, grain, metric) {
    mux (d > grain) {
        uid
    } else {
        let thr = 0.5 * grain;
        mux (d >= thr) {
            default()
        } else {
            foldMin(
                mux (nbr(d) + metric() >= thr) {
                    default()
                } else {
                    nbrLead
                }
            )
        }
    }
}

def randomUid() {
    rep (v <- [self.nextRandomDouble(), self.getDeviceUID()]) {
        v
    }
}

/**
 * Devices compete against one another to become local leaders,
 * resulting  in  a  random  Voronoi  partition  with  a  characteristic
 * grain size.
 *
 * @param grain  num, partition dimension
 * @param metric () -> num, estimate distance from the leader
 * @return       bool, true if the current device is the leader, false otherwise
 */
public def S(grain, metric) {
    breakUsingUids(randomUid(), grain, metric)
}

/**
 * Multi-leader election based on a symmetry breaking value, presented at ACSOS 2022.
 * Implemented from Self-stabilising Priority-Based Multi-Leader Election and Network Partitioning.
 * Find more at https://ieeexplore.ieee.org/document/9935012
 *
 * @param localId  num, local identifier
 * @param radius  num, extension of the local candidacy
 * @param strength  num, power of the local device candidacy
 * @param metric () -> num, estimated distance from neighbors
 * @return       bool, true if the current device is the leader, false otherwise
 */
public def boundedElection(localId, radius, strength, metric) {
	let local = Candidacy(-strength, 0, localId)
	let worstCandidacy = Candidacy(POSITIVE_INFINITY, POSITIVE_INFINITY, POSITIVE_INFINITY)
	candidacyLeaderId(
		share (received <- local) {
			let candidacies = received.set(1, candidacyDistance(received) + metric())
			let shouldBeDiscarded = candidacyLeaderId(candidacies) == localId // myself
			    || candidacyDistance(candidacies) >= radius // too far away
			let filtered = mux (shouldBeDiscarded) { worstCandidacy } else { candidacies }
			min(local, foldMin(worstCandidacy, filtered))
		}
	)
}
/*
  * Support functions for boundedElection
  */
def Candidacy(symmetryBreaker, distance, leaderId) = [symmetryBreaker, distance, leaderId]
def candidacyDistance(candidacy) = candidacy.get(1)
def candidacyLeaderId(candidacy) = candidacy.get(2)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy