学校の時間割を作成するためのアルゴリズム


95

学校の時間割を作成するアルゴリズムの既知の解決策があるかどうか疑問に思っていました。基本的に、それは、与えられたクラス-サブジェクト-ティーチャーの関連付けに対して(教師とクラスの両方で)「時間分散」を最適化することです。入力で互いに関連付けられた一連のクラス、レッスンの主題、教師があり、時刻表は午前8時から午後4時の間に収まると想定できます。

そのための正確なアルゴリズムはおそらくないだろうと思いますが、誰かがそれを開発するための良い近似やヒントを知っているかもしれません。


2
すべての回答をありがとう。アルゴリズムにはさらに調査が必要なようです。私はそれを修士論文または小規模な商業的応用の良い主題と考えます。私が書いたら、ここでお知らせします;)
2010

10
StackOverflowのIan Ringroseが別の質問に言ったように、「ソフトウェアのスケジューリングにはまだ多くのPHDが必要です」。
Reed Debaets、

回答:


84

この問題はNP-Completeです。
簡単に言えば、許容可能なソリューションのリストを見つけるために、可能なすべての組み合わせを探る必要があります。さまざまな学校で問題が発生する状況の変動のため(例:教室に関して制約がありますか?、一部のクラスはサブグループに分割されることがありますか?、これは週次スケジュールですか?など)すべてのスケジューリング問題に対応するよく知られた問題クラスはありません。たぶん、ナップザック問題には、これらの問題全般と類似する要素がたくさんあります。

これが難しい問題であり、人々が永遠に解決策を模索している問題の両方であることの確認は、(主に商用の)ソフトウェアスケジューリングツールのこの(長い)リストをチェックすることです。

関係する変数の数が多いため、その最大の原因は通常、教員の希望です;-)...、可能なすべての組み合わせを列挙することを検討することは、一般的に非現実的です。代わりに、問題/ソリューションスペースのサブセットにアクセスするアプローチを選択する必要があります。
- 別の回答で引用されている遺伝的アルゴリズムは、この種のセミガイド検索を実行するのに十分に備えています(または、私見のようです)(問題は、次世代のために保持される候補の良い評価関数を見つけることです)
- グラフこのタイプの組み合わせ最適化問題では、書き換えアプローチも役立ちます。

自動スケジュール生成プログラムの特定の実装に焦点を合わせるのではなく、問題の定義のレベルで、適用できるいくつかの戦略を提案したいと思います
一般的な理論的根拠は、ほとんどの現実世界のスケジューリング問題では、表現および暗示されているすべての制約ではなく、いくつかの妥協が必要であり、完全に満たされるということです。したがって、私たちは次のことで自分自身を助けます。

  • すべての既知の制約の定義とランク付け
  • 追加の制約のセットを手動で提供して、問題のスペースを削減します。
    これは直感に反するように見えるかもしれませんが、たとえば、すべての制約を完全に満たす方法で、初期の部分的に満たされたスケジュール(たとえば、タイムスロットの約30%)を提供し、この部分的なスケジュールを不変と見なすことで、候補ソリューションの作成に必要な時間/スペース。
    追加の制約が役立つもう1つの方法は、たとえば、「人為的に」制約を追加して、特定の科目を特定の曜日に教えることを防ぐことです(これが週次スケジュールの場合...)。このタイプの制約により、通常、かなりの数の適切な候補を除外することなく、問題/ソリューションスペースが削減されます。
  • 問題の制約の一部を迅速に計算できるようにする。これは多くの場合、問題を表すために使用されるデータモデルの選択に関連しています。このアイデアは、いくつかのオプションをすばやくオプトイン(またはプルーニング)できるようにすることです。
  • 問題を再定義し、いくつかの制約を(通常はグラフの終了ノードに向かって)数回解除できるようにします。ここでの考え方は、スケジュールの最後のいくつかのスロットを埋めるための制約の一部を削除する、自動スケジュールジェネレータープログラムがスケジュール全体を完了するのをためらうのではなく、代わりに12かそれ以上のもっともらしいリストを提供することです。候補者。示されているように、人間はパズルを完了するのに適切な位置にいることが多く、通常は自動化されたロジックと共有されない情報を使用して、いくつかの制約を破る可能性があります(たとえば、「午後に数学なし」ルールは時々破られる可能性があります) 「高度な数学と物理学」クラスの場合、または「スミス先生の1つよりもジョーンズ先生の要件の1つを破る方がよい... ;-))

