Based on idea @Hugo's answer about using random weight:
$array = array(
array('id' => 101, 'bid' => 0.5, 'priority' => 5),
array('id' => 102, 'bid' => 0.4, 'priority' => 4),
array('id' => 103, 'bid' => 0.4, 'priority' => 4),
array('id' => 104, 'bid' => 0.4, 'priority' => 4),
array('id' => 105, 'bid' => 0.3, 'priority' => 5),
array('id' => 106, 'bid' => 0.3, 'priority' => 5),
array('id' => 107, 'bid' => 0.2, 'priority' => 5),
array('id' => 108, 'bid' => 0.7, 'priority' => 5),
array('id' => 108, 'bid' => 0.1, 'priority' => 4)
);
function cmp(&$a, &$b) { # notice the use of & in function signature
if ($a['bid'] - $b['bid']) {
return $a['bid'] - $b['bid'] > 0 ? 1 : -1; # bid is different, sort using bid
} else if ($a['priority'] - $b['priority']) {
return $a['priority'] - $b['priority'] > 0 ? 1 : -1; # priority is different, sort using priority
} else {
if (isset($a['rw']) == false) {
$a['rw'] = rand(1, 100); # assign random tie breaker
}
if (isset($b['rw']) == false) {
$b['rw'] = rand(1, 100); # assign random tie breaker
}
if ($a['rw'] - $b['rw']) {
return $a['rw'] - $b['rw'] > 0 ? 1 : -1; # sort using random weight
} else {
return 0;
}
}
}
usort($array, 'cmp');
var_dump($array);
Output
array(9) {
[0]=>array(3) {["id"]=>int(108) ["bid"]=>float(0.1) ["priority"]=>int(4)}
[1]=>array(3) {["id"]=>int(107) ["bid"]=>float(0.2) ["priority"]=>int(5)}
[2]=>array(4) {["id"]=>int(106) ["bid"]=>float(0.3) ["priority"]=>int(5) ["rw"]=>int(70)}
[3]=>array(4) {["id"]=>int(105) ["bid"]=>float(0.3) ["priority"]=>int(5) ["rw"]=>int(73)}
[4]=>array(4) {["id"]=>int(103) ["bid"]=>float(0.4) ["priority"]=>int(4) ["rw"]=>int(29)}
[5]=>array(4) {["id"]=>int(104) ["bid"]=>float(0.4) ["priority"]=>int(4) ["rw"]=>int(67)}
[6]=>array(4) {["id"]=>int(102) ["bid"]=>float(0.4) ["priority"]=>int(4) ["rw"]=>int(80)}
[7]=>array(3) {["id"]=>int(101) ["bid"]=>float(0.5) ["priority"]=>int(5)}
[8]=>array(3) {["id"]=>int(108) ["bid"]=>float(0.7) ["priority"]=>int(5)}
}