Saya seorang tutor praktikum di universitas, berdasarkan komentar siswa tahun lalu, kami ingin, bos saya dan saya, untuk mengatasinya. Bos saya memilih untuk menulis skrip C dan saya memilih python (python-constraint) untuk mencoba menyelesaikan masalah kita.
Informasi
- Ada 6 sesi
- Ada 4 peran
- Ada 6 praktik
- Ada 32 siswa
- Ada 4 siswa per tim
Masalah:
Tugasi setiap siswa ke 4 peran, dalam 4 praktik dalam 4 sesi yang berbeda.
Kendala:
- Siswa harus berperan sekali
- Siswa harus melakukan 4 praktik berbeda dari 6
- Siswa harus melakukan hanya satu latihan per sesi
- Siswa harus bertemu pasangan yang sama hanya sekali
Templat:
Inilah templat yang saya rasakan dengan siswa, di mana setiap tim terdiri dari 4 siswa, posisi [0, 1, 2 atau 3] adalah peran yang diberikan kepada mereka. Setiap posisi yang tersedia diberi nomor dari 1 hingga 128
[# Semester
[ # Session
[ # Practice/Team
1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24]],
[[25, 26, 27, 28],
[29, 30, 31, 32],
[33, 34, 35, 36],
[37, 38, 39, 40],
[41, 42, 43, 44],
[45, 46, 47, 48]],
[[49, 50, 51, 52],
[53, 54, 55, 56],
[57, 58, 59, 60],
[61, 62, 63, 64],
[65, 66, 67, 68],
[69, 70, 71, 72]],
[[73, 74, 75, 76],
[77, 78, 79, 80],
[81, 82, 83, 84],
[85, 86, 87, 88],
[89, 90, 91, 92],
[93, 94, 95, 96]],
[[97, 98, 99, 100],
[101, 102, 103, 104],
[105, 106, 107, 108],
[109, 110, 111, 112]],
[[113, 114, 115, 116],
[117, 118, 119, 120],
[121, 122, 123, 124],
[125, 126, 127, 128]]]
Dengan kata lain :
Ini adalah sesi:
[[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24]],
Tim-tim itu melakukan latihan yang sama:
[
[1, 2, 3, 4],
[25, 26, 27, 28],
[49, 50, 51, 52],
[73, 74, 75, 76],
[97, 98, 99, 100],
[113, 114, 115, 116]
]
Posisi itu melakukan peran yang sama:
[
1,
5,
9,
13,
17,
21,
25,
...
]
Apa yang saya miliki sejauh ini:
Menggunakan python-constraint, saya dapat memvalidasi tiga kendala pertama:
Valid solution : False
- sessions : [True, True, True, True, True, True]
- practices : [True, True, True, True, True, True]
- roles : [True, True, True, True]
- teams : [False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False]
Bagi mereka yang mungkin menarik, saya cukup melakukan ini:
Untuk setiap kondisi saya menggunakan AllDifferentConstraint . Misalnya, untuk satu sesi saya lakukan:
problem.addConstraint(AllDifferentConstraint(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])
Saya tidak dapat menemukan cara untuk membatasi tim, upaya terakhir saya secara keseluruhan semester
adalah ini:
def team_constraint(self, *semester):
students = defaultdict(list)
# get back each teams based on the format [# Semester [ #Session [# Practice/Team ...
teams = [list(semester[i:i+4]) for i in range(0, len(semester), 4)]
# Update Students dict with all mate they work with
for team in teams:
for student in team:
students[student] += [s for s in team if s != student]
# Compute for each student if they meet someone more than once
dupli = []
for student, mate in students.items():
dupli.append(len(mate) - len(set(mate)))
# Loosly constraint, if a student meet somone 0 or one time it's find
if max(dupli) >= 2:
print("Mate encounter more than one time", dupli, min(dupli) ,max(dupli))
return False
pprint(students)
return True
Pertanyaan:
- Apakah mungkin untuk melakukan apa yang saya inginkan untuk kondisi tim? Maksud saya adalah saya tidak tahu apakah mungkin untuk menetapkan 12 pasangan untuk setiap siswa dan masing-masing dari mereka bertemu pasangan yang sama hanya sekali.
- Untuk batasan tim, apakah saya kehilangan algoritma yang lebih berkinerja?
- Adakah yang bisa saya ikuti?
sumber
(4, 4)
alih-alih(4, 6)
seperti yang lain?Jawaban:
Pertanyaan utama akan dijawab dengan sesuatu seperti ...
Menambahkan Edit
Saya melihat lagi masalah Anda kemarin - (memang tidak lama, karena saya punya banyak pekerjaan saat ini), dan ...
Pertama-tama, saya melihat bahwa entitas 'tim' Anda, adalah apa yang saya sebut entitas 'aksi', dan dalam retrospeksi saya pikir 'tim' (atau 'grup') adalah kata yang lebih baik untuk itu.
Jika Anda masih menemukan kendala sulit, saya sarankan Anda memecahkannya, dan mengatasinya secara individual - terutama kendala tim / orang / sesi, diikuti oleh kendala peran / tugas.
/ Ditambahkan Edit
Saya memiliki masalah yang sama baru-baru ini, dan pada akhirnya beralih ke OR-tools. https://developers.google.com/optimization/cp/cp_solver
Khususnya, lihat masalah penjadwalan perawat: https://developers.google.com/optimization/scheduling/employee_scheduling#nurse_scheduling
Bagaimanapun, masalahnya tidak terlalu rumit, jadi mungkin menggunakan pemecah akan terlalu banyak untuk Anda.
Demikian juga, untuk masalah semacam ini, mungkin lebih baik menggunakan dikt kunci tuple untuk menampung variabel Anda, daripada daftar bersarang:
{Tim, Sesi, Orang: BoolVar}
Alasan utamanya adalah Anda kemudian dapat menerapkan kendala melalui filter, yang jauh lebih mudah daripada harus melakukan manipulasi daftar bersarang, misalnya, untuk menerapkan kendala di seluruh orang / tim, Anda dapat melakukannya (di mana orang diindeks 2 dan tim diindeks 0):
sumber
p for p in all_people
?Hanya ide algoritme permutasi, untuk setiap iterasi dapat difokuskan pada satu dari setiap siswa atau dalam satu dari setiap sesi:
Di sini siswa 2 mengambil tempat siswa 1 di sesi 1 dan berlanjut seperti ini
Lanjutkan dengan siswa 1 S3 R 1234 St 10,9,1,8
Pada akhirnya Anda menghapus interaksi untuk siswa 1, seperti pada permutasi untuk iterasi berikutnya yang Anda hapus saat ini.
Ini seperti kubus rubiks.
Jika Anda mendapatkan kode ini atau mengetahui beberapa kode dengan algo ini, beri tahu saya.
Mungkin dengan permutasi itertools
Sesi lebih dari praktik saya percaya tidak relevan dengan jumlahnya. Hanya beberapa kolam untuk mengambil lebih banyak ketika Anda kehabisan atau lebih banyak ruang untuk rotasi. Mungkin bisa menyederhanakan masalah yang pertama bertujuan untuk 4 sesi = praktik?
sumber