Skip to content

Commit

Permalink
alter distibution algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
irinahpe committed May 23, 2024
1 parent 9768092 commit 43dcf7b
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 24 deletions.
11 changes: 11 additions & 0 deletions classes/task/cron_task.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,25 @@ public function execute() {
return true;
}

// For testing purpsoses

// Clear eventually scheduled distribution of unallocated users.
$ratingallocate->clear_distribute_unallocated_tasks();
// Run allocation.
$ratingallocate->distrubute_choices();


// To do wieder alte funktion...
// Only start the algorithm, if it should be run by the cron and hasn't been started somehow, yet.
/*
if ($ratingallocate->ratingallocate->runalgorithmbycron === "1" &&
$ratingallocate->get_algorithm_status() === \mod_ratingallocate\algorithm_status::NOTSTARTED) {
// Clear eventually scheduled distribution of unallocated users.
$ratingallocate->clear_distribute_unallocated_tasks();
// Run allocation.
$ratingallocate->distrubute_choices();
}
*/
}
return true;
}
Expand Down
27 changes: 27 additions & 0 deletions locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,33 @@ public function get_ratings_for_rateable_choices() {
return $fromraters;
}

/**
* Returns all ratings for active choices but takes teamvote into consideration
*/
public function get_ratings_for_rateable_choices_with_teamvote() {
$sql = 'SELECT ra.*
FROM {ratingallocate_choices} c
JOIN ( SELECT min(r.id) as id, r.choiceid, r.rating, r.groupid
FROM {ratingallocate_ratings} r
GROUP BY r.choiceid, r.rating, r.groupid ) ra
ON c.id = ra.choiceid
WHERE c.ratingallocateid = :ratingallocateid AND c.active = 1';

$ratings = $this->db->get_records_sql($sql, array(
'ratingallocateid' => $this->ratingallocateid
));
/*
$raters = $this->get_raters_in_course();
// Filter out everyone who can't give ratings.
$fromraters = array_filter($ratings, function($rating) use ($raters) {
return array_key_exists($rating->userid, $raters);
});
*/

return $ratings;
}

/**
* Returns the groups in the teamvote grouping with the amount of groupmembers
*
Expand Down
107 changes: 86 additions & 21 deletions solver/edmonds-karp.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function compute_distribution($choicerecords, $ratings, $usercount, $team
// with Bellman-Ford as search function (see: Edmonds-Karp in Introduction to Algorithms)
// http://stackoverflow.com/questions/6681075/while-loop-in-php-with-assignment-operator
// Look for an augmenting path (a shortest path from the source to the sink).
while ($path = $this->find_shortest_path_bellf_cspf($source, $sink, $teamvote, $toteamid)) { // If the function returns null, the while will stop.
while ($path = $this->find_shortest_path_bellf_cspf2($source, $sink, $teamvote, $toteamid)) { // If the function returns null, the while will stop.
// Reverse the augmentin path, thereby distributing a user into a group.
$this->augment_flow($path);
unset($path); // Clear up old path.
Expand All @@ -93,7 +93,56 @@ public function compute_distribution($choicerecords, $ratings, $usercount, $team

/**
* Find the shortest path with constraint (enough space for all teammembers in choice).
* This is a modified version of the Yen Algorithm for the consstrained shortest path first problem.
* This is a modified version of the Yen Algorithm for the constrained shortest path first problem.
*
* @param $from
* @param $to
* @param $teamvote
* @param $toteamid
* @return array|mixed|null array of the nodes in the path, null if no path found.
*/
private function find_shortest_path_bellf_cspf2 ($from, $to, $teamvote, $toteamid) {

// Stop if no shortest path is found.
$i=1;
while ($pathcandidate = $this->find_shortest_path_bellf($from, $to)) {
// var_dump($this->graph);
var_dump($i);
var_dump($pathcandidate);
$foundedge = null;

foreach ($this->graph[$pathcandidate[1]] as $index => $edge) {
if ($edge->to == $pathcandidate[0]) {
$foundedge = $edge;
$foundedgeid = $index;
break;
}
}
if ($foundedge->space > $teamvote[$toteamid[$pathcandidate[2]]]) {
// We just found the shortest path fulfilling the constraint.
return $pathcandidate;
} else {
// Remove the edge since this path is impossible.
array_splice($this->graph[1], $foundedgeid, 1);
// Add a new edge in the opposite direction whose weight has an opposite sign
// array_push($this->graph[$to], new edge($to, $from, -1 * $edge->weight));
// according to php doc, this is faster.
// $this->graph[2][] = new edge(2, 1, -1 * $edge->weight);
}
unset($pathcandidate);
$i++;
}
var_dump("nix gefunden");
return null;

}