この回答の校正では、明確な応答を提供することは非常に恥ずかしがり屋ですが、それでもなお、実用的な提案がいっぱいです。結局のところ、これが「困難な問題」であることを助けてくれることを願っています。


1
NP-Completenessについてのヒントと言及に感謝し、素晴らしい、正確で手の込んだ回答(それも私の推測でした)。
2010

3
この問題のNPの完全性を説明する引用はありますか?
ドン

49

それは混乱です。王室の混乱。答えを追加するために、すでに非常に完全な、私は家族の経験を指摘したいと思います。私の母は教師であり、かつてその過程に関与していた。

コンピュータにそうすることは、それ自体をコーディングすることが難しいだけでなく、プリベークされたコンピュータプログラムに指定するのが難しい条件があるために難しいこともわかりました。例:

  • 先生はあなたの学校と他の研究所の両方で教えます。明らかに、彼がそこで10.30にレッスンを終了した場合、彼はあなたの施設から10.30に開始することができません。なぜなら、彼は教育機関の間で通勤するためにいくらかの時間が必要だからです。
  • 二人の先生が結婚しています。一般に、同じクラスに2人の既婚教師がいないことは良い習慣と考えられています。したがって、これらの2人の教師には2つの異なるクラスが必要です。
  • 2人の教師が結婚していて、子供は同じ学校に通っています。ここでも、2人の教師が子供がいる特定のクラスで教えることを禁止する必要があります。
  • 学校には別の施設があります。たとえば、ある日クラスが1つの研究所にあり、別の日にクラスが別の研究所にあるなどです。
  • 学校は実験室を共有していますが、これらの実験室は特定の平日にしか利用できません(セキュリティ上の理由から、たとえば追加の人員が必要な場合など)。
  • 教師の中には、休日を好む人もいます。月曜日を好む教師、金曜日を好む教師、水曜日に好む教師もいます。朝早く来ることを好む人もいれば、遅く来ることを好む人もいます。
  • 最初の1時間は歴史、次に3時間の数学、そして次の1時間の歴史など、レッスンを行うような状況は避けてください。生徒にとっても、教師にとっても意味がありません。
  • あなたは議論を均等に広げるべきです。週の最初の日を数学だけにして、残りの週を数学だけにするのは意味がありません。
  • 一部の教師は、2時間連続して評価テストを行う必要があります。

ご覧のとおり、問題はNP完全ではなく、NP狂気です。

つまり、彼らは小さなプラスチックのはめ込みを備えた大きなテーブルを備えており、満足のいく結果が得られるまではめ込みを移動します。ゼロから始めることはありません。通常、前年のタイムテーブルから始まり、調整を行います。


12
「NP-insane」-素晴らしい名前;)この問題の「現実世界」の扱いに関するコメントをありがとう、これは本当に複雑な問題であることに同意します。私の父とガールフレンドも教師であり、ほとんどの学校にプラスチック製のはめ込み式のテーブルがあることを知っています。この問題のアルゴリズムの可能性を考えるようになりました-男がそれを解決できれば、おそらく書くことができるでしょう。アルゴリズムとしてダウンします。
2010

10
あなたが書きたいのはエキスパートシステムです:ヒューリスティックなルールの束から作られたシステムです。エキスパートシステムは別として、これは遺伝的アルゴリズムが最善策の1つである分野です。問題を解決することだけでなく、問題を解決することも困難ではありません。困難は、問題とその制約を述べることにもあります。
Stefano Borini、2010

