TOP メニュー

2010年3月

  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      
フォトアルバム

カテゴリー「時間割自動作成」の13件の投稿

2007年5月24日 (木)

時間割自動作成(13)

【´・ω・`】:今回はまず、サブプロシージャ、Main_Partからだ。

      まず見てくれ。

Sub Main_Part()
%Tanni_Total = Cells(13, 10)
    %i = 2
   
    For %j = 1 To 10000
        Randomize(ThisTime())            !!乱数の発生
        %X = Int(Rand() * 6 + 1)
        %Y = Int(Rand() * 6 + 1)
       
        %Tannisu = Cells(%i, 9)
      
            
        If Cells(%Y + 1, %X) = "" Then
          If Cells(%i, 9) > Cells(%i, 10) Then
            If Not Kamoku_Check(%X, %i) Then
                Cells(%Y + 1, %X) = Cells(%i, 8)
               
            End If
          End If
        End If
       
        If Cells(%i, 10) = %Tannisu Then
            
            %Limit = %Limit + Cells(%i, 10)
            %i = %i + 1
            If %Limit = %Tanni_Total Then
             Exit Sub
            End If
            
        End If
            
            
    Next
End Sub   

(●`ε´●):なんだ、プロトタイプⅡのコードとやっていることは

      同じだな。

【´・ω・`】:うん、まずPut2jikanで2時間続きの科目を書き込み、

     残りの科目を空いているところにMain_Partで書き込むだけだからな。

     一応全てのコードを掲載しておこう。

%MyRange=Range("B2:F7")
%Cnt=0
Do While %Cnt <10000
        Range("B2:F7")=%MyRange
        Put2Jikan
        Main_Part
        If Cells(13, 9) = Cells(13, 10) Then
         MsgBox("Done")
         Stop
        End If
        %Cnt =%Cnt+1
Loop
MsgBox("解が見つかりませんでした。")

Sub Main_Part()
%Tanni_Total = Cells(13, 10)

    %i = 2
   
    For %j = 1 To 10000
        Randomize(ThisTime())            
!!乱数の発生
        %X = Int(Rand() * 6 + 1)
        %Y = Int(Rand() * 6 + 1)
       
        %Tannisu = Cells(%i, 9)
      
            
        If Cells(%Y + 1, %X) = "" Then
          If Cells(%i, 9) > Cells(%i, 10) Then
            If Not Kamoku_Check(%X, %i) Then
                Cells(%Y + 1, %X) = Cells(%i, 8)
               
            End If
          End If
        End If
       
        If Cells(%i, 10) = %Tannisu Then
            
            %Limit = %Limit + Cells(%i, 10)
            %i = %i + 1
            If %Limit = %Tanni_Total Then

             Exit Sub
            End If
            
        End If
            
            
    Next
End Sub   

Private Function Kamoku_Check(%Youbi, %Kamoku) As Boolean
    !!同一曜日に同じ科目がないかチェックする
    !!同じ科目があればTrueをかえす。
   
    Kamoku_Check = False
   
    %KamokuMei = Cells(%Kamoku, 8)
    For %i = 2 To 7
        If Cells(%i, %Youbi) = %KamokuMei Then
         Kamoku_Check = True
        End If
    Next
   
End Function

Sub Put2Jikan()
               
    %Limit = 0
   
    %i = 2
   
    For %j = 1 To 1000
        Randomize(ThisTime())            !!乱数の発生
        %X = Int(Rand() * 6 + 1)
        %Y = Int(Rand() * 6 + 1)

         
        If Cells(%i, 11) = 1 Then
            If %Y = 1 Or %Y = 2 Or %Y = 3 Or %Y = 5 Then
                 If Cells(%Y + 1, %X) = "" And \\
                       Cells(%Y + 1 + 1, %X) = "" Then
                  
                     If Not Kamoku_Check(%X, %i) Then
                         Cells(%Y + 1, %X) = Cells(%i, 8)
                         Cells(%Y + 1 + 1, %X) = Cells(%i, 8)
                         %i = %i + 1
                         %Limit = %Limit + 2
                     End If
                 End If
            
                
            End If
        Else
            %i = %i + 1
        End If
        If %i = 12 Then
         Exit Sub
        End If
    Next
   

End Sub

【´・ω・`】:これで当初の目標・・・・

  • あらかじめ特定の科目を特定の曜日の特定の時間に組み込める。
  • 同じ科目を同じ日に2時間履修することの無いようにする。
  • 2時間続きの科目を設定できるようにする。

    ・・・は達成した。