/**
* Find the shortest path with constraint (enough space for all teammembers in choice).
* This is a modified version of the Yen Algorithm for the constrained shortest path first problem.
*
* @param $from
* @param $to
Expand All @@ -103,30 +152,38 @@ public function compute_distribution($choicerecords, $ratings, $usercount, $team
*/
private function find_shortest_path_bellf_cspf ($from, $to, $teamvote, $toteamid) {

var_dump("find shortest path cspf");
var_dump($this->graph);
// Find the first shortest path.
$pathcandidates = array();
$pathcandidates[0] = $this->find_shortest_path_bellf($from, $to);

$nopathfound = is_null($pathcandidates[0]);

// Check if the path fulfills our constraint: space in choice left >= teammembers.
$constraintflag = true;
$foundedge = null;
foreach ($this->graph[$pathcandidates[0][1]] as $edge) {
if ($edge->to == $pathcandidates[0][0]) {
$foundedge = $edge;
break;

// If the path exists, check if the path fulfills our constraint: space in choice left >= teammembers.
if (!$nopathfound) {
$constraintflag = true;
$foundedge = null;

$pclenth = count($pathcandidates[0]);
foreach ($this->graph[$pathcandidates[0][1]] as $edge) {
if ($edge->to == $pathcandidates[0][0]) {
$foundedge = $edge;
break;
}
}
if ($foundedge->space <= $teamvote[$toteamid[$pathcandidates[0][2]]]) {
$constraintflag = false;
}

if ($constraintflag) {
// We just found the shortest path fulfilling the constraint.
return $pathcandidates[0];
}
}
if ($foundedge->space <= $teamvote[$toteamid[$pathcandidates[0][2]]]) {
$constraintflag = false;
$constraintflag = true;
}

if ($constraintflag) {
// We just found the shortest path fulfilling the constraint.
return $pathcandidates[0];
}
$constraintflag = true;

// Array of the potential next shortest paths.
$nextpaths = array();
Expand Down Expand Up @@ -177,6 +234,11 @@ private function find_shortest_path_bellf_cspf ($from, $to, $teamvote, $toteamid

// Calculate the spur path from the spur node to the sink.
$spurpath = $this->find_shortest_path_bellf($i, $to);
if (is_null($spurpath)) {
var_dump("No spurpath");
$nopathfound = true;
break;
}

// Entire path is made up of the root path and spur path.
$totalpath = array_merge($rootpath, $spurpath);
Expand Down Expand Up @@ -210,13 +272,14 @@ private function find_shortest_path_bellf_cspf ($from, $to, $teamvote, $toteamid
var_dump($nextpaths);

// Check if the next best path fullfillst our constraint.
foreach ($this->graph[$nextpaths[0][1]] as $edge) {
if ($edge->to == $nextpaths[0][0]) {
$pclenth = count($pathcandidates[0]);
foreach ($this->graph[$pathcandidates[0][1]] as $edge) {
if ($edge->to == $pathcandidates[0][0]) {
$foundedge = $edge;
break;
}
}
if ($foundedge->space <= $teamvote[$toteamid[$nextpaths[0][2]]]) {
if ($foundedge->space <= $teamvote[$toteamid[$pathcandidates[0][2]]]) {
$constraintflag = false;
}

Expand All @@ -225,6 +288,7 @@ private function find_shortest_path_bellf_cspf ($from, $to, $teamvote, $toteamid
return $nextpaths[0];
}

// Not sure if saving all the paths is even necessary...
$pathcandidates[$k] = $nextpaths[0];

// Reset flag condition.
Expand All @@ -234,6 +298,7 @@ private function find_shortest_path_bellf_cspf ($from, $to, $teamvote, $toteamid
}
$k++;
}
var_dump("Path not found");
return null;
}

Expand All @@ -247,7 +312,7 @@ private function get_cost_of_path ($path) {

$cost = 0;

for ($i = count($path) - 1; $i > 0; $i--) {
for ($i = count($path)-1; $i > 0; $i--) {
$from = $path[$i];
$to = $path[$i - 1];
$edge = null;
Expand Down
10 changes: 7 additions & 3 deletions solver/solver-template.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,11 @@ public function distribute_users(\ratingallocate $ratingallocate) {

// Load data from database.
$choicerecords = $ratingallocate->get_rateable_choices();
$ratings = $ratingallocate->get_ratings_for_rateable_choices();
if ($teamvote) {
$ratings = $ratingallocate->get_ratings_for_rateable_choices_with_teamvote();
} else {
$ratings = $ratingallocate->get_ratings_for_rateable_choices();
}

// Randomize the order of the entries to prevent advantages for early entry.
shuffle($ratings);
Expand All @@ -116,9 +120,9 @@ public function distribute_users(\ratingallocate $ratingallocate) {
$userids = array();
foreach ($distributions as $choiceid => $teamids) {
foreach ($teamids as $teamid) {
$userids[$teamid] = groups_get_members($teamid, 'u.id');
array_merge($userids, groups_get_members($teamid, 'u.id'));
}
$userdistributions[$choiceid] = array_merge($userids);
$userdistributions[$choiceid] = $userids;
}

// We have to delete the provisionally groups containing only one user.
Expand Down

0 comments on commit 43dcf7b

Please sign in to comment.