1
その通りです。問題は、満たすための複雑な条件と制約のセットを提供する必要があり、おそらく「許容可能な」ソリューションの評価が必要です。遺伝的アルゴリズムについては同意します。遺伝的アルゴリズムはこの問題にうまく適合するはずです。また、単純な条件セットで開発を開始し、正しい答えが得られたらそれを強化する方が良いと思います。
カンド

1
これらの制約と目標をMAXSATに直接直接変換することもできます。MAXSATアルゴリズムは一般に遺伝的アルゴリズムよりも信頼性が高くなりますが、数学のクラスを1週間に分散させる必要があるなどの目標のために、節が急増する場合があります。
ジュール

26

国際時間割コンペティション2007レッスンのスケジュールトラックと試験スケジュールトラックを持っていました。多くの研究者がその競争に参加した。多くのヒューリスティックスとメタヒューリスティックスが試されましたが、結局、ローカル検索メタヒューリスティックス(タブー検索やシミュレーテッドアニーリングなど)は、他のアルゴリズム(遺伝的アルゴリズムなど)よりも明らかに優れています。

ファイナリストの一部が使用した2つのオープンソースフレームワークを見てください。


17

私の半期の任務の1つは、遺伝的アルゴリズムの学校のテーブル生成でした。

テーブル全体が1つの「生物」です。一般的な遺伝的アルゴリズムのアプローチにはいくつかの変更と警告がありました:

  • ルールは「違法なテーブル」のために作られました:同じ教室での2つのクラス、同時に2つのグループを教える1人の教師など。最初の問題は、合法的な(意味がない場合)を取得しようとする一連のランダムな試行によって生成されました。致死突然変異は反復における突然変異の数にカウントされませんでした。

  • 「交換」変異は「変更」変異よりもはるかに一般的でした。変化は遺伝子の意味のある部分の間だけでした-教室で先生を代用することはありません。

  • 特定の2時間をまとめてバンドルし、同じグループに同じ汎用教室を順番に割り当て、教師の作業時間とクラスの負荷を継続的に維持するために、小さなボーナスが割り当てられました。適度なボーナスは、特定の科目の正しい教室を提供するため、クラスの時間を絆(午前または午後)内に保つためなどに割り当てられました。大きなボーナスは、与えられた主題の正しい数、教師の与えられた作業負荷などを割り当てることでした。

  • 教師は、「仕事をしたい」、「仕事をしたい」、「仕事をしたくない」、「仕事ができない」というワークロードスケジュールを作成し、適切な重みを割り当てることができます。夜間が非常に望ましくないことを除いて、24時間は合法的な労働時間でした。

  • 重み関数...そうそう。重み関数は、選択した機能とプロパティに割り当てられた重みの(乗算のように)巨大で巨大な積でした。それは非常に急勾配で、1つのプロパティは1桁上または下に簡単に変更でき、1つの生物には数百または数千のプロパティがありました。これは、重みとして絶対的に巨大な数値をもたらし、直接の結果として、計算を実行するためにbignumライブラリ(gmp)を使用する必要がありました。約10グループ、10教師、10教室の小さなテストケースの場合、最初のセットは10 ^ -200somethingで始まり、10 ^ + 300somethingで終わりました。それがより平らであるとき、それは完全に非効率的でした。また、「学校」が大きくなるほど、値ははるかに大きくなりました。

  • 時間的に計算すると、長い期間にわたる小さな人口(100)と少ない世代にわたる大きな人口(10k +)との間にほとんど違いがありませんでした。同じ時間の計算では、ほぼ同じ品質が得られました。

  • 計算(一部の1GHz CPUで)は、10 ^ + 300近くで安定するまでに1時間かかり、上記の10x10x10テストケースでは、見栄えの良いスケジュールを生成します。

  • この問題は、計算を実行しているコンピューター間で最良の標本を交換するネットワーク機能を提供することにより、簡単に並列化できます。