サンプルファイルを用意したので試して欲しい。

使い方は・・・

  1. 科目名を設定し・・・
  2. 単位数を設定・・・(30単位になるように)・・・
  3. 二時間続きにしたい科目には1を入力・・・
  4. マクロ「時間割作成03」を実行。

snsSample011.lzhをダウンロード

三四郎マクロで時間割自動作成プログラムラムを作る・・・(終了)

2007年5月23日 (水)

時間割自動作成(12)

【´・ω・`】:下がサブプロシージャ、Put2jikanのコードだ。

(●`ε´●):2時間続きの科目を書き込むコードだったな。

【´・ω・`】:うん。

Sub Put2Jikan()
               
    %Limit = 0
   
    %i = 2
   
    For %j = 1 To 1000
        Randomize(ThisTime())            
!!乱数の発生
        %X = Int(Rand() * 6 + 1)
        %Y = Int(Rand() * 6 + 1)
       
       
       
       
        If Cells(%i, 11) = 1 Then
            If %Y = 1 Or %Y = 2 Or %Y = 3 Or %Y = 5 Then
                 If Cells(%Y + 1, %X) = "" And \\
                       Cells(%Y + 1 + 1, %X) = "" Then
                  
                     If Not Kamoku_Check(%X, %i) Then
                         Cells(%Y + 1, %X) = Cells(%i, 8)
                         Cells(%Y + 1 + 1, %X) = Cells(%i, 8)
                         %i = %i + 1
                         %Limit = %Limit + 2
                     End If
                 End If
            
                
            End If
        Else
            %i = %i + 1
        End If
        If %i = 12 Then
         Exit Sub

        End If
    Next
   

End Sub

【´・ω・`】:基本的にはプロトタイプⅡの「核になる部分」のコードと

      やっていることは変わらない。

      違いは・・・

      If %Y = 1 Or %Y = 2 Or %Y = 3 Or %Y = 5 Then

     ・・・で書き込むべき時間が1時間目、2時間目、3時間目

     あるいは5時間目になっているかをチェックする。

