#include <stdio.h>
#include <stdlib.h>
// Struktur untuk merepresentasikan setiap barang
typedef struct {
int id; // Nomor identitas barang
float bobot; // Bobot barang
float nilai; // Nilai barang
float rasio; // Rasio Nilai/Bobot (nilai/bobot)
} Barang;
// Fungsi perbandingan untuk qsort. Mengurutkan barang berdasarkan Rasio secara MENURUN.
int bandingkan_barang(const void *a, const void *b) {
Barang *barang_a = (Barang *)a;
Barang *barang_b = (Barang *)b;
// Logika pengurutan menurun: jika rasio A < rasio B, A harus diletakkan setelah B (return 1).
if (barang_a->rasio < barang_b->rasio) {
return 1;
} else if (barang_a->rasio > barang_b->rasio) {
return -1;
} else {
return 0;
}
}
// Fungsi utama untuk menyelesaikan masalah Rational Knapsack
float knapsack_rational(Barang barang[], int jumlah_barang, float kapasitas_maks) {
// 1. Urutkan barang berdasarkan rasio Nilai/Bobot secara menurun (Strategi Greedy)
qsort(barang
, jumlah_barang
, sizeof(Barang
), bandingkan_barang
);
float total_nilai = 0.0;
float sisa_kapasitas = kapasitas_maks;
printf("--- Proses Pengambilan Barang Berdasarkan Rasio (Greedy) ---\n"); printf("| No. | Bobot | Nilai | Rasio | Sisa Kps | Aksi |\n"); printf("----------------------------------------------------------\n");
// 2. Proses pengambilan barang
for (int i = 0; i < jumlah_barang; i++) {
if (sisa_kapasitas <= 0) {
break; // Ransel penuh, hentikan iterasi
}
printf("| %-3d | %-5.1f | %-5.1f | %-5.2f | %-8.2f | ", barang[i].id, barang[i].bobot, barang[i].nilai, barang[i].rasio, sisa_kapasitas);
if (barang[i].bobot <= sisa_kapasitas) {
// Ambil seluruh barang
total_nilai += barang[i].nilai;
sisa_kapasitas -= barang[i].bobot;
printf("Ambil SELURUH (Nilai +%.2f) |\n", barang
[i
].
nilai); } else {
// Ambil sebagian (fraksi) barang
float fraksi = sisa_kapasitas / barang[i].bobot;
float nilai_diambil = fraksi * barang[i].nilai;
total_nilai += nilai_diambil;
sisa_kapasitas = 0; // Ransel terisi penuh oleh fraksi ini
printf("Ambil FRAKSI (%.2f) (Nilai +%.2f) |\n", fraksi
, nilai_diambil
); }
}
printf("----------------------------------------------------------\n");
return total_nilai;
}
int main() {
// --- KASUS UJI (Contoh data, GANTI dengan data dari buku Anda) ---
// Barang-barang dengan Bobot (kg) dan Nilai (Rp)
float Bobot[] = {10.0, 20.0, 30.0};
float Nilai[] = {60.0, 100.0, 120.0};
float KAPASITAS_RANSEL = 50.0;
int JUMLAH_BARANG = sizeof(Bobot) / sizeof(Bobot[0]);
// Inisialisasi dan pengisian data ke dalam array struktur Barang
Barang daftar_barang[JUMLAH_BARANG];
for (int i = 0; i < JUMLAH_BARANG; i++) {
daftar_barang[i].id = i + 1;
daftar_barang[i].bobot = Bobot[i];
daftar_barang[i].nilai = Nilai[i];
daftar_barang[i].rasio = Nilai[i] / Bobot[i];
}
printf("--- Rasional Knapsack Problem (Informatika Kelas 11) ---\n"); printf("Kapasitas Ransel: %.2f kg\n\n", KAPASITAS_RANSEL
);
// Panggil fungsi utama Knapsack
float hasil_optimal = knapsack_rational(daftar_barang, JUMLAH_BARANG, KAPASITAS_RANSEL);
printf("\n=============================================\n"); printf("NILAI TOTAL OPTIMAL yang dapat dicapai: Rp%.2f\n", hasil_optimal
); printf("=============================================\n");
return 0;
}