割り当てシミュレーションの実行は、最初の実行後に繰り返し壊れます

StackOverflow https://stackoverflow.com/questions/2910240

  •  04-10-2019
  •  | 
  •  

質問

バックグラウンド
私には、それぞれのプロジェクトの学生、彼らの望ましいプロジェクト、監督者がたくさんいます。私は一連のシミュレーションを実行して、学生が最終的にどのプロジェクトにするかを確認します。これにより、フィードバックに必要な有用な統計を取得できます。したがって、これは本質的にです Monte-Carlo シミュレーションでは、生徒のリストをランダムにしてから、それを繰り返し、リストの最後に達するまでプロジェクトを割り当てます。その後、プロセスが再び繰り返されます。

1回のセッション内で、プロジェクトの割り当てが成功した後、次のことが行われることに注意してください。
+プロジェクトはに設定されています allocated そして、他の学生に与えることはできません
+スーパーバイザーには固定があります quota 彼が監督できる学生の。これは1によって減少します
+一度 quota ヒット0、その監督者からのすべてのプロジェクトは blocked そして、これはプロジェクトがあるのと同じ効果を持っています allocated

コード

def resetData():
    for student in students.itervalues():
        student.allocated_project = None

    for supervisor in supervisors.itervalues():
        supervisor.quota = 0

    for project in projects.itervalues():
        project.allocated = False
        project.blocked = False

の役割 resetData() データの特定のビットを「リセット」することです。たとえば、プロジェクトが正常に割り当てられた場合、 project.allocated そのプロジェクトは反転します True. 。それは1回の実行に役立ちますが、次のランでは扱いを受ける必要があります。

上記の3つの辞書を繰り返しています - それぞれ学生、プロジェクト、監督者向けに、情報が保存されています。

次のビットは、割り当てアルゴリズムの「モンテカルロ」シミュレーションです。

sesh_id = 1

for trial in range(50):

    for id in randomiseStudents(1):
        stud_id = id
        student = students[id]
        if not student.preferences:
        # Ignoring the students who've not entered any preferences

            for rank in ranks:
                temp_proj = random.choice(list(student.preferences[rank]))

                if not (temp_proj.allocated or temp_proj.blocked):
                    alloc_proj = student.allocated_proj_ref = temp_proj.proj_id
                    alloc_proj_rank = student.allocated_rank = rank
                    successActions(temp_proj)
                    temp_alloc = Allocated(sesh_id, stud_id, alloc_proj, alloc_proj_rank)
                    print temp_alloc # Explained
                    break                  
    sesh_id += 1
    resetData()  # Refer to def resetData() above

全て randomiseStudents(1) は、学生の順序をランダム化することです。

Allocated そのように定義されているクラスは次のとおりです。

class Allocated(object):
    def __init__(self, sesh_id, stud_id, alloc_proj, alloc_proj_rank):
        self.sesh_id = sesh_id
        self.stud_id = stud_id
        self.alloc_proj = alloc_proj
        self.alloc_proj_rank = alloc_proj_rank

   def __repr__(self):
        return str(self)

   def __str__(self):
        return "%s - Student: %s (Project: %s - Rank: %s)" %(self.sesh_id, self.stud_id, self.alloc_proj, self.alloc_proj_rank)

Output and problem

これを実行すると、このような出力が得られます(切り捨てられます):

1 - Student: 7720 (Project: 1100241 - Rank: 1)
1 - Student: 7832 (Project: 1100339 - Rank: 1)
1 - Student: 7743 (Project: 1100359 - Rank: 1)
1 - Student: 7820 (Project: 1100261 - Rank: 2)
1 - Student: 7829 (Project: 1100270 - Rank: 1)
.
.
.
1 - Student: 7822 (Project: 1100280 - Rank: 1)
1 - Student: 7792 (Project: 1100141 - Rank: 7)
2 - Student: 7739 (Project: 1100267 - Rank: 1)
3 - Student: 7806 (Project: 1100272 - Rank: 1)
.
.
.
45 - Student: 7806 (Project: 1100272 - Rank: 1)
46 - Student: 7714 (Project: 1100317 - Rank: 1)
47 - Student: 7930 (Project: 1100343 - Rank: 1)
48 - Student: 7757 (Project: 1100358 - Rank: 1)
49 - Student: 7759 (Project: 1100269 - Rank: 1)
50 - Student: 7778 (Project: 1100301 - Rank: 1)

基本的に、それは最初の実行で完全に機能しますが、その後の実行では nこの場合、走行すると、1人の学生プロジェクト割り当てペアのみが返されます。

したがって、私が問題を抱えている主な問題は、特に最初の実行がスムーズに機能するため、この異常な挙動を引き起こしているものを把握することです。

前もって感謝します、

AZ

役に立ちましたか?

解決

スーパーバイザーのクォータを0に設定するつもりですか resetData()?それは彼らのすべてのプロジェクトが現在ブロックされているということではないでしょうか?

レイヴンをquoth:

監督者は、監督できる学生の固定クォータを持っています。これは1によって減少します。クォータが0になると、その監督者からのすべてのプロジェクトがブロックされ、これはプロジェクトが割り当てられるのと同じ効果があります。

そうでない場合は、の出力を確認する必要があります randomiseStudents() 完全なリストを返していることを確認します。結局のところ、それはその内側のループの制御アイテムです。


コメントに基づく更新:

問題のように見えます だった スーパーバイザーのクォータを0に設定していたため、すべてのプロジェクトがブロックされたことを示しています。

これは私の側の純粋な推測ですが、すべての監督者のチェックが割り当ての後に起こったため、おそらく各反復で1人の学生を出したでしょう。その場合、割り当てられたばかりのものは-1の割り当てがあり、他のすべてのクォータは0になり、効果的に停止します すべて その後の割り当て。

理想的には、監督者のクォータを元の値に戻したいと思います resetData(). 。固定クォータ(スーパーバイザーごとに同じ)である場合、単に使用できます。

for supervisor in supervisors.itervalues():
    supervisor.quota = 7 # for example

各スーパーバイザーに別の割り当てがあった場合、他の情報と一緒に(初期化中ではなくリセットしない)とともに保存する必要があります。 supervisor.start_quota. 。その後、使用できます。

for supervisor in supervisors.itervalues():
    supervisor.quota = supervisor.start_quota
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top