Skip to content

Commit

Permalink
Analyse relative sizes of economies on various goods
Browse files Browse the repository at this point in the history
  • Loading branch information
cim-- committed Aug 13, 2018
1 parent 47263ae commit 0537b32
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 14 deletions.
116 changes: 102 additions & 14 deletions app/Console/Commands/GoodsAnalysis2.php
Expand Up @@ -13,6 +13,7 @@
use App\Models\Tradebalance;
use App\Models\Economy;
use App\Models\Baselinestock;
use App\Models\Commoditystat;

class GoodsAnalysis2 extends Command
{
Expand All @@ -21,7 +22,7 @@ class GoodsAnalysis2 extends Command
*
* @var string
*/
protected $signature = 'cdb:goodsanalysis2';
protected $signature = 'cdb:goodsanalysis2 {--sizeonly}';

/**
* The console command description.
Expand All @@ -43,6 +44,8 @@ public function __construct()
protected $commodityinfo = [];
private $maxsupmultiplier = 0;
private $maxdemmultiplier = 0;
private $colonysizefactor = 0;
private $genericsizefactor = 0;

/**
* Execute the console command.
Expand All @@ -51,9 +54,17 @@ public function __construct()
*/
public function handle()
{
/* Derived by comparing hydrogen fuel baselines with CEI bases */
$this->genericsizefactor = 1806.52032;
$this->colonysizefactor = 0.18432;

try {
\DB::transaction(function() {
$this->runGoodsAnalysis();
if (!$this->option('sizeonly')) {
$this->runGoodsAnalysis();
} else {
$this->info("Size analysis only");
}
$this->runEconomySizeAnalysis();
});
} catch (\Throwable $e) {
Expand Down Expand Up @@ -105,7 +116,7 @@ private function runGoodsAnalysis() {
}
$estimate = "Neither";
if (count($supplyregen)>0) {
$commodity->supplycycle = $this->median($supplyregen);
$commodity->supplycycle = floor($this->median($supplyregen));
} else if ($commodity->averageprice > 0) {
/* The broad trend seems to be 2 days + 1 minute per
* credit of average price */
Expand All @@ -115,7 +126,7 @@ private function runGoodsAnalysis() {
$commodity->supplycycle = null;
}
if (count($demandregen)>0) {
$commodity->demandcycle = $this->median($demandregen);
$commodity->demandcycle = floor($this->median($demandregen));
} else if ($commodity->averageprice > 0) {
/* The broad trend seems to be 2.5x the supply cycle,
* so 5 days + 2.5 minutes per credit of average
Expand Down Expand Up @@ -167,8 +178,9 @@ public function analyseRegeneration(Commodity $commodity, Station $station, Stat
$stability++;
}
}
if ($stability < 5) {
if ($stability < 5 && $commodity->id != 1) {
// insufficient to confirm baseline
// will use for HFuel *anyway* because a guess is better than nothing
return null;
}

Expand Down Expand Up @@ -235,7 +247,7 @@ public function analyseRegeneration(Commodity $commodity, Station $station, Stat
return null;
}
// $this->line("Checking: ".$commodity->name." at ".$station->name." in ".$state->name);
$avgrate = (int)$this->median($slopes);
$avgrate = floor($this->median($slopes));
$regentime = $avgrate * $max;
// $this->line(($sign>0?"Supply":"Demand")." Regen time: $regentime (".round($regentime/86400, 1).") days");
return $regentime * $sign;
Expand All @@ -259,13 +271,7 @@ private function mean($arr) {
}

private function median($arr) {
sort($arr);
$mid = (count($arr)-1)/2;
if ($mid == floor($mid)) {
return $arr[$mid];
} else {
return floor(($arr[floor($mid)]+$arr[ceil($mid)])/2);
}
return $this->percentile($arr, 0.5);
}


Expand Down Expand Up @@ -294,15 +300,26 @@ private function runEconomySizeAnalysis() {
$hydrogen = Commodity::where('name', 'HydrogenFuel')->first();

$commodities = Commodity::get();

$cdata = [
'supply'=>[],
'demand'=>[]
];

foreach ($stations as $station) {
$hfuelbaseline = $station->baselinestocks->where('commodity_id', $hydrogen->id)->first();
if (!$hfuelbaseline) {
continue;
}
$hfb = $hfuelbaseline->reserves;

if ($station->economy->name == "Colony") {
$esf = $this->colonysizefactor;
} else {
$esf = $this->genericsizefactor;
}

$economysize = ($hfb*$hfb)/(1849);
$economysize = ($hfb*$hfb)/($esf);
$station->economysize = $economysize;
$station->save();

Expand All @@ -315,12 +332,83 @@ private function runEconomySizeAnalysis() {
$baseline = $station->baselinestocks->where('commodity_id', $commodity->id)->first();
if ($baseline) {
$intensity = $baseline->reserves / $ecsizefactor;
if ($intensity > 0) {
if (!isset($cdata['supply'][$commodity->id])) {
$cdata['supply'][$commodity->id] = [];
}
$cdata['supply'][$commodity->id][] = $intensity;
} else if ($intensity < 0) {
if (!isset($cdata['demand'][$commodity->id])) {
$cdata['demand'][$commodity->id] = [];
}
$cdata['demand'][$commodity->id][] = -$intensity;
}
$baseline->intensity = $intensity;
$baseline->save();
}
}
}

foreach ($commodities as $commodity) {
$demand = isset($cdata['demand'][$commodity->id])?$cdata['demand'][$commodity->id]:[];
$supply = isset($cdata['supply'][$commodity->id])?$cdata['supply'][$commodity->id]:[];
$dstats = $this->stats($demand);
$sstats = $this->stats($supply);

$stat = Commoditystat::firstOrNew(['commodity_id' => $commodity->id]);

$stat->demandmin = $dstats['min'];
$stat->demandlowq = $dstats['lowq'];
$stat->demandmed = $dstats['median'];
$stat->demandhighq = $dstats['highq'];
$stat->demandmax = $dstats['max'];
$stat->supplymin = $sstats['min'];
$stat->supplylowq = $sstats['lowq'];
$stat->supplymed = $sstats['median'];
$stat->supplyhighq = $sstats['highq'];
$stat->supplymax = $sstats['max'];

$stat->save();
}
}



private function stats($arr) {
if (count($arr) == 0) {
return [
'min' => null,
'max' => null,
'lowq' => null,
'median' => null,
'highq' => null
];
}
sort($arr);
return [
'min' => $arr[0],
'max' => $arr[count($arr)-1],
'lowq' => $this->lowq($arr),
'median' => $this->median($arr),
'highq' => $this->highq($arr)
];
}

private function percentile($arr, $per) {
sort($arr);
$mid = (count($arr)-1)*$per;
if ($mid == floor($mid)) {
return $arr[$mid];
} else {
return ($arr[floor($mid)]+$arr[ceil($mid)])/2;
}
}

private function lowq($arr) {
return $this->percentile($arr, 0.25);
}
private function highq($arr) {
return $this->percentile($arr, 0.5);
}

}
5 changes: 5 additions & 0 deletions app/Models/Commodity.php
Expand Up @@ -13,6 +13,11 @@ public function reserves()
return $this->hasMany('App\Models\Reserve');
}

public function commoditystat()
{
return $this->hasOne('App\Models\Commoditystat');
}

public function baselinestocks()
{
return $this->hasMany('App\Models\Baselinestock');
Expand Down
59 changes: 59 additions & 0 deletions app/Models/Commoditystat.php
@@ -0,0 +1,59 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Commoditystat extends Model
{
protected $fillable = ['commodity_id'];

public function commodity() {
return $this->belongsTo('App\Models\Commodity');
}

public function getLevel($intensity) {
if ($intensity < 0) {
return $this->getDemandLevel(-$intensity);
} else if ($intensity > 0) {
return $this->getSupplyLevel($intensity);
} else {
return 0;
}
}

protected function getDemandLevel($intensity) {
if ($this->demandmin === null) {
return 0;
}
if ($intensity < ($this->demandmin+$this->demandlowq)/2) {
return 1;
} else if ($intensity < ($this->demandlowq+$this->demandmed)/2) {
return 2;
} else if ($intensity <= ($this->demandmed+$this->demandhighq)/2) {
return 3;
} else if ($intensity <= ($this->demandhighq+$this->demandmax)/2) {
return 4;
} else {
return 5;
}
}

protected function getSupplyLevel($intensity) {
if ($this->supplymin === null) {
return 0;
}
if ($intensity < ($this->supplymin+$this->supplylowq)/2) {
return 1;
} else if ($intensity < ($this->supplylowq+$this->supplymed)/2) {
return 2;
} else if ($intensity <= ($this->supplymed+$this->supplyhighq)/2) {
return 3;
} else if ($intensity <= ($this->supplyhighq+$this->supplymax)/2) {
return 4;
} else {
return 5;
}
}

}
@@ -0,0 +1,42 @@
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCommoditystatsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('commoditystats', function (Blueprint $table) {
$table->increments('id');
$table->integer('commodity_id')->index();
$table->float('demandmin')->nullable();
$table->float('demandlowq')->nullable();
$table->float('demandmed')->nullable();
$table->float('demandhighq')->nullable();
$table->float('demandmax')->nullable();
$table->float('supplymin')->nullable();
$table->float('supplylowq')->nullable();
$table->float('supplymed')->nullable();
$table->float('supplyhighq')->nullable();
$table->float('supplymax')->nullable();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('commoditystats');
}
}
5 changes: 5 additions & 0 deletions resources/views/components/intensity.blade.php
@@ -0,0 +1,5 @@
@if (!$baseline)
<td data-sort='0'></td>
@else
@include('components/intensitycell', ['level' => $stats->getLevel($baseline->intensity), 'labels' => ['', 'Very low', 'Low', 'Average', 'High', 'Very high'], 'exact' => $baseline->intensity])
@endif
3 changes: 3 additions & 0 deletions resources/views/components/intensitycell.blade.php
@@ -0,0 +1,3 @@
<td title='{{$exact}}' data-sort='{{$level}}'>
{{$labels[$level]}}
</td>
6 changes: 6 additions & 0 deletions resources/views/stations/show.blade.php
Expand Up @@ -62,6 +62,12 @@
<a href="{{route('stations.showtrade', $station->id)}}">
{{$facility->name}}
</a>
(economy size:
@if ($station->economysize)
{{number_format($station->economysize)}})
@else
Unknown)
@endif
@elseif ($facility->name == "Outfitting")
<a href="{{route('stations.showoutfitting', $station->id)}}">
{{$facility->name}}
Expand Down
9 changes: 9 additions & 0 deletions resources/views/stations/trade.blade.php
Expand Up @@ -10,6 +10,13 @@

@section('content')

<p>Economy size:
@if ($station->economysize)
{{number_format($station->economysize)}}
@else
Unknown
@endif
</p>
<p>Total estimated reserves: {{number_format($supply)}}</p>
<p>Total estimated demand: {{number_format($demand)}}</p>

Expand All @@ -26,6 +33,7 @@
<th>Status</th>
<th>Stock/Demand</th>
<th>Baseline Stock/Demand</th>
<th title='Allowing for the overall size of the station economy, how much does this produce/consume relative to other stations?'>Relative Production/Consumpion</th>
<th>Price</th>
<th>History</th>
</tr>
Expand Down Expand Up @@ -55,6 +63,7 @@
<td>
@include('components/surplusdeficit', ['value' => $station->baselinestocks->where('commodity_id', $reserve->id)->first()])
</td>
@include('components/intensity', ['baseline' => $station->baselinestocks->where('commodity_id', $reserve->id)->first(), 'stats' => $reserve->commoditystat])
<td>
{{$reserve->reserves->first()->price}}
</td>
Expand Down
2 changes: 2 additions & 0 deletions resources/views/trade/commodity.blade.php
Expand Up @@ -43,6 +43,7 @@
<th>Status</th>
<th>Stock/Demand</th>
<th>Baseline Stock/Demand</th>
<th>Trade Intensity</th>
<th>Price</th>
@if ($station !== null)
<th>Distance to {{$station->name}} (LY)</th>
Expand Down Expand Up @@ -100,6 +101,7 @@
<td>
@include('components/surplusdeficit', ['value' => $commodity->baselinestocks->where('station_id', $reserve->station->id)->first()])
</td>
@include('components/intensity', ['baseline' => $commodity->baselinestocks->where('station_id', $reserve->station->id)->first(), 'stats' => $commodity->commoditystat])
<td>
{{$reserve->price}}
</td>
Expand Down

0 comments on commit 0537b32

Please sign in to comment.