Commit
•
24baecc
1
Parent(s):
afaea99
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
from ortools.linear_solver import pywraplp
|
4 |
+
import random
|
5 |
+
import numpy as np
|
6 |
+
import base64
|
7 |
+
from base64 import b64encode
|
8 |
+
from io import BytesIO
|
9 |
+
|
10 |
+
# Fungsi untuk menyelesaikan Knapsack Problem
|
11 |
+
def knapsack_solver(df, max_price, max_weight, min_rating):
|
12 |
+
solver = pywraplp.Solver.CreateSolver('SCIP')
|
13 |
+
|
14 |
+
# Menambahkan variabel biner untuk setiap produk
|
15 |
+
x = {}
|
16 |
+
for i in range(len(df)):
|
17 |
+
x[i] = solver.BoolVar('x[%i]' % i)
|
18 |
+
|
19 |
+
# Menetapkan fungsi tujuan (maksimalkan total rating)
|
20 |
+
objective = solver.Objective()
|
21 |
+
for i in range(len(df)):
|
22 |
+
objective.SetCoefficient(x[i], df['Rating'].iloc[i])
|
23 |
+
objective.SetMaximization()
|
24 |
+
|
25 |
+
# Menetapkan batasan harga, berat, dan minimal rating
|
26 |
+
price_constraint = solver.Constraint(0, max_price)
|
27 |
+
weight_constraint = solver.Constraint(0, max_weight)
|
28 |
+
rating_constraint = solver.Constraint(min_rating, solver.infinity())
|
29 |
+
|
30 |
+
for i in range(len(df)):
|
31 |
+
price_constraint.SetCoefficient(x[i], df['Price'].iloc[i])
|
32 |
+
weight_constraint.SetCoefficient(x[i], df['Weight'].iloc[i])
|
33 |
+
rating_constraint.SetCoefficient(x[i], df['Rating'].iloc[i])
|
34 |
+
|
35 |
+
# Menetapkan batasan minimal satu produk dipilih untuk setiap kategori
|
36 |
+
categories = df['Product_Category'].unique()
|
37 |
+
for category in categories:
|
38 |
+
category_df = df[df['Product_Category'] == category]
|
39 |
+
category_constraint = solver.Constraint(1, solver.infinity()) # Minimal satu produk yang dipilih
|
40 |
+
for i in range(len(category_df)):
|
41 |
+
category_constraint.SetCoefficient(x[df.index.get_loc(category_df.index[i])], 1)
|
42 |
+
|
43 |
+
# Menyelesaikan masalah
|
44 |
+
solver.Solve()
|
45 |
+
|
46 |
+
# Menyimpan hasil ke dalam DataFrame baru
|
47 |
+
selected_products = pd.DataFrame(columns=df.columns)
|
48 |
+
for i in range(len(df)):
|
49 |
+
if x[i].solution_value():
|
50 |
+
selected_products = pd.concat([selected_products, df.iloc[[i]]], ignore_index=True)
|
51 |
+
|
52 |
+
return selected_products
|
53 |
+
|
54 |
+
# Load data
|
55 |
+
df = pd.read_excel('OutputAspoo.xlsx')
|
56 |
+
dataset = df[['kota_nama','nama_barang','harga_umum','name','kategori']]
|
57 |
+
num_records = len(dataset)
|
58 |
+
data = {
|
59 |
+
'Rating': np.random.uniform(low=3.0, high=5.0, size=num_records).round(2),
|
60 |
+
'Weight': np.random.uniform(low=0.1, high=2.0, size=num_records).round(2),
|
61 |
+
}
|
62 |
+
|
63 |
+
|
64 |
+
#Preprocessing data
|
65 |
+
data_rating = pd.DataFrame(data)
|
66 |
+
dataset_final = dataset.join(data_rating)
|
67 |
+
dataset_final.rename(columns={'kategori':'Product_Category','nama_barang': 'Item', 'harga_umum': 'Price'}, inplace=True)
|
68 |
+
dataset_final = dataset_final.dropna()
|
69 |
+
dataset_final['Price'] = dataset_final['Price'].astype(int).astype(float)
|
70 |
+
dataset_final['Price'] = dataset_final['Price'].div(1000)
|
71 |
+
|
72 |
+
|
73 |
+
# Tampilan Streamlit
|
74 |
+
st.title('Aplikasi Rekomendasi Parcell ASPOO')
|
75 |
+
|
76 |
+
# Input field untuk memasukkan kota
|
77 |
+
selected_city = st.selectbox('Pilih Nama Kota', df['kota_nama'].unique())
|
78 |
+
|
79 |
+
# Input field untuk batasan harga, berat, dan minimal rating
|
80 |
+
max_price = st.number_input('Batasan Harga Maksimal (... ribu)', min_value=0, value=200)
|
81 |
+
max_weight = st.number_input('Batasan Berat Maksimal (... kg)', min_value=0, value=10)
|
82 |
+
min_rating = st.number_input('Minimal Rating', min_value=0, max_value=5, value=4)
|
83 |
+
|
84 |
+
# Tombol untuk memproses
|
85 |
+
if st.button('Proses'):
|
86 |
+
# Filter berdasarkan kota yang dimasukkan
|
87 |
+
df_kota = dataset_final.loc[dataset_final['kota_nama']==selected_city]
|
88 |
+
df_kota_final = df_kota[['name','Item','Price','Product_Category','Rating','Weight']]
|
89 |
+
|
90 |
+
# Memanggil fungsi knapsack_solver
|
91 |
+
result_df = knapsack_solver(df_kota_final, max_price, max_weight, min_rating)
|
92 |
+
|
93 |
+
# Menampilkan hasil
|
94 |
+
st.markdown('### Hasil Rekomendasi Parcell ASPOO')
|
95 |
+
renamed_columns = {
|
96 |
+
'name': 'Nama Produk',
|
97 |
+
'Item': 'Barang',
|
98 |
+
'Price': 'Harga',
|
99 |
+
'Product_Category': 'Kategori Produk',
|
100 |
+
'Rating': 'Rating',
|
101 |
+
'Weight': 'Berat'
|
102 |
+
}
|
103 |
+
result_df.rename(columns=renamed_columns, inplace=True)
|
104 |
+
st.write(result_df)
|
105 |
+
|
106 |
+
# Menyimpan hasil ke dalam file CSV
|
107 |
+
st.markdown('### Unduh Hasil Rekomendasi Parcell ASPOO')
|
108 |
+
result_df.reset_index().drop("index", axis = 1, inplace = True)
|
109 |
+
csv = result_df
|
110 |
+
csv_download = csv.to_csv(index=False)
|
111 |
+
href = f'<a href="data:file/csv;base64,{b64encode(csv_download.encode()).decode()}" download="hasil_parcell_ASPOO2023.csv">Unduh File</a>'
|
112 |
+
st.markdown(href, unsafe_allow_html=True)
|