(●`ε´●):4時間目だと、それに続く時間が5時間目になり

      昼休みを挟むことになるので不可、6時間目だと

      それに続く時間が存在しない7時間目になってしまうので

      不可、というわけだな?

【´・ω・`】:うん、その通り。そしてさらに・・・

       If Cells(%Y + 1, %X) = "" And \\
                       Cells(%Y + 1 + 1, %X) = "" Then

      ・・・でその時間が空いているかをチェックする。

(●`ε´●):大きな違いはそれだけか?

【´・ω・`】:うん。後はサブプロシージャMain_Partが残るだけだが

     眠くなったので次回回しだ。

2007年5月20日 (日)

時間割自動作成(11)

【´・ω・`】:下が時間割自動作成マクロプロトタイプⅢの核となる部分だ。

1:  %MyRange=Range("B2:F7")
2:  %Cnt=0
3:  Do While %Cnt <10000
4:          Range("B2:F7")=%MyRange
5:          Put2Jikan
6:          Main_Part
7:          If Cells(13, 9) = Cells(13, 10) Then
8:             MsgBox("Done")
9:            Stop
10:         End If
11:         %Cnt =%Cnt+1
12: Loop
13: MsgBox("解が見つかりませんでした。")

【´・ω・`】:説明のために行番号をふっておいた。

(●`ε´●):たったの13行か?

【´・ω・`】:うん。・・・では解説しよう。

      まず、1行目。ここで初期状態の時間割表を変数%MyRangeに

      格納しておく。

(●`ε´●):初期状態?

【´・ω・`】:うん。最初にユーザはあらかじめ、いくつかの科目は

     何曜日の何時間目と・・・指定しているかもしれない。

(●`ε´●):この場合は火曜6限の「総合」と木曜6限の「LHR」の

      ことか?

【´・ω・`】:そう。なんでこんなことをするかは後ですぐわかる。

(●`ε´●):OK。それでは2行目は?

【´・ω・`】:ループカウンタの初期化だ。3行目から12行目まで

     黙っていれば10000回ループする。ここで適当に科目を

     割り振っていって、上手く割り振れればループを抜ける。

     まず、4行目で時間割表を初期状態にする・・・。

     関数Put2Jikanを呼び出して2時間続きの科目を時間割表に

     書き込む・・・。次に関数Main_Partを呼び出し、2時間続きではない

     科目を時間割表に書き込む。

     次に7行目で全ての科目を時間割表に書き込めたかをチェックして

     書き込めていれば終了、そうでなければ4行目に戻る・・・。

     1万回ループしても解が見つからなければ、その旨を表示して

     プログラムを終了する。

(●`ε´●):なるほど、書き込みに失敗した場合、時間割表にはいろいろと

      科目が書き込まれてしまっているから、それを初期状態に戻せるように

      1行目で・・・

      %MyRange=Range("B2:F7")

      ・・・としておいたのか。

【´・ω・`】:うん。プログラムの流れがだいたい、わかったと思う。次回は

     サブルーチンのPut2Jikan と  Main_Part を見てみよう。

2007年5月18日 (金)

時間割自動作成(10)

【´・ω・`】:さあ、いよいよ最終バージョン、プロトタイプⅢの公開だ。

(●`ε´●):どんな仕様だったっけ?

【´・ω・`】:仕様は以下の通りだ。

  • あらかじめ特定の科目を特定の曜日の特定の時間に組み込める。
  • 同じ科目を同じ日に2時間履修することの無いようにする。
  • 2時間続きの科目を設定できるようにする。

【´・ω・`】:今回はプロトタイプⅡに、2時間続きの科目を設定できる機能を

     付け加えた。画面は下のようになる。

Snstimetable003 *

*

*

*

使い方は・・・

  1. 科目名を設定し・・・
  2. 単位数を設定・・・(30単位になるように)・・・
  3. 二時間続きにしたい科目には1を入力・・・
  4. マクロ「時間割作成03」を実行。

サンプルファイルを用意したので試して欲しい。

snsSample011.lzhをダウンロード

2007年5月15日 (火)

時間割自動作成(9)

【´・ω・`】:下が1日に同一科目を履修しているかいないかを検査する

      関数のコードだ。

Private Function 重複検査(%曜日 , %科目 ) As Boolean
    !!同一曜日に同じ科目がないかチェックする
    !!同じ科目があればTrueをかえす。
   
    重複検査 = False
   
    %科目名 = Cells(%科目, 8)
    For %i = 2 To 7
        If Cells(%i, %曜日) = %科目名 Then
          重複検査 = True
        End If
    Next
       
   
   
End Function

(●`ε´●):で、どんな動きをするんだ?

【´・ω・`】:この関数は重複があればTRUEを、そうでなければFALSEを返す。

      まず、最初に・・・

      重複検査 = False

      ・・・・で、とにかく重複はないということにしておく。

      そして、つぎの・・・

      %科目名 = Cells(%科目, 8)

      ・・・変数科目名に検査するべき科目名を格納しておく。

      そして、次のForループで、当該曜日の1時間目から

      6時間目までを調べて、もしも重複があれば・・・

      重複検査 = True

      ・・・で関数の戻り値をTRIUEに設定し直す。

(●`ε´●):単純だな。
   

      

      

2007年5月14日 (月)

時間割自動作成(8)

【´・ω・`】:下が時間割自動作成プログラムⅡの核となる部分だ。

!!時間割自動作成プロトタイプⅡ
!!同じ日に同じ科目を入れない

!!時間割表を火・木の6限にそれぞれ総合・LHRを

!!先指定したままクリアー、
Range("B2:F6").Select()
Range("B7").Select(true)
Range("D7").Select(true)
Range("F7").Select(true)
Selections.Clear(1, false, false, false)

MsgBox("時間割を作ります")

!!ここから時間割作成

   %空欄の数 = Cells(1, 1) !!書き込むべき単位数

   %科目 = 2
   
    For %試行回数 = 1 To 1000
        Randomize(ThisTime())           !!乱数の発生
        %列 = Int(Rand()* 5) + 2
        %行 = Int(Rand() * 6) + 2
       
       
        %該当科目の単位数  = Cells(%科目, 9)  !!個々の科目の単位数
       
        If Cells(%行, %列) = "" Then
          !!同一科目の履修がなければ
          !!科目名を書き込む
            If Not 重複検査(%列,%科目) Then   
                Cells(%行, %列) = Cells(%科目, 8)
                %書き込済み科目名 = %書き込済み科目名 + 1
            End If
        End If
       
       !!科目の書き込みが指定の
    !!単位数になったら次の科目へ

        If %書き込済み科目名 = %該当科目の単位数  Then 
           %科目 =%科目 + 1
            %書き込んだ単位数  = %書き込んだ単位数  + %書き込済み科目名
            
           !!指定された単位数の合計分
            !!科目名を書き込んだら終了、

            If %書き込んだ単位数  = %空欄の数 Then
             Stop
            End If
            %書き込済み科目名 = 0
            
        End If
            
            
    Next
MsgBox("ダメポ") 

【´・ω・`】:時間割自動作成プログラムⅠと大きく違うのは

     赤字の部分だ。

(●`ε´●):赤字の部分?

【´・ω・`】:うん、そこで重複検査(%列,%科目)を呼び出して

     同じ列、つまり同じ曜日にに科目名が重複していないかを

     検査して、重複していなければ時間割に科目名を書き込むように

     している。 

(●`ε´●):単純だな。では重複検査(%列,%科目)のコードは?

【´・ω・`】:それも単純なコードだ。次回、時間割自動作成(8)で

      お見せしよう。

2007年5月13日 (日)

時間割自動作成(7)

【´・ω・`】:時間割自動作成プロトタイプⅡの公開だ。

(●`ε´●):プロトタイプⅠとどこがちがうんだ?

【´・ω・`】:Ⅰでは単にランダムに科目名を当てはめていくだけだったけど

      Ⅱでは同じ日に同じ科目を履修することがないように

      してある。

      サンプルファイルを用意したので遊んでみて欲しい。

(●`ε´●):文書マクロの「時間割作成02」を実行すればいいんだな?

【´・ω・`】:うん。

snsSample010.lzhをダウンロード

2007年5月 9日 (水)

時間割自動作成(6)

【´・ω・`】:それでは解説をしよう。まず、最初の1行・・・

      %Tanni_Total = Cells(1, 1)     !!書き込むべき単位数

      Cells(1, 1) には=CountBlank(B2:F7)が入っている。よって

      変数%Tanni_Total にはこれから、書き込むべき科目名が

      いくつあるのかが格納される。

(●`ε´●):では2行目の・・・

     %i = 2

      ・・・はなんだ?

【´・ω・`】:これは現在、何の科目名を書こうとしているのかを示す変数だ。

     %i = 2は2行目、つまり科目名が英語であることを示している。
   
(●`ε´●):この後の・・・      

      Randomize(ThisTime())             !!乱数の発生
                       %X = Int(Rand() * 5) + 2
                       %Y = Int(Rand() * 6) + 2

               ・・・は?

【´・ω・`】:ランダムに%X、%Y座標を決める。そこに科目名を

      書き込んでいくんだ・・・

      %Tannisu = Cells(%i, 9)             !!個々の科目の単位数

      ・・・%Tannisu には個々の科目の単位数を格納しておく。

      %i=2 であるなら英語の単位数だ。
    
            If Cells(%Y, %X) = "" Then    
!!科目名を書き込む
                            Cells(%Y, %X) = Cells(%i, 8)
                           %Count = %Count + 1
                  End If

      さっき、ランダムに決められた%Y・%XをもとにしてCells(%Y, %X)が

      空欄ならばそこに科目名を書き込んでいく。

(●`ε´●):%Count = %Count + 1 というのは?

【´・ω・`】:%Countにいくつ、おなじ科目名を書き込んだのかを

      記憶させておく。

      もしも%Count = %Tannisu 、つまり、

      指定された単位数だけ科目名を書き込んだなら

      %iを1増加させて次の科目の処理に移る。

(●`ε´●):変数%Limitの役割は?

【´・ω・`】:一つ一つの科目の単位数の合計だ。これが・・・

  If %Limit = %Tanni_Total Then
                Stop         !!指定された単位数の合計分、  
   End If            !!科目名を書き込んだら

・・・%Tanni_Total 、つまり書き込むべき単位数に

達したら、処理を終了する・・・。

(●`ε´●):それを・・・

      For %j = 1 To 1000 のループで1000回繰り返すというわけだな?

【´・ω・`】:うん、1000回もやれば、解が見つかるだろう・・・ということで

      特に1000回でなくてもよい。

       

For %j = 1 To 1000
                       Randomize(ThisTime())             !!乱数の発生
                       %X = Int(Rand() * 5) + 2
                      %Y = Int(Rand() * 6) + 2
       
                     %Tannisu = Cells(%i, 9)             !!個々の科目の単位数
       
                   If Cells(%Y, %X) = "" Then    !!科目名を書き込む
                            Cells(%Y, %X) = Cells(%i, 8)
                           %Count = %Count + 1
                  End If
       
                  If %Count = %Tannisu Then   !!科目の書き込みが指定の
                           %i = %i + 1          !!単位数になったら次の科目へ
                          %Limit = %Limit + %Count
                           If %Limit = %Tanni_Total Then
                                   Stop         !!指定された単位数の合計分、  
                          End If            !!科目名を書き込んだら終了 
            
                        %Count = 0
            
                     End If
                        
         Next

2007年5月 7日 (月)

時間割自動作成(5)

【´・ω・`】:時間割自動作成マクロプロトタイプⅠの解説をしようと

      思ったけどその前に・・・

(●`ε´●):なんだ、解説をするんじゃなかったのか?

【´・ω・`】:うん、そう思ったんだけど解説は次回に回して・・・

(●`ε´●):で、何をするんだ?

【´・ω・`】:うん、前のコードの変数名を日本語名にしたから

      それを見ておくれ。そうしたら、わざわざ解説をしなくても

      何をやっているかわかっちゃうかも・・・。

%空欄の数 = Cells(1, 1)     !!書き込むべき単位数
%科目 = 2
   
For %試行回数 = 1 To 1000
           Randomize(ThisTime())             !!乱数の発生
           %列 = Int(Rand() * 5) + 2
            %行 = Int(Rand() * 6) + 2
       
           %該当科目の単位数 = Cells(%科目, 9)             !!個々の科目の単位数
       
             If Cells(%行, %列) = "" Then    !!科目名を書き込む
                   Cells(%行, %列) = Cells(%科目, 8)
                    %書き込済み科目名 = %書き込済み科目名 + 1
            End If
       
           If %書き込済み科目名 = %該当科目の単位数 Then !!科目の書き込みが指定の
                    %科目 = %科目 + 1          !!単位数になったら次の科目へ
                     %書き込んだ単位数 = %書き込んだ単位数 + %書き込済み科目名
                     If %書き込んだ単位数 = %書込むべき単位数 Then
                                   Stop         !!指定された単位数の合計分、  
                   End If            !!科目名を書き込んだら終了 
            
                        %書き込済み科目名 = 0
            
           End If
                        
Next

時間割自動作成(4)

【´・ω・`】:下が時間割自動作成プロトタイプⅠの全コードだ。

      取りあえず、見ておいて欲しい。

      %Tanni_Total = Cells(1, 1)     !!書き込むべき単位数
         %i = 2
   
               For %j = 1 To 1000
                       Randomize(ThisTime())             !!乱数の発生
                       %X = Int(Rand() * 5) + 2
                      %Y = Int(Rand() * 6) + 2
       
                     %Tannisu = Cells(%i, 9)             !!個々の科目の単位数
       
                   If Cells(%Y, %X) = "" Then    !!科目名を書き込む
                            Cells(%Y, %X) = Cells(%i, 8)
                           %Count = %Count + 1
                  End If
       
                  If %Count = %Tannisu Then   !!科目の書き込みが指定の
                           %i = %i + 1          !!単位数になったら次の科目へ
                          %Limit = %Limit + %Count
                           If %Limit = %Tanni_Total Then
                                   Stop         !!指定された単位数の合計分、  
                          End If            !!科目名を書き込んだら終了 
            
                        %Count = 0
            
                     End If
                        
         Next

2007年5月 6日 (日)

時間割自動作成(3)

【´・ω・`】:サンプルファイルを開くと下の二つの表が現れる。

      (snsSample009.lzhをダウンロード

Sanshiro007

*

*

*

*

*

(●`ε´●):B2からF7のセルに科目名を割り振っていくというわけだな?

【´・ω・`】:うん。あと注意して欲しいのは一つセルに数式が埋め込まれている。

      A1に=CountBlank(B2:F7)

      ・・・だ。

      それに科目は10個ほど。単位数をキーにして降順に並んでいる。

      科目を増やすのはたいしたマクロを組むに際しては手間ではない。

      増やすならば、それに応じて数字を変えればいい。

(●`ε´●):どうして単位数をキーにして降順なんだ?

【´・ω・`】:実際に時間割作成の作業に当たった人は経験的に知っていると

      思うが、単位数の多いものからコマを組んでいった方が、作りやすいんだ。

(●`ε´●):あと、火曜日の6限にに「総合」、木曜日の6限に「LHR」がすでに

      組み込まれているようだが?

【´・ω・`】:うん。この曜日のこの時間には、この科目を・・・と既に決まっているものも

      あるから、そういう科目はあらかじめ時間割に組み込んでおけるようにしたい。

2007年5月 5日 (土)

時間割自動作成(2)

(●`ε´●):おい、くまぷー!このブログがジャストブログ トップページ

     「今週のピックアップブログ」に選ばれているぞ!!

【´・ω・`】:あ、ほんとうだ!

(●`ε´●):おまえみたいな、いい加減なやつの戯言が選ばれるとはな!!

【´・ω・`】:うん、確かに。くまぷーのブログが選ばれるなんてありがたいことだ!!

(●`ε´●):これを励みになお一層、内容を充実させないとな!!

【´・ω・`】:うん。

      さて、それでは「時間割自動作成」だが、まず、第一段階として

      ただランダムに時間割に科目を単位数分だけ当てはめていく

      というところから始めようか。

(●`ε´●):・・・ということは同じ日に同一の科目が入ることもあるし、

      2時間続きの科目を指定する機能もないということだな。

