EXCELワークシート関数で不完全な迷路を作る

 ドルアーガの塔みたいに柱1本に対し壁1枚を置くような迷路を作る、という思い付きです。最近の新しい関数を使うと割と簡潔になりますが、きちんとしたものを作るのはやはり難しいのであります。

 まずはC1セルに次のように入力します。

=CHOOSE(MOD(ROW(),2)+MOD(COLUMN(),2)+1,RANDBETWEEN(1,4),IF(OR(C4=1,B3=2,C2=3,D3=4),-1,0),0)

f:id:accs2014:20190118155646p:plain:w600
 補足です。
 行番号、列番号がともに偶数番(D4など)のセルは「柱」として、そこから生じる壁の向きをRANDBETWEEN関数で定めます(1なら左、など)。
 行番号、列番号がともに奇数番(E5など)のセルは通常の通路として0を記します。
 それ以外のセルは壁になり得るセルとして、周囲の「柱」の値によって0(通路)か-1(壁)を記します。


 そして0以外のセルを塗りつぶす条件付き書式を設定します。
f:id:accs2014:20190118155643p:plain:w600


 あとはドラッグして完成です;-o-)
f:id:accs2014:20190118155636p:plain:w600


 せっかくですのでさらにドラッグしてさらに拡大。
f:id:accs2014:20190118155631p:plain:w600
 さてお気づきのとおり、この迷路には「周回路が発生する(外周に届かない壁が発生する)」「密室が発生する(迷路が壁で分割されるというケースもあり得ます)」という迷路としての大きな欠陥があります。
 しかし作成方法の性質上(とっかかりが簡単なのと引き換えに)大域的な制約をかけるのがド難しいため解決は困難です。手動で直す前提なら少しは役に立つかもしれません;-o-)

サーチコンソールで「AMP 推奨サイズより大きい画像を指定してください」の警告を受けた

 何の気なしにサーチコンソールを開きましたら標記のメッセージが届いていました。
 メインブログに対するものでしたが、どうも「記事の見出し画像のサイズをもっとデカいものにしろ」という要請らしいです。
 とはいえ画像は全部スクリーンショットですので元画像を拡大保存しなければ訂正できません。しかも対象件数が200件近くあり面倒すぎるうえ、メッセージのレベルが「警告」であることにビビったので、念のためAMP配信を停止しました。
 ほとんどPCからの流入なのでたいした影響はないと思いますが、それにしてもなぜわざわざ重くなるような変更を強いるのか;-o-)

読者数が30人に到達しました

 またもメインブログの方ですけども、はてなProにしてから苦節2年半でやっと読者数が30人に到達しました。
 ほとんどが検索流入、しかも恐らくは事業所からのアクセスで成り立っているブログですので読者数自体はさほど気にする必要もないんでしょうけども、やはり増えると嬉しいということで、この場にてお礼を申し上げます。
 一時はAccess2019の発売も危ぶまれる状況でしたが何とか出ましたし、まあPublisher(機会があってちょっと調べましたがびっくりするほど情報がない)も出るくらいですから当分はAccessが無くなるということはなさそうです。敷居はちょっと高いですがとても便利で面白いソフトですので、この素晴らしさを広めるべく今後も細々やっていきたいと思います。引き続きよろしくお願いします_ _)

ナップサック問題をEXCEL VBAで解く

 こないだの記事の続きというか焼き直しです。

www.yomogi2017.xyz

 扱うのは同じ「0-1ナップサック問題」で、詳細を再掲します。

  • 価値、重量がそれぞれ異なるアイテムがいくつかあり、定められた上限重量以内で価値が最大になるようにアイテムを選択する
  • 1つのアイテムを分割したり2回以上選択することはできない
  • 重量は整数とする

 解法も同様に動的計画法とします。


f:id:accs2014:20190115175904p:plain:right:w400

 ではやってみます。
 まずはワークシート。

入力部
 上限重量入力欄……B4
 アイテム価値/重量入力欄……B8:C107
 (ただし下記のコードは価値と重量の両方が入力されている限り、アイテムが100個を超えても処理します)
出力部
 価値総和表示欄……E4
 個々のアイテムの要否判定表示欄……E8:E107
 (ただし下記のコードはアイテムが100個を超えても表示します)

f:id:accs2014:20190115175901p:plain:right:w450

 あとは次のようなコードを標準モジュールに入力してドンと実行すればOK。
 やっぱりこっちの方がシンプルですね;-o-)

Sub knap_dp()

'dpメモ(上限重量10000まで対応),items要否結果
Dim dp(10000, 1) As Variant, items() As String
'iループ,jループ,vアイテム価値,w重量,max_w上限重量
Dim i As Variant, j As Integer, v As Variant, w As Variant, max_w As Integer
i = 0
max_w = Range("B4")

'読み込みと計算
    Do While True
    v = Range("B8").Offset(i, 0)
    w = Range("B8").Offset(i, 1)
        If v = "" Or w = "" Then
        Exit Do
        Else
            For j = max_w To 1 Step -1
                If j - w >= 0 Then
                    If dp(j, 0) < dp(j - w, 0) + v Then
                    dp(j, 0) = dp(j - w, 0) + v
                    dp(j, 1) = dp(j - w, 1) & i & ","
                    End If
                End If
            Next
        i = i + 1
        End If
    Loop

'結果表示
Range("E4") = dp(max_w, 0)
dp(max_w, 1) = Left(dp(max_w, 1), Len(dp(max_w, 1)) - 1)
items() = Split(dp(max_w, 1), ",")
Range("E8", Range("E8").Offset(i - 1, 0)) = ""
    For Each i In items()
    Range("E8").Offset(Val(i), 0) = "○"
    Next

End Sub

 インデントが不自然でした;-o-)その他もいろいろと雑でスミマセン。
 コメントに記載しているとおり設定できる上限重量は10000までです。拡張する場合は配列のカッコ内の10000を増やしてください。


f:id:accs2014:20190115175858p:plain:right:w400

 実行の様子です。
 アイテム数100、上限重量10000でもやってみましたがほとんど待たされませんのでそこそこ実用的かと思います。

Bingからの流入が増えている

 メインブログの方ですけども、以前は9割方googleからの流入で残りはほぼYahooという状態が長く続き、Bingからのアクセスは全くありませんでした。

f:id:accs2014:20190113150255p:plain:right:w400

 しかし大したシェアもなさそうだったのでBingのウェブマスターツールは利用せず、2年近く前に登録ページからURLを送信した(今は匿名でのURL登録はできなくなっているようです)だけであとはほったらかしにしていました。ところが近頃になってgoogleの割合が減少してYahooがやや増加、そしてBingの割合が10%を超えるようになりました。画像ははてなのアクセス解析ですが、これでもBingは高い方ではなく、最近は13~15%を記録する日もあります。
 マイクロソフト製品関連のサイトということで何か優遇されているのかとも思いましたがそんなことはなく、Access関連の用語で検索しても大して引っ掛かりません;-o-)理由はわかりませんが、現状でこれでこれだけ流入しているならウェブマスターツールを使ってさらにPVを余地が伸ばすチャンスなのではないかという気がしてきました。近いうちに試してみたいと思います。