PHP - Round Robin and 3rd person (2 players and one writer / refugee) - php

I have the following code
poule = ['Jason', 'Raymond', 'Rupert', 'Mike', 'Simon', 'Jeremy'];
$games = [];
$cnt_players = count($poule);
$players = $poule;
if ($cnt_players % 2 != 0)
{
array_push($players, ['name' => 'bye', 'uid' => FALSE, 'alias' => NumToChar($cnt_players + 1), TRUE]);
$cnt_players++;
}
$away = array_splice($players, $cnt_players / 2);
$home = $players;
$write = [];
for ($i = 0; $i < count($home) + count($away) - 1; $i++)
{
for ($j = 0; $j < count($home); $j++)
{
//Get the writer
$writer = $this->GetWriter($home, $away, $j, $i);
//Remove the dummy games (where one player is bye)
if ($home[$j]['name'] !== 'bye' && $away[$j]['name'] !== 'bye')
{
$games[] = [['uid' => $home[$j]['uid'], 'name' => $home[$j]['name'], 'alias' => $home[$j]['alias']], ['uid' => $away[$j]['uid'], 'name' => $away[$j]['name'], 'alias' => $away[$j]['alias']], $writer];
}
//echo 'I:' . $i . ' - J: ' . $j . ' - ' . $home[$j]['alias'] . ' : ' . $home[$j]['name'] . ' - ' . $away[$j]['alias'] . ' : ' . $away[$j]['name'] . ' ==> ' . $writer['alias'] . ' : ' . $writer['name'] . "\n\r";
$write[$writer['name']][] = $writer['name'];
}
if (count($home) + count($away) - 1 > 2)
{
array_unshift($away, current(array_splice($home, 1, 1)));
array_push($home, array_pop($away));
}
}
//print_r($write);
return $games;
--
The function GetWriter should give us the player who will note the scores for that particulair game.
private function GetWriter($home, $away, $j, $i)
{
if ($j > 0)
{
if ($j == 1)
{
$writer = (isset($home[$j + 1]['alias']) ? $home[$j + 1] : $home[$j + 1]);
}
else
{
$writer = (isset($home[$j - 1]['alias']) ? $home[$j - 1] : $home[$j + 1]);
}
//Check if writer is a bye, this is not possible
if ($writer['name'] == 'bye')
{
$writer = (isset($away[$j - 2]['alias']) ? $away[$j - 2] : $home[$j - 1]);
}
}
else
{
$writer = (isset($home[$j + 1]['alias']) ? $home[$j + 1] : $away[$j]);
if ($writer['name'] == 'bye')
{
$writer = (isset($away[$j + 1]['alias']) ? $away[$j + 1] : $home[$j]);
}
}
return $writer;
}
Above code gives me all games with each player playing once to another player (round robin). However I need to find a third player who will be the writer / refugee. Like in Darts, 1 player is the person who writes the scores on the scoreboard. I do get a writer, but it isn't nicely divided per player.
Is there an formula to get the correct player who is writer / refugee ?
Some examples
Jason vs Mike Raymond
Raymond vs Simon Rupert
Rupert vs Jeremy Mike
etc
So Jason plays against Mike and Raymond notes the scores.
Raymond plays against Simon and Rupert notes the scores etc etc
My GetWriter returns writes, but not well divided.
Eg: Player Jason writes never and Raymond writes the most scores.

I have the following solution which works well.
Because player A and player B always start, we set the key as default index 3.
Now we loop with GetCounter though all players and get the writer / refugee which is first available.
$games = [];
$cnt_players = count($poule);
$players = $poule;
$key = 3;
if ($cnt_players % 2 != 0)
{
array_push($players, ['name' => 'bye', 'uid' => FALSE, 'alias' => NumToChar($cnt_players + 1, TRUE), TRUE]);
$cnt_players++;
}
$away = array_splice($players, $cnt_players / 2);
$home = $players;
for ($i = 0; $i < count($home) + count($away) - 1; $i++)
{
for ($j = 0; $j < count($home); $j++)
{
//Remove the dummy games (where one player is bye)
if ($home[$j]['name'] != 'bye' && $away[$j]['name'] != 'bye')
{
//Get the writer
$writer = $this->GetCounter($home, $away, $j, $poule, $key);
$games[] = [['uid' => $home[$j]['uid'], 'name' => $home[$j]['name'], 'alias' => $home[$j]['alias']], ['uid' => $away[$j]['uid'], 'name' => $away[$j]['name'], 'alias' => $away[$j]['alias']], $writer['array']];
$key = $writer['key'];
}
$key++;
}
if (count($home) + count($away) - 1 > 2)
{
array_unshift($away, current(array_splice($home, 1, 1)));
array_push($home, array_pop($away));
}
}
return $games;
And the GetCounter
private function GetCounter($home, $away, $j, $writers, $key)
{
if (isset($writers[$key]['alias']))
{
$writer['array'] = $writers[$key];
$writer['key'] = $key;
if ($home[$j]['alias'] == $writer['array']['alias'] || $away[$j]['alias'] == $writer['array']['alias'])
{
$key++;
return $this->GetCounter($home, $away, $j, $writers, $key);
}
}
else {
$key = 0;
return $this->GetCounter($home, $away, $j, $writers, $key);
}
return $writer;
}

