memperbaiki cost/benefit

This commit is contained in:
iFannJR 2026-06-02 21:58:50 +07:00
parent 4b2a9130cd
commit e68e59a169
3 changed files with 72 additions and 16 deletions

View File

@ -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;
}
}

View File

@ -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
{
//
}
};

View File

@ -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');
});
}
};