結果として得られたプログラムでは、学期に適した成績を収めるのに外光はまったく見られませんでした。ある程度の期待はありましたが、GUIを追加して一般ユーザーが使用できるようにするための十分な動機がありませんでした。


5
だからそれを開いて宣伝し、学者を中に入れてみませんか?今後のプロジェクトで再利用しますか?技術的には、300人のスタッフだけのプログラムは、最適なスケジュールを作成するために学校にとってお金の価値があるでしょう、そして彼らは最適なスケジュールを遺伝的に計算するために数日費やすことを気にしません。バッチ処理を考えてください。こんにちはハードウェアとソフトウェアの契約;)
jcolebrand

1
いいね!重み関数は0..1の範囲のフロートで実行できるのだろうか。
Craig McQueen、2011

1
@Craig:ランダムな変異は、育種/選択が相殺できるよりも多くのマイナスの変化をもたらしたため、平坦なものは、時間の経過とともに品質が停滞または悪化した集団を生み出します。非常に急勾配の品質関数のみが着実に成長します。確かに関数は正規化できるが、それでもなお、「一段と優れた」遺伝子は、生き残る確率が高くなければならない。
SF。

9

この問題は、見かけよりも困難です。

他の人が言及したように、これはNP完全な問題ですが、それが何を意味するかを分析してみましょう。

基本的に、それはあなたがすべての可能な組み合わせを見なければならないことを意味します。

しかし、「見て」では、何をする必要があるかはあまりわかりません。

すべての可能な組み合わせを生成するのは簡単です。大量のデータが生成される可能性がありますが、問題のこの部分の概念を理解するのにそれほど問題はないはずです。

2番目の問題は、特定の可能な組み合わせが前の「良い」ソリューションよりも良いか、悪いか、または良いかを判断することです。

このためには、単に「可能な解決策か」以上のものが必要です。

たとえば、同じ教師が週5日X週間続けて働いているのでしょうか。それが有効な解決策であったとしても、各教師がそれぞれ1週間行うように2人を交互に切り替えるよりも良い解決策ではないかもしれません。ああ、あなたはそれについて考えていませんでしたか?覚えておいてください、これはあなたが扱っている人々であり、単なるリソース割り当ての問題ではありません。

1人の教師が16週間連続してフルタイムで作業できたとしても、教師を切り替えようとするソリューションと比較して、次善のソリューションになる可能性があり、この種のバランス調整をソフトウェアに組み込むことは非常に困難です。

要約すると、この問題の適切な解決策を作成することは、多くの人々にとって多くの価値があります。したがって、分解して解決するのは簡単な問題ではありません。100%でないいくつかの目標を杭打ちし、それらを「十分に良い」と呼ぶ準備をしてください。


1
まあ、私は最初にすべての制約を知ることはかなり難しいと主張します、それは問題の経験と調査を必要とします。私はむしろ問題を2つの別々の部分に分け、それらを同時に開発したいと思います。最初は、一般的なアルゴリズムの構造です。あまりに多くの「対象ロジック」(おそらく遺伝的アルゴリズム)を使わずに、メカニズムのドラフトではなく、「次のタイムテーブル生成」を実装する方法を示します。2つ目は、タイムテーブルの「正しさ」をチェックする一連の制約を持つルールプロバイダーです。最初は単純で、後で拡張できます。
2010

8

FETに実装された私の時間割アルゴリズム(無料の時間割ソフトウェア、http://lalescu.ro/liviu/fet/、成功したアプリケーション):

アルゴリズムはヒューリスティックです。「再帰スワッピング」と名付けました。

入力:アクティビティA_1 ... A_nと制約のセット。

出力:一連の時間TA_1 ... TA_n(各アクティビティのタイムスロット。ここでは、簡略化のため、部屋は除外されています)。アルゴリズムは、制約を考慮して、各アクティビティをタイムスロットに配置する必要があります。各TA_iは0(T_1)からmax_time_slots-1(T_m)の間です。

制約:

C1)基本:同時にできないアクティビティのペアのリスト(たとえば、A_1とA_2、同じ教師または同じ生徒がいるため)。