Related

find polygons/lines/points in array of latitude/longitude points using php/javascript

I have an online app I am developing to search for historical wheat collection sites matched to climate http://www.wheat-gateway.org.uk/climate_search_1.php?ord=4&cns=108,114&ctrl_r=1//522/891&ctrl=1
I have the collection sites (some 173,000 and the data of the wheats collected from them) and their climate records and I have a climate record for a set of longitude/latitude points at 15 minute intervals for all land.
As you can see currently I am displaying points from the climate data set as heatmap in Google Maps but I want to convert these into lines, points and polygons as geoJSON file for display in Google maps viz https://developers.google.com/maps/documentation/javascript/datalayer partly for speed (I hope) and partly because for this purpose heatmaps distort when zoomed out and don't work visually zoomed right down either.
I have found https://assemblysys.com/php-point-in-polygon-algorithm/ which looks good to strip out points in search results array once I have found polygons - but first of all how to find them (and lines and points)? Any suggestions?
yours
Andy Forbes
so basically I cycle though the array of points that can be used as heatmap in Google maps from W>E and N>S and each new one found check if lone point or has neighbours. If has neighbours then trace around to see if part of polygon or line. When vertices back to start point are found run a check on remainder of points to see if they are inside the vertices, remove any found and the vertices' points and put vertices points and lone points into arrays that will output geoJSON file. Move to next point left in points until none left.
The costly part in terms of time is checking if points are inside a polygon. I found https://assemblysys.com/php-point-in-polygon-algorithm/ to be most accurate non-library set of functions to do this - most vertices found. I tried a variety of others including https://geophp.net/ which I found over twice as slow as "php-point-in-polygon-algorithm" funciton though I can't install GEOS on my server as recommended. However I found library phpgeos https://github.com/mjaschen/phpgeo did a much quicker job.
So here is result with both heatmap and points(as diamonds),lines and polygons - you can see on this area heatmap is much quicker.
http://www.wheat-gateway.org.uk/climate_search_both.php?ord=4&cns=110,113,116,124,131,135,150,153,157,161&ctrl_r=1//66/535,2//-5/31&ctrl=1,2
but on a smaller area the extra time is acceptable http://www.wheat-gateway.org.uk/climate_search_both.php?ord=4&cns=108,114&ctrl_r=1//291/1135,2//-5/12&ctrl=1,2
so my solution is to find out how many points in set and go with heatmap over 3000 points. I have managed to tune radius of points in heatmap depending on zoom level so the presentation doesn't give typical distortion when zoomed out eg http://www.wheat-gateway.org.uk/climate_search.php?ord=4&cns=all&ctrl_r=1//1061/1361,2//23.043/27.043&ctrl=1,2&targ=107723
Probably the most tricky bit is finding if there are holes in any polygon found, see the "rings" function here.
// requires library php-geos
$lines = array();
$pts = array();
$polys = array();
$holes = array();
//array to put results in
$cnt_p = 1;
$div = 0.25;
//gap between points in grid
$motion = 8;
$points=array (
'-9.50:38.75' => '-9.50 38.75',
'-9.25:38.75' => '-9.25 38.75',
'-9.25:39.00' => '-9.25 39.00',
'-9.25:39.25' => '-9.25 39.25',
'-9.00:38.50' => '-9.00 38.50',
'-9.00:38.75' => '-9.00 38.75',
'-9.00:39.00' => '-9.00 39.00',
'-9.00:39.25' => '-9.00 39.25',
'-9.00:39.50' => '-9.00 39.50',
'-9.00:39.75' => '-9.00 39.75',
'-8.75:38.00' => '-8.75 38.00',
'-8.75:38.25' => '-8.75 38.25',
'-8.75:38.50' => '-8.75 38.50',
'-8.75:38.75' => '-8.75 38.75',
'-8.75:39.00' => '-8.75 39.00',
'-8.75:39.25' => '-8.75 39.25',
'-8.75:39.50' => '-8.75 39.50',
'-8.75:39.75' => '-8.75 39.75',
'-8.75:40.00' => '-8.75 40.00',
'-8.75:40.25' => '-8.75 40.25',
'-8.75:40.50' => '-8.75 40.50',
'-8.50:38.25' => '-8.50 38.25',
'-8.50:38.50' => '-8.50 38.50',
'-8.50:38.75' => '-8.50 38.75',
'-8.50:39.00' => '-8.50 39.00',
'-8.50:39.25' => '-8.50 39.25',
'-8.50:39.50' => '-8.50 39.50',
'-8.50:39.75' => '-8.50 39.75',
'-8.25:38.50' => '-8.25 38.50',
'-8.25:38.75' => '-8.25 38.75',
'-8.25:39.00' => '-8.25 39.00',
'-8.25:39.25' => '-8.25 39.25',
'-8.25:39.50' => '-8.25 39.50',
'-8.25:39.75' => '-8.25 39.75',
'-8.00:37.25' => '-8.00 37.25',
'-8.00:38.50' => '-8.00 38.50',
'-8.00:38.75' => '-8.00 38.75',
'-8.00:39.00' => '-8.00 39.00',
'-8.00:39.25' => '-8.00 39.25',
'-8.00:39.50' => '-8.00 39.50',
'-7.75:38.75' => '-7.75 38.75',
'-7.75:39.00' => '-7.75 39.00',
'-7.75:39.25' => '-7.75 39.25',
'-7.75:39.50' => '-7.75 39.50',
'-7.75:39.75' => '-7.75 39.75',
'-7.50:38.75' => '-7.50 38.75',
'-7.50:39.00' => '-7.50 39.00',
'-7.50:39.25' => '-7.50 39.25',
'-7.50:39.50' => '-7.50 39.50',
'-7.50:39.75' => '-7.50 39.75',
'-7.50:40.00' => '-7.50 40.00',
'-7.25:39.00' => '-7.25 39.00',
'-7.25:39.25' => '-7.25 39.25',
'-7.25:39.50' => '-7.25 39.50',
'-7.25:39.75' => '-7.25 39.75',
'-7.25:40.00' => '-7.25 40.00',
'-7.00:38.00' => '-7.00 38.00',
'-7.00:38.50' => '-7.00 38.50',
'-7.00:39.50' => '-7.00 39.50',
'-7.00:39.75' => '-7.00 39.75',
'-7.00:40.00' => '-7.00 40.00',
'-7.00:40.25' => '-7.00 40.25',
'-7.00:40.50' => '-7.00 40.50',
'-7.00:40.75' => '-7.00 40.75',
)
function scope_it() {
global $scope, $points, $re, $pts, $lines, $polys, $holes;
if ($points) {
$re = key($points);
do_res($re);
//start search picking N>S and W>E
}
}
function do_res($re) {
// start enquiry
global $points, $results;
$results = array();
array_push($results, $points[$re]);
$targ = $re;
clock($targ);
//set off search
}
function clock($targ) {
// sniff along from neigbour to neigbour to find lines and polygons
global $poss, $points, $re, $starter, $motion, $pts, $results;
get_poss($targ);
//get box of points to search for neighbours
$got = NULL;
for ($i = 0; $i <= $motion - 1; ++$i) {
$pos = $i + $starter;
$find = isset($points[$poss[$pos]]);
if ($find !== FALSE) {
$got = $poss[$pos];
array_push($results, $points[$poss[$pos]]);
$i = $motion + 1;
//got a neighbour, stop search
} elseif ($pos == $motion) {
$starter = -$i;
}
}
if ($got === NULL) {
array_push($pts, $points[$re]);
$sn2 = explode(":", $re);
// no neighbours, it must be a point
unset($points[$re]);
$starter = 1;
scope_it();
} elseif ($got == $re) {
$starter = 1;
examine($results);
// go to check if result is a polygon or a line
} else {
// end of object not reached, carry on sniffing along line till back to start
$starter = $pos + 5;
if ($starter > 8) {
$starter = $starter - 8;
}
//change start point in next search in order to avoid coming back to previous point in the line (unless all the way around
clock($got);
}
}
function get_poss($targ) {
global $poss, $div, $points;
$poss = array();
$sn = explode(":", $targ);
$sn = explode(":", $targ);
$poss[1] = number_format($sn[0] - $div, 2) . ":" . $sn[1];
$poss[2] = number_format($sn[0] - $div, 2) . ":" . number_format($sn[1] + $div, 2);
$poss[3] = $sn[0] . ":" . number_format($sn[1] + $div, 2);
$poss[4] = number_format($sn[0] + $div, 2) . ":" . number_format($sn[1] + $div, 2);
$poss[5] = number_format($sn[0] + $div, 2) . ":" . $sn[1];
$poss[6] = number_format($sn[0] + $div, 2) . ":" . number_format($sn[1] - $div, 2);
$poss[7] = $sn[0] . ":" . number_format($sn[1] - $div, 2);
$poss[8] = number_format($sn[0] - $div, 2) . ":" . number_format($sn[1] - $div, 2);
//compile array of possible neighbours to a point
}
function get_dia($quo) {
global $div;
$poss = array();
$sn = explode(" ", $quo);
$div2 = $div / 2;
$poss[4] = "[" . $sn[0] . ", " . number_format($sn[1] - $div2, 3) . "]";
$poss[1] = "[" . number_format($sn[0] - $div2, 3) . ", " . $sn[1] . "]";
$poss[2] = "[" . $sn[0] . ", " . number_format($sn[1] + $div2, 3) . "]";
$poss[3] = "[" . number_format($sn[0] + $div2, 3) . ", " . $sn[1] . "]";
$poss[0] = "[" . $sn[0] . ", " . number_format($sn[1] - $div2, 3) . "]";
//get cordinate of diamond around points to convert them to small polygon/diamond
return implode(",", $poss);
}
function examine($polygon) {
// run through polygon check
global $points, $lines, $polys, $cnt_p, $n, $s, $w, $e, $in_points, $pts, $geofence;
$poly = 0;
$in_points = array();
$n = -180;
$s = 180;
$w = 90;
$e = -90;
$geofence = new Polygon();
foreach ($polygon as $k => $v) {
$sn = explode(" ", $v);
$geofence->addPoint(new Coordinate($sn[1], $sn[0]));
$key = $sn[0] . ":" . $sn[1];
$in_points[$key] = $v;
unset($points[$key]);
unset($search[$sn[0]][$sn[1]]);
}
$area = $geofence->getArea();
if ($area > 0) {
foreach ($points as $key => $point) {
$pt = explode(" ", $point);
$Point = new Coordinate($pt[1], $pt[0]);
if (($geofence->contains($Point)) == 1) {
$in_points[$key] = $points[$key];
// put points into array to be searched for holes (rings)
unset($points[$key]);
//find area square if new polygon
if ($pt[0] > $n)
$n = $pt[0];
if ($pt[0] < $s)
$s = $pt[0];
if ($pt[1] < $w)
$w = $pt[1];
if ($pt[1] > $e)
$e = $pt[1];
}
}
if (count($in_points) > 9) {
rings($polygon, $in_points, $cnt_p);
}
$polys[$cnt_p] = $polygon;
++$cnt_p;
} else {
$break = array_unique($polygon);
foreach ($break as $k => $v) {
array_push($pts, $v);
}
}
scope_it();
}
function rings($polygon, $in_points, $cnt_p) {
global $n, $s, $w, $e, $div, $ring_s, $holes, $geofence;
// create array same area sqaure as polygon
$ring_s = array();
for ($a = $w; $a <= $e; $a = $a + $div) {
for ($b = $n; $b >= $s; $b = $b - $div) {
$val = number_format($b, 2) . " " . number_format($a, 2);
$key = number_format($b, 2) . ":" . number_format($a, 2);
$ring_s[$key] = $val;
}
}
// remove points in new array outside of polygon
foreach ($ring_s as $key => $point) {
$pt = explode(":", $key);
$Point = new Coordinate($pt[1], $pt[0]);
if (($geofence->contains($Point)) == 0) {
unset($ring_s[$key]);
}
}
foreach ($polygon as $k => $v) {
$sn = explode(" ", $v);
$key = $sn[0] . ":" . $sn[1];
$ring_s[$key] = $v;
}
foreach ($in_points as $k => $v) {
$find = isset($ring_s[$k]);
//deduct from new array ponits found in those to be sorted, leaves any holes in polygon
if ($find !== FALSE) {
unset($ring_s[$k]);
}
}
$cn_r = count($ring_s);
if ($cn_r > 0) {
$holes[$cnt_p] = array();
scope_r($cnt_p);
}
}
function scope_r($cnt_p) {
global $ring_s, $in_points, $poss, $motion, $re, $results, $starter, $previous;
// cycle through remains of the new array W>E and N>S looking for ones that are neigbouring vertices of holes in points to de sorted. When one is found jump onto that vertices and find the other points of internal polygon/edge.
if ($ring_s) {
$key = key($ring_s);
$val = reset($ring_s);
get_poss($key);
$got = NULL;
for ($i = 1; $i <= $motion; ++$i) {
$find = isset($in_points[$poss[$i]]);
if ($find !== FALSE) {
$got = $poss[$i];
$pos = $i;
$i = $motion + 1;
}
}
if ($got !== NULL) {
$results = array();
$re = $got;
array_push($results, $in_points[$re]);
$starter = $pos + 4;
if ($starter > 8) {
$starter = $starter - 8;
}
clock_r($cnt_p, $got);
// jump to search set of points
} else {
unset($ring_s[$key]);
scope_r($cnt_p);
}
}
}
function clock_r($cnt_p, $targ) {
global $poss, $starter, $in_points, $motion, $re, $results, $holes, $ring_s;
get_poss($targ);
//get box of points to search for neighbours
$got = NULL;
for ($i = 0; $i <= $motion - 1; ++$i) {
// search through neighbours for internal hole edges
$pos = $i + $starter;
$find = isset($in_points[$poss[$pos]]);
if ($find !== FALSE) {
$got = $poss[$pos];
array_push($results, $in_points[$got]);
$i = $motion + 1;
} elseif ($pos == $motion) {
$starter = -$i;
}
}
if ($got == $re) {
$starter = 1;
$poly = $results;
array_push($holes[$cnt_p], array_reverse($poly));
$geo2 = new Polygon();
foreach ($poly as $k => $v) {
$sn = explode(" ", $v);
$geo2->addPoint(new Coordinate($sn[1], $sn[0]));
}
foreach ($ring_s as $key => $point) {
$pt = explode(":", $key);
$Point = new Coordinate($pt[1], $pt[0]);
if (($geo2->contains($Point)) == 1) {
unset($ring_s[$key]);
}
}
//when whole of internal polygon found ($re is start/end point), add it to array of holes per main polygon, reversing array order as these should be clockwise and main polygon anti-clockwise. Delete points internal to hole searching array and find any other holes left to record in that array
scope_r($cnt_p);
} else {
$starter = $pos + 5;
if ($starter > 8) {
$starter = $starter - 8;
}
clock_r($cnt_p, $got);
}
}
$starter = 1;
// start position for searching through neighbours
scope_it();
the array shown here outputs http://wheat-gateway.org.uk/json_map_final.php?ord=4&cns=109&ctrl_r=1//591/923,2//-5/31&ctrl=1,2 which in turn creates http://www.wheat-gateway.org.uk/climate_search.php?ord=4&cns=109&ctrl_r=1//591/923,2//-5/31&ctrl=1,2