【´・ω・`】:取りあえず、下敷きとなるファイルを用意したから

      ダウンロードしておいてくれ。

snsSample009.lzhをダウンロード

2007年5月 4日 (金)

時間割自動作成(1)

 教員相手の講座で「時間割を作る」というと、たいていの場合「時間割の枠」を作ってそこに科目やら教科担当者の名前を打ち込んでハイ終わり、というものがすべてだと思います。つまり、やることはせいぜい罫線の引き方の練習ですね。それでは「教員のための三四郎活用術」でわざわざ取り上げる意味がありません。ここではあくまでも「師楽」のように時間割の自動作成を目標にします。ただ「師楽」は1式17万円もする高価なソフトです。おそらく開発費用は優に数千万円以上かかっているはずです(うっかりすると億単位かも)。さすがにくまぷーでも「師楽」並のものをちょちょいと作るというわけにはいきません(でもそれなりの開発費用をだしてくれるスポンサーが現れればがんばりますが...)。
 

 ここでは最終的には下のような機能を持った時間割プログラムを作ります。

  • あらかじめ特定の科目を特定の曜日の特定の時間に組み込める。
  • 同じ科目を同じ日に2時間履修することの無いようにする。
  • 2時間続きの科目を設定できるようにする。

 「師楽」には比べることもできないような本当にちゃちなものですが、ここでやるものをしっかりと身につけた人は根性と気合いと時間さえあれば、きっと「師楽」のような時間割作成ソフトがつくれるようになると思います。

                                         くまぷー