Last active
July 6, 2024 14:11
-
-
Save tarekeldeeb/e8630ce38876fbcd5942a7d371c03665 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Blog post: https://tarekeldeeb.github.io/quran-table-for-moqantereen | |
------------------ | |
Problem Definition | |
------------------ | |
Try to find the optimal Sura words distribution among a given number of days with the following constraints: | |
- Each day should have 1000+ aya (Days 6 or less) | |
- The difference of word counts at each day is minimal | |
This is basically a https://en.wikipedia.org/wiki/Multiway_number_partitioning Problem (NP-hard) | |
The result is populated in https://docs.google.com/spreadsheets/d/1xGWmfp1Ucinxae14whkBmOaPAktFOnryAXB95CvYEAo | |
""" | |
from copy import deepcopy | |
from pulp import * | |
number_days = 3 #Valid Numbers 6-3 | |
## | |
# Quran Data is compiled based on: https://github.com/tarekeldeeb/quranquiznet/blob/master/www/_model_/utils.js | |
# which is further based on https://tanzil.net/download/ dataset | |
# | |
sura_name = ['البقرة','آلعمران','النساء','المائدة','الأنعام','الأعراف','الأنفال','التوبة','يونس', | |
'هود','يوسف','الرعد','إبراهيم','الحجر','النحل','الإسراء','الكهف','مريم','طه','الأنبياء','الحج', | |
'المؤمنون','النور','الفرقان','الشعراء','النمل','القصص','العنكبوت','الروم','لقمان','السجدة', | |
'الأحزاب','سبأ','فاطر','يس','الصافات','ص','الزمر','غافر','فصلت','الشورى','الزخرف','الدخان', | |
'الجاثية','جزء الأحقاف','جزء الذاريات','جزء قد سمع','جزء تبرك','جزء عم'] | |
sura_words = [ | |
6120,3485,3751,2808,3054,3324,1237,2498,1837,1921,1781,857,834,659,1848,1560,1583,965,1339, | |
1173,1278,1054,1320,897,1322,1155,1434,980,821,550,376,1291,887,779,729,865,737,1176,1223, | |
798,864,834,350,492,2482,2706,2654,2705,2455 | |
] | |
sura_ayahs = [ | |
286,200,176,120,165,206,75,129,109,123,111,43,52,99,128,111,110,98, | |
135,112,78,118,64,77,227,93,88,69,60,34,30,73,54,45,83,182,88,75,85, | |
54,53,89,59,37,165,429,137,431,564] | |
def lists_to_dict(keys, values): | |
dict_ = {} # using naive method to convert lists to dictionary | |
for key in keys: | |
for value in values: | |
dict_[key] = value | |
values.remove(value) | |
break | |
return dict_ | |
dict_words = lists_to_dict(sura_name, deepcopy(sura_words)) | |
dict_ayahs = lists_to_dict(sura_name, deepcopy(sura_ayahs)) | |
prob = LpProblem("Moqantareen-Problem", LpMaximize) | |
parts = range(number_days) | |
items = range(len(sura_name)) | |
min_value = LpVariable("min_value", cat=LpContinuous) | |
vars = [ | |
[LpVariable(f"x_{item}_{part}", lowBound=0, upBound=1, cat=LpBinary) | |
for part in parts] | |
for item in items | |
] # vars[i][j] is 1 iff item i is in part j. | |
prob += min_value # Objective function: maximize min_value | |
for item in items: # Constraints: each item must be in exactly one part. | |
prob += (lpSum([vars[item][part] for part in parts]) == 1) | |
for part in parts: # Constraint: the sum of each part must be at least min_value (by definition of min_value). | |
prob += (min_value <= pulp.lpSum([vars[item][part]*dict_words[sura_name[item]] for item in items])) | |
prob += (1000 <= pulp.lpSum([vars[item][part]*dict_ayahs[sura_name[item]] for item in items])) | |
pulp.PULP_CBC_CMD(timeLimit=100).solve(prob) | |
# The status of the solution is printed to the screen | |
print("Status:", LpStatus[prob.status]) | |
# Each of the variables is printed with it's resolved optimum value | |
res = [-1]*len(sura_name) | |
for v in prob.variables(): | |
if v.varValue == 1.0: | |
tok = v.name.split('_') | |
#print(sura_name[int(tok[1])], ' ==> ', (int(tok[2])+1)) | |
res[int(tok[1])] = int(tok[2])+1 | |
print(res) | |
print("يمكنك نسخ القيم الاخيرة في الجدول") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
بارك الله فيك وكتب اجر من صلى بهذه التقسيم الرائع وجزاك الله خبر