Basic perceptron for AND gate in PHP, am I doing it right? Weird results

I'd like to learn about neural nets starting with the very basic perceptron algorithm. So I've implemented one in PHP and I'm getting weird results after training it. All the 4 possible input combinations return either wrong or correct results (more often the wrong ones).
1) Is there something wrong with my implementation or the results I'm getting are normal?
2) Can this kind of implementation work with more than 2 inputs?
3) What would be the next (easiest) step in learning neural nets after this? Maybe adding more neurons, changing the activation function, or ...?
P.S. I'm pretty bad at math and don't necessarily understand the math behind perceptron 100%, at least not the training part.
Perceptron Class
<?php
namespace Perceptron;
class Perceptron
{
// Number of inputs
protected $n;
protected $weights = [];
protected $bias;
public function __construct(int $n)
{
$this->n = $n;
// Generate random weights for each input
for ($i = 0; $i < $n; $i++) {
$w = mt_rand(-100, 100) / 100;
array_push($this->weights, $w);
}
// Generate a random bias
$this->bias = mt_rand(-100, 100) / 100;
}
public function sum(array $inputs)
{
$sum = 0;
for ($i = 0; $i < $this->n; $i++) {
$sum += ($inputs[$i] * $this->weights[$i]);
}
return $sum + $this->bias;
}
public function activationFunction(float $sum)
{
return $sum < 0.0 ? 0 : 1;
}
public function predict(array $inputs)
{
$sum = $this->sum($inputs);
return $this->activationFunction($sum);
}
public function train(array $trainingSet, float $learningRate)
{
foreach ($trainingSet as $row) {
$inputs = array_slice($row, 0, $this->n);
$correctOutput = $row[$this->n];
$output = $this->predict($inputs);
$error = $correctOutput - $output;
// Adjusting the weights
$this->weights[0] = $this->weights[0] + ($learningRate * $error);
for ($i = 0; $i < $this->n - 1; $i++) {
$this->weights[$i + 1] =
$this->weights[$i] + ($learningRate * $inputs[$i] * $error);
}
}
// Adjusting the bias
$this->bias += ($learningRate * $error);
}
}
Main File
<?php
require_once 'vendor/autoload.php';
use Perceptron\Perceptron;
// Create a new perceptron with 2 inputs
$perceptron = new Perceptron(2);
// Test the perceptron
echo "Before training:\n";
$output = $perceptron->predict([0, 0]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([0, 1]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([1, 0]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([1, 1]);
echo "{$output} - " . ($output == 1 ? 'correct' : 'nope') . "\n";
// Train the perceptron
$trainingSet = [
// The 3rd column is the correct output
[0, 0, 0],
[0, 1, 0],
[1, 0, 0],
[1, 1, 1],
];
for ($i = 0; $i < 1000; $i++) {
$perceptron->train($trainingSet, 0.1);
}
// Test the perceptron again - now the results should be correct
echo "\nAfter training:\n";
$output = $perceptron->predict([0, 0]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([0, 1]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([1, 0]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([1, 1]);
echo "{$output} - " . ($output == 1 ? 'correct' : 'nope') . "\n";
I must thank you for posting this question, I have wanted a chance to dive a little deeper into neural networks. Anyway, down to business. After tinkering around and verbose logging what all is happening, it ended up only requiring 1 character change to work as intended:
public function sum(array $inputs)
{
...
//instead of multiplying the input by the weight, we should be adding the weight
$sum += ($inputs[$i] + $this->weights[$i]);
...
}
With that change, 1000 iterations of training ends up being overkill.
One bit of the code was confusing, different setting of weights:
public function train(array $trainingSet, float $learningRate)
{
foreach ($trainingSet as $row) {
...
$this->weights[0] = $this->weights[0] + ($learningRate * $error);
for ($i = 0; $i < $this->n - 1; $i++) {
$this->weights[$i + 1] =
$this->weights[$i] + ($learningRate * $inputs[$i] * $error);
}
}
I don't necessarily understand why you chose to do it this way. My unexperienced eye would think that the following would work as well.
for ($i = 0; $i < $this->n; $i++) {
$this->weight[$i] += $learningRate * $error;
}
Found my silly mistake, I wasn't adjusting the bias for each row of a training set as I accidentally put it outside the foreach loop. This is what the train() method should look like:
public function train(array $trainingSet, float $learningRate)
{
foreach ($trainingSet as $row) {
$inputs = array_slice($row, 0, $this->n);
$correctOutput = $row[$this->n];
$output = $this->predict($inputs);
$error = $correctOutput - $output;
// Adjusting the weights
for ($i = 0; $i < $this->n; $i++) {
$this->weights[$i] += ($learningRate * $inputs[$i] * $error);
}
// Adjusting the bias
$this->bias += ($learningRate * $error);
}
}
Now I get the correct results after training each time I run the script. Just 100 epochs of training is enough.

PHP remove dropdownlist 2 items taken from database

I am new to PHP. This is an existing system. I have been told to remove particularly 2 items from the drop down list. The dropdown items is taken from the mysql database. There is 3 items currently in the dropdown: ICD, Product and Doctor Charges. I have been told to remove Product and Doctor Charges.
The codes in PHP:
function split_csv_line($record) {
$first = NULL;
if (strlen($record) == 0) {
return array('');
}
if ($record[0] === '"') {
$first = '';
$start = 1;
while ($start < strlen($record)
&& ($end = strpos($record, '"', $start)) !== FALSE
&& $end < strlen($record) - 1
&& $record[$end + 1] !== ',')
{
if ($record[$end + 1] !== '"') {
die("Found characters between double-quoted field and comma.");
}
$first .= substr($record, $start, $end - $start - 1);
$start = $end + 2;
}
if ($start < strlen($record) || $end === FALSE) {
die("Could not find end-quote for double-quoted field");
}
$first .= substr($record, $start, $end - $start - 1);
if ($end >= strlen($record) - 1) {
return array($first);
}
/* Assertion: $record[$end + 1] == ',' */
$rest = substr($record, $end + 2);
} else {
$end = strpos($record, ',');
if ($end === FALSE) {
return array($record);
}
/* Assertion: $end < strlen($record) */
$first = substr($record, 0, $end);
$rest = substr($record, $end + 1);
}
$fields = split_csv_line($rest);
array_unshift($fields, $first);
return $fields;
}
And this is MYSQL query:
$code_types = array();
$default_search_type = '';
$ctres = sqlStatement("SELECT * FROM code_types WHERE ct_active=1 ORDER BY ct_seq, ct_key");
while ($ctrow = sqlFetchArray($ctres)) {
$code_types[$ctrow['ct_key']] = array(
'active' => $ctrow['ct_active' ],
'id' => $ctrow['ct_id' ],
'fee' => $ctrow['ct_fee' ],
'mod' => $ctrow['ct_mod' ],
'just' => $ctrow['ct_just'],
'rel' => $ctrow['ct_rel' ],
'nofs' => $ctrow['ct_nofs'],
'diag' => $ctrow['ct_diag'],
'mask' => $ctrow['ct_mask'],
'label'=> ( (empty($ctrow['ct_label'])) ? $ctrow['ct_key'] : $ctrow['ct_label'] ),
'external'=> $ctrow['ct_external'],
'claim' => $ctrow['ct_claim'],
'proc' => $ctrow['ct_proc'],
'term' => $ctrow['ct_term'],
'problem'=> $ctrow['ct_problem'],
'drug'=> $ctrow['ct_drug']
);

how can I sort and display dynamic data under dymanic table headers?

The project is a web calendar/scheduler using php. The idea is that a user can schedule a job that is assigned to specific machine at a specific time and others can see the job schedule and which 'asset' the job is assigned to. The scheduling works, however, I cannot tie the data to header/columns they belong to. It looks like this:
<?php
include_once("HTML/TABLE.PHP");
$data = array( 0=>array(1,'asset1','2013-07-24 10:00:00', '2013-07-24 12:00:00','red',2),
1=>array(2,'asset1','2013-07-24 12:00:00', '2013-07-24 13:00:00','green',3),
2=>array(3,'asset2','2013-07-24 11:00:00', '2013-07-24 12:00:00','blue', 4),
3=>array(4,'asset2','2013-07-24 12:00:00', '2013-07-24 14:00:00','red', 2),
4=>array(5,'asset3','2013-07-24 11:30:00', '2013-07-24 12:00:00','green', 4),
5=>array(6,'asset4','2013-07-24 12:00:00', '2013-07-24 14:00:00','blue', 3),
6=>array(7,'asset1','2013-07-24 11:45:00', '2013-07-24 13:00:00','red', 1),
7=>array(8,'asset4','2013-07-24 13:00:00', '2013-07-24 15:00:00','yellow', 5)
);
$attrs = array( 'class' => 'main',
'id' => 'main_id',
'width' => '100%',
'border' => '1',
'cellspacing' => '0',
'cellpadding' => '0');
$table = new HTML_Table($attrs);
$table->setAutoGrow(true);
$table->setAutoFill('n/a');
$heads = array( array('asset1','asset2','asset3','asset4'));
$i = 1;
foreach($heads as $val)
{
$table->setHeaderContents(0, $i++, $val);
unset($val);
}
$now = date('U');
$offset = ($now % 900);
$now = $now-$offset;
for ($i = 0;$i < 33; $i++)
{
$table->setHeaderContents($i,0, date('g:i',$now));
$now += 900;
}
$cellPosition = 1;
$rowCounter = 1;
for ($i=0;$i < count($data);$i++)
{
$table->setCellAttributes ($rowCounter,$cellPosition,' bgcolor = '. $data[$i][4]. ' rowspan=' . $data[$i][5]);
$table->setCellContents($rowCounter,$cellPosition,"Job# ".$data[$i][0] . " belongs to: " . $data[$i][1]);
$cellPosition++;
$rowCounter =1;
}
echo $table->display();
?>
How can I tie the information to only the column it belongs to?
I have gotten this far, but I get odd results if the first column is true:
$cellPosition = 0;
$rowCounter = 1;
for ($x=0;$x <= count($heads);$x++)
{
for ($i=0;$i < count($data);$i++)
{
if ($data[$i][1] == $table->getCellContents(0,$x))
{
$table->setCellAttributes ($rowCounter,$cellPosition,' bgcolor = '. $data[$i][4]. ' rowspan=' . $data[$i][5]);
$table->setCellContents($rowCounter,$cellPosition,"Job# ".$data[$i][0] . " belongs to: " . $data[$i][1]);
//$cellPosition++;
//echo ;
echo "<br> The current count of x = : ". $x;
echo "<br>" . $table->getCellContents(0,$x) . " Matches " . $table->getCellContents(0,$x) . " at index " . $i;
$rowCounter += $data[$i][5];
}
else
{
$rowCounter = 1;
}
}
$cellPosition++;
Ok this is working, but only if the array results are in order by asset. If not the row is reset to row 1 and the second entry overlays the previous.
$cellPosition = 0;
$rowCounter = 1;
for ($x=0;$x <= count($heads);$x++)
{
for ($i=0;$i < count($data);$i++)
{
if ($data[$i][1] == $table->getCellContents(0,$x))
{
$table->setCellAttributes ($rowCounter,$cellPosition,' bgcolor = '. $data[$i][4]. ' rowspan=' . $data[$i][5]);
$table->setCellContents($rowCounter,$cellPosition,"Job# ".$data[$i][0] . " belongs to: " . $data[$i][1]);
echo "<br> The current count of x = : ". $x;
echo "<br>" . $table->getCellContents(0,$x) . " Matches " . $data[$i][1] . " at index " . $i;
$rowCounter += $data[$i][5];
}
else
{
$rowCounter = 1;
}
}
$cellPosition++;
}
My solution is to presort the records using sql order by. I don't know how elegant that is but for the moment it is working and I can move further into this project. Any suggestions would be welcome. Thanks!

A loop suddenly ceases to iterate?

I have this php code:
<?php
$numarray = trim($_GET['num']);
$i = strlen($numarray);
$result = "";
$numneedarray = array(
90 => 'ninety',
80 => 'eighty',
70 => 'seventy',
60 => 'sixty',
50 => 'fifty',
40 => 'forty',
30 => 'thirty',
20 => 'twenty',
19 => 'nineteen',
18 => 'eighteen',
17 => 'seventeen',
16 => 'sixteen',
15 => 'fifteen',
14 => 'fourteen',
13 => 'thirteen',
12 => 'twelve',
11 => 'eleven',
10 => 'ten',
9 => 'nine',
8 => 'eight',
7 => 'seven',
6 => 'six',
5 => 'five',
4 => 'four',
3 => 'three',
2 => 'two',
1 => 'one'
);
for ($v = 1; $v <= $i; $v++) {
if ($i > 10) {
exit("Has to be 10-digit or less.");
}
if ($i == 3) {
$result .= ", " . $numneedarray[$numarray[strlen($numarray) - 3]] . " hundred";
if ($numarray % 100 == 0) {
echo "Hi95";
break;
}
} elseif ($i == 2) {
if ($numarray[$v] == 1) {
$othernum = $numarray[strlen($numarray) - 1];
$othernum2 = $numarray[strlen($numarray) - 2] * 10;
$othernum3 = $othernum2 + $othernum;
if (strlen($numarray) > 2) {
$result .= " and ";
}
$result .= $numneedarray[$othernum3];
echo "Hi107";
} else {
$othernum = $numarray[strlen($numarray) - 2] * 10;
$othernum2 = $numarray[strlen($numarray) - 1];
$result .= " and " . $numneedarray[$othernum] . " " . $numneedarray[$othernum2];
echo "Hi112";
}
}
if ($i == 10) {
$digit = substr($numarray, 0, 1);
$result .= $numneedarray[$digit] . " billion";
if ($numarray % 1000000000 == 0) {
break;
}
} elseif ($i == 9) {
$number = substr($numarray, 1, 3);
$digit1 = substr($number, 0, 1);
$digit1con = $numneedarray[$digit1] . " hundred";
$digit2 = substr($number, 1, 1);
$noneed = false;
if ($digit2 != 1) {
$digit2con = $numneedarray[$digit2 * 10];
} else {
$digit23 = substr($number, 1, 2);
$digit23con = $numneedarray[$digit23];
$noneed = true;
}
$digit3 = substr($number, -1);
$digit3con = $numneedarray[$digit3];
if ($noneed == true) {
$result .= ", " . $digit1con . " and " . $digit23con . " million";
} else {
$result .= ", " . $digit1con . " and " . $digit2con . " " . $digit3con . " million";
}
if ($numarray % 100000000 == 0) {
echo "Hi";
break;
}
} elseif ($i == 6) {
$number = substr($numarray, 4, 3);
$digit1 = substr($number, 0, 1);
$digit1con = $numneedarray[$digit1] . " hundred";
$digit2 = substr($number, 1, 1);
$noneed = false;
if ($digit2 != 1) {
$digit2con = $numneedarray[$digit2 * 10];
} else {
$digit23 = substr($number, 1, 2);
$digit23con = $numneedarray[$digit23];
$noneed = true;
}
$digit3 = substr($number, -1);
$digit3con = $numneedarray[$digit3];
if ($noneed == true) {
$result .= ", " . $digit1con . " and " . $digit23con . " thousand";
} else {
$result .= ", " . $digit1con . " and " . $digit2con . " " . $digit3con . " thousand";
}
if ($numarray % 100000 == 0) {
echo "Hi89";
break;
}
}
echo $i;
$i = $i - 1;
}
if (strlen($numarray) == 1) {
echo $numneedarray[$numarray];
}
echo $result;
?>
The num value is equal to 1234567890. When I refresh the page, the value of $i only goes from 10 -> 9 -> 8 -> 7 -> 6 and then suddenly stops. Why would the loop stop running?
You try to check each digit:
for ($v = 1; $v <= $i; $v++) {
But then you decrease $i in the loop:
$i = $i - 1;
That's why you see less loops than you expected.
I hope below post will help you achieve what you're looking for:
http://www.karlrixon.co.uk/writing/convert-numbers-to-words-with-php/
not optimal - but change
$i = strlen($numarray);
to
$i = strlen($numarray);
$count = $i;
and
for ($v = 1; $v <= $i; $v++)
to
for ($v = 1; $v <= $count; $v++)

Categories