C2)その他の多くの制約(ここでは簡単にするために除外されています)。

時間割アルゴリズム(私は「再帰的スワッピング」と名付けました):

  1. 最初に最も難しいのは、アクティビティをソートすることです。重要なステップではありませんが、アルゴリズムをおそらく10倍以上高速化します。
  2. 上記の順序に従って、許可された時間帯に各アクティビティ(A_i)を一度に1つずつ配置してみます。制約を考慮してこのアクティビティを配置できるA_iの使用可能なスロット(T_j)を検索します。さらに多くのスロットが利用可能な場合は、ランダムなスロットを選択します。何も利用できない場合は、再帰的なスワッピングを実行します。

    A。タイムスロットT_jごとに、A_iをT_jに挿入するとどうなるかを検討します。この移動に同意しない他のアクティビティのリストがあります(たとえば、アクティビティA_kは同じスロットT_jにあり、A_iと同じ教師または同じ生徒がいます)。タイムスロットT_jごとに競合するアクティビティのリストを保持します。

    b。競合するアクティビティの数が最も少ないスロット(T_j)を選択します。このスロットのアクティビティのリストに、A_p、A_q、A_rの3つのアクティビティが含まれているとします。

    c。A_iをT_jに配置し、A_p、A_q、A_rを未割り当てにします。

    d。A_p、A_q、A_rを再帰的に配置しようとします(再帰のレベルが大きすぎない場合、たとえば14であり、A_iの開始時にカウントされた再帰呼び出しの総数が多すぎない場合、たとえば2 * n)、手順2と同様)。

    e。A_p、A_q、A_rの配置が成功した場合は、成功して戻ります。それ以外の場合は、他のタイムスロットを試し(ステップ2 bに進み)、次に最適なタイムスロットを選択します。

    f。すべての(または妥当な数の)タイムスロットが失敗した場合は、成功せずに戻ります。

    g。レベル0で、A_iの配置に成功しなかった場合は、ステップ2 b)および2 c)のように配置しますが、再帰は行いません。これで、3-1 = 2のアクティビティを配置できます。ステップ2)に進みます(ここでは、サイクリングを回避するためのいくつかの方法を使用しています)。


1
FETは私にとって非常に役に立ちました。@Liviu Lalescu、ありがとう!
Noel Llevares、2014年

6

更新:コメントから...ヒューリスティックも必要です!

私はPrologを使用します...次に、RubyまたはPerlなどを使用して、ソリューションをよりきれいな形式にクリーンアップします。

teaches(Jill,math).
teaches(Joe,history).

involves(MA101,math).
involves(SS104,history).

myHeuristic(D,A,B) :- [test_case]->D='<';D='>'.
createSchedule :- findall(Class,involves(Class,Subject),Classes),
                  predsort(myHeuristic,Classes,ClassesNew),
                  createSchedule(ClassesNew,[]).
createSchedule(Classes,Scheduled) :- [the actual recursive algorithm].

私は(まだ)この問題と同様のことをしていますが、今述べたのと同じパスを使用しています。プロローグ(関数型言語として)は、実際にNP-Hard問題の解決を容易にします。


1
Prologは確かに必要な問題を表現するための優れた言語ですが、指摘したように、問題はNP-Hardでない場合でもNP-completeです。これは、Prologは実際の実装には十分高速でない可能性があることを意味します。
Poindexter、2010

3
それがNPと関係があり、近似では満足できない場合、決定論的アルゴリズムは指数関数的に次のように機能します:)
GabrielŠčerbákFeb

1
次に、目標は効果的なヒューリスティックを実装することです。たとえば、単純な9タスクスケジューリングアルゴリズムでは3.078秒で完了しますが、最小ウィンドウファーストヒューリスティックを実装すると、同じ問題は0.123秒
Reed Debaets

