memperbaiki cost/benefit
This commit is contained in:
parent
4b2a9130cd
commit
e68e59a169
|
|
@ -29,7 +29,7 @@ public function getRecommendations(array $input): Collection
|
|||
|
||||
$criterias = Criteria::orderBy('weight_order')->get();
|
||||
if ($criterias->isEmpty()) {
|
||||
return $products->take(5)->map(fn ($p, $i) => [
|
||||
return $products->take(5)->map(fn($p, $i) => [
|
||||
'rank' => $i + 1,
|
||||
'product' => $p,
|
||||
'score' => 0.0,
|
||||
|
|
@ -47,7 +47,7 @@ public function getRecommendations(array $input): Collection
|
|||
|
||||
return $ranked->map(function ($item, $index) use ($products, $criteriaNames, $priorities) {
|
||||
$product = $products->firstWhere('id', $item['product_id']);
|
||||
if (! $product) {
|
||||
if (!$product) {
|
||||
return null;
|
||||
}
|
||||
$explanation = $this->buildExplanation($product, $item['score'], $priorities, $criteriaNames);
|
||||
|
|
@ -87,7 +87,7 @@ public function getRecommendationsWithMatrix(array $input): array
|
|||
|
||||
$criterias = Criteria::orderBy('weight_order')->get();
|
||||
if ($criterias->isEmpty()) {
|
||||
$recommendations = $products->take(5)->map(fn ($p, $i) => [
|
||||
$recommendations = $products->take(5)->map(fn($p, $i) => [
|
||||
'rank' => $i + 1,
|
||||
'product' => $p,
|
||||
'score' => 0.0,
|
||||
|
|
@ -110,7 +110,7 @@ public function getRecommendationsWithMatrix(array $input): array
|
|||
$ranked = $scores->sortByDesc('score')->take(5)->values();
|
||||
$topProductIds = $ranked->pluck('product_id')->all();
|
||||
$rankedScoresByProductId = $ranked
|
||||
->mapWithKeys(fn ($item) => [$item['product_id'] => round($item['score'], 4)])
|
||||
->mapWithKeys(fn($item) => [$item['product_id'] => round($item['score'], 4)])
|
||||
->all();
|
||||
|
||||
$criteriasWithWeight = [];
|
||||
|
|
@ -125,7 +125,7 @@ public function getRecommendationsWithMatrix(array $input): array
|
|||
$decisionMatrix = [];
|
||||
foreach ($topProductIds as $productId) {
|
||||
$row = $matrix[$productId] ?? null;
|
||||
if (! $row) {
|
||||
if (!$row) {
|
||||
continue;
|
||||
}
|
||||
$product = $products->firstWhere('id', $productId);
|
||||
|
|
@ -139,7 +139,7 @@ public function getRecommendationsWithMatrix(array $input): array
|
|||
$normalizedMatrix = [];
|
||||
foreach ($topProductIds as $productId) {
|
||||
$row = $normalized[$productId] ?? null;
|
||||
if (! $row) {
|
||||
if (!$row) {
|
||||
continue;
|
||||
}
|
||||
$product = $products->firstWhere('id', $productId);
|
||||
|
|
@ -156,7 +156,7 @@ public function getRecommendationsWithMatrix(array $input): array
|
|||
$criteriaNames = $criterias->keyBy('id')->map->name;
|
||||
$recommendations = $ranked->map(function ($item, $index) use ($products, $criteriaNames, $priorities) {
|
||||
$product = $products->firstWhere('id', $item['product_id']);
|
||||
if (! $product) {
|
||||
if (!$product) {
|
||||
return null;
|
||||
}
|
||||
$explanation = $this->buildExplanation($product, $item['score'], $priorities, $criteriaNames);
|
||||
|
|
@ -205,23 +205,33 @@ protected function ageRangeOverlaps(string $ageRange, int $childMin, int $childM
|
|||
|
||||
protected function buildWeightsFromPriorities(array $priorities, Collection $criterias): array
|
||||
{
|
||||
// priorities: [criteria_id => 1..5]
|
||||
// return weights by criteria name: ['Harga' => 0.2, 'Kualitas' => 0.2, ...]
|
||||
$raw = [];
|
||||
$sum = 0.0;
|
||||
|
||||
foreach ($criterias as $c) {
|
||||
$w = (float) ($priorities[(string) $c->id] ?? $priorities[$c->id] ?? 1);
|
||||
if ($w < 1) $w = 1;
|
||||
if ($w > 5) $w = 5;
|
||||
|
||||
$input = (int) ($priorities[(string) $c->id] ?? $priorities[$c->id] ?? 3);
|
||||
|
||||
if ($input < 1)
|
||||
$input = 1;
|
||||
if ($input > 5)
|
||||
$input = 5;
|
||||
|
||||
// Jika Cost, dibalik
|
||||
if ($c->type === 'cost') {
|
||||
$w = 6 - $input;
|
||||
} else {
|
||||
$w = $input;
|
||||
}
|
||||
|
||||
$raw[$c->name] = $w;
|
||||
$sum += $w;
|
||||
}
|
||||
|
||||
$count = max(1, $criterias->count());
|
||||
$weights = [];
|
||||
foreach ($raw as $name => $v) {
|
||||
$weights[$name] = $sum > 0 ? $v / $sum : 1 / $count;
|
||||
|
||||
foreach ($raw as $name => $value) {
|
||||
$weights[$name] = $value / $sum;
|
||||
}
|
||||
|
||||
return $weights;
|
||||
|
|
@ -240,7 +250,7 @@ protected function buildMatrix(Collection $products, Collection $criterias): arr
|
|||
}
|
||||
}
|
||||
foreach ($criterias as $c) {
|
||||
if (! isset($row[$c->name])) {
|
||||
if (!isset($row[$c->name])) {
|
||||
$row[$c->name] = $c->name === 'Harga' ? (float) $product->price : 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('products', function (Blueprint $table) {
|
||||
$table->longBlob('image_blob')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('products', function (Blueprint $table) {
|
||||
$table->binary('image_blob')->nullable()->after('image');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('products', function (Blueprint $table) {
|
||||
$table->dropColumn('image_blob');
|
||||
});
|
||||
}
|
||||
};
|
||||
Loading…
Reference in New Issue