2
HAHA、プロローグ(単独)は決してこれを解決しません。大文字で申し訳ありませんが、10年か15年前に私は同じ考えを持っていて、完全に失敗しました。遅いというわけではありません。それは単純で実際のケースを解決できませんでした;)!
Karussell、2012年


5

ここに私が見つけたいくつかのリンクがあります:

学校の時間割 -関係するいくつかの問題をリストします

学校の時間割のためのハイブリッド遺伝的アルゴリズム

ユーティリティとツールのスケジュール


1
ユーティリティとツールのスケジュール設定のリンクは機能
Baran

@Baranウェイバックマシンを使用すると、リストが表示されます
srijanshukla 2017年


3

私はこれを正確に行う、広く使用されているスケジューリングエンジンに取り組んでいます。はい、それはNP-Completeです。最善のアプローチは、最適なソリューションを近似することです。そしてもちろん、どちらが「最良の」ソリューションであるかを示すためのさまざまな方法があります。たとえば、教師がスケジュールに満足していること、または生徒がすべてのクラスに参加していることのほうが重要ですか。

あなたが早い段階で解決する必要がある絶対的に最も重要な質問は、このシステムを別の方法よりも優れた方法でスケジュールする方法を作るものですかです。つまり、ジョーンズ夫人が8歳で数学を教え、スミス氏が9歳で数学を教えるというスケジュールがある場合、どちらも10歳で数学を教えるよりも良いですか、悪いですか。ジョーンズ先生が8歳で教え、ジョーンズ先生が2歳で教えるよりも良いですか、悪いですか?どうして?

ここで私が与える主なアドバイスは、問題を可能な限り分割することです。コースごと、教師ごと、部屋ごとなどであり、最初に副問題の解決に取り組みます。そこでは、複数のソリューションから選択する必要があり、最も可能性の高い最適なソリューションを選択する必要があります。次に、「以前の」副問題に潜在的な解決策を採点する際の後の副問題の必要性を考慮に入れるように取り組みます。次に、「有効な解決策がない」状態になったときに、塗装済みの状況から抜け出す方法に取り組みます(以前のサブ問題でこれらの状況を予測できない場合)。

ローカル検索最適化パスは、より良い結果を得るために最終回答を「磨く」ためによく使用されます。

通常、学校のスケジュールでは、リソースに制約の多いシステムを扱っています。学校は、1日の75%がラウンジにたくさんの空の部屋や教師が座っているという形で1年中過ごしていません。ソリューションが豊富な環境で最適に機能するアプローチは、必ずしも学校のスケジュールに適用できるとは限りません。


2

クラスの時間割と試験時間割の両方の商用アルゴリズムを設計しました。最初は整数プログラミングを使用しました。もう1つは、スロットスワップを選択して目的関数を最大化することに基づくヒューリスティックです。これは、進化した元の手動プロセスに非常に似ています。そのようなソリューションが受け入れられるための主なものは、すべての現実世界の制約を表す能力です。人間のタイムテーブル担当者は、ソリューションを改善する方法を見ることができません。結局のところ、アルゴリズムの部分は、データベースの準備、ユーザーインターフェイス、部屋の利用状況、ユーザーの教育などの統計情報をレポートする機能と比較して、非常に単純で実装が簡単でした。


1

一般に、制約プログラミングは、このタイプのスケジューリング問題への良いアプローチです。スタックオーバーフローとGoogleの両方で「制約プログラミング」とスケジューリングまたは「制約ベースのスケジューリング」を検索すると、いくつかの適切な参照が生成されます。不可能ではありません-線形最適化や整数最適化などの従来の最適化方法を使用する場合、考えるのは少し難しいです。1つの出力は-すべての要件を満たすスケジュールが存在しますか?それ自体が明らかに役立ちます。

幸運を !


1

はい、遺伝的アルゴリズムでそれを処理できます。しかし、すべきではありません:)。遅くなりすぎたり、パラメータの調整に時間がかかりすぎたりする場合があります。

他の成功したアプローチがあります。すべてがオープンソースプロジェクトに実装されています。

  • 制約ベースのアプローチ
    • UniTimeで実装(学校向けではない)
    • さらに進んで、整数プログラミングを使用することもできます。ウーディネ大学で成功した商用ソフトウェア(ILOG CPLEX)を使用して、とバイロイト大学(私はそこで参加しました)
    • ヒューリスティックによるルールベースのアプローチ-Droolsプランナーを参照
  • 異なるヒューリスティック-FET私自身

時間割ソフトウェア一覧はこちらをご覧ください


0

私はあなたが遺伝的アルゴリズムを使うべきだと思います:

また見てみましょう:同様の質問別の質問


0

誰もがこのコードに同意するかどうかはわかりませんが、私は自分のアルゴリズムの助けを借りてこのコードを開発し、ルビで私のために働いています。 subjectflagとTeacherflagは、対応するIDとブール値であるフラグ値を持つハッシュです。問題があれば連絡してください.......(-_-)

periodflag.each do | k2、v2 |

            if(TimetableDefinition.find(k2).period.to_i != 0)
                subjectflag.each do |k3,v3|
                    if (v3 == 0)
                        if(getflag_period(periodflag,k2))
                            @teachers=EmployeesSubject.where(subject_name: @subjects.find(k3).name, division_id: division.id).pluck(:employee_id)
                            @teacherlists=Employee.find(@teachers)
                            teacherflag=Hash[teacher_flag(@teacherlists,teacherflag,flag).to_a.shuffle] 
                            teacherflag.each do |k4,v4|
                                if(v4 == 0)
                                    if(getflag_subject(subjectflag,k3))
                                        subjectperiod=TimetableAssign.where("timetable_definition_id = ? AND subject_id = ?",k2,k3)
                                        if subjectperiod.blank?
                                            issubjectpresent=TimetableAssign.where("section_id = ? AND subject_id = ?",section.id,k3)
                                            if issubjectpresent.blank?
                                                isteacherpresent=TimetableAssign.where("section_id = ? AND employee_id = ?",section.id,k4)
                                                if isteacherpresent.blank?
                                                    @finaltt=TimetableAssign.new
                                                    @finaltt.timetable_struct_id=@timetable_struct.id
                                                    @finaltt.employee_id=k4
                                                    @finaltt.section_id=section.id
                                                    @finaltt.standard_id=standard.id
                                                    @finaltt.division_id=division.id
                                                    @finaltt.subject_id=k3
                                                    @finaltt.timetable_definition_id=k2
                                                    @finaltt.timetable_day_id=k1
                                                    set_school_id(@finaltt,current_user)
                                                    if(@finaltt.save)

                                                        setflag_sub(subjectflag,k3,1)
                                                        setflag_period(periodflag,k2,1)
                                                        setflag_teacher(teacherflag,k4,1)
                                                    end
                                                end
                                            else
                                                @subjectdetail=TimetableAssign.find_by_section_id_and_subject_id(@section.id,k3)
                                                @finaltt=TimetableAssign.new
                                                @finaltt.timetable_struct_id=@subjectdetail.timetable_struct_id
                                                @finaltt.employee_id=@subjectdetail.employee_id
                                                @finaltt.section_id=section.id
                                                @finaltt.standard_id=standard.id
                                                @finaltt.division_id=division.id
                                                @finaltt.subject_id=@subjectdetail.subject_id
                                                @finaltt.timetable_definition_id=k2
                                                @finaltt.timetable_day_id=k1
                                                set_school_id(@finaltt,current_user)
                                                if(@finaltt.save)

                                                    setflag_sub(subjectflag,k3,1)
                                                    setflag_period(periodflag,k2,1)
                                                    setflag_teacher(teacherflag,k4,1)
                                                end
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
        end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.