2017-10-24 9 views
0

私は日付範囲があり、日付範囲をチャンク(ユーザーが提供する数量)に分割したいという問題があります。各チャンクは1ヶ月間の連続した範囲でなければなりません。最長のチャンクは、最短のチャンクよりも1か月以上長くなければなりません。グループの日付範囲はバケットになります

日付範囲は、同様に、全体ヶ月以下のとおりです。

  • 開始日は常に
  • 終了日は常に月の最後の日になります月の最初のものです。

入力範囲は、各チャンクが少なくとも1ヶ月を1つ以上持つことができるほど十分に大きいと仮定できます。

例えば、日付範囲1/1/2000から8/31/2000の8つのチャンクが要求されていることはごく簡単な例です。その後、それぞれのチャンクは完全な月になるでしょう。

この問題を考えるための簡単な方法は、1-15 から番号のリストを考えてみましょう 次のようであり、我々は8つのチャンク 可能な組み合わせにそれらを分割したいが、私はジョダ考えた

(1),(2),(3),(4),(5),(6),(7),(8,9,10,11,12,13,14,15) -> satisfies only one constraints of using up all the chunks 
(1,9),(2,10), (3,11), (4,12), (5,13), (6,14), (7,15), (8) ---> satisfies only 1 constraint of minimizing the difference between maximum number and minimum numbers in a chunk. 

(1,2), (3,4), (5,6), (7,8) (9,10), (11,12) (13,14), 15 ---> correct 

です日付ライブラリとしての時刻。

これは宿題の問題ではありません。私は入力として日付範囲を取るクエリを並列化しようとしています。チャンクはコアであることが意図されており、コア全体の後続の日付範囲に対してクエリを実行したいと考えています。

+0

これまでに何を試しましたか?これは宿題のように聞こえる...特定の質問をしてください。 [SOの質問をするにはここを見てください](https://stackoverflow.com/help/how-to-ask) –

+0

何を試すことができますか?私はこの問題を私がどこにいるのか分かっていた。それは差を最小にするという制約である。 私は質問が下の投票に値すると思うとは思わない – AnyaK

答えて

1

これは難しい問題ではありません。仕事をするためのシンプルな構造があります。まず第一に、あなたは日数を気にせず、満月に過ぎないことに注意してください。

  • 範囲内の月数を計算します。日を忘れて、ちょうど 月と年を使用してください。それらの入力をm1/d1/y1(開始)とm2/d2/y2(終了)と呼んでください。 m_range = 12*(y2-y1) + m2-m1 + 1
  • 入力チャンク数chunkを呼び出します。 m_range < chunkの場合、入力が無効です。
  • 最小チャンクサイズはmin_size = floor(m_range/chunk)(切り捨て)です。最大サイズはもう1つです。
  • 分割が偶数でない場合は、割り当てようとする残りの月があります。この余分をextra = m_range mod chunkと計算します。これらのパラメータを持つ

、割り当ては単純です:最初のextraチャンクは、各余分月取得、およびサイズmin_size+1のものであろう。残りのchunk-extraチャンクはそれぞれmin_sizeヶ月になります。

たとえば、2010年1月1日〜2010年5月31日の範囲と4つのチャンクを考えてみましょう。

m_range = 12*(2018-2017) + (5-1) + 1 = 12 + 4 + 1 = 17 
min_size = floor(m_range/chunk) = floor(17/4) = 4 
extra = m_range mod chunk = 1 

したがって、最初のチャンクは5か月間与えます。他の3つのチャンクはそれぞれ4か月になります。

個々の日付の操作は、学生の練習として残されています。 :-)

+0

はい。これは正しい方法だと思うし、私は前処理をしてから日付を割り当てることができます。 – AnyaK

0

与えられた日付範囲は、その範囲内の日数を計算します。私はジョーダのデータライブラリに精通していない、多分それを行うことができます。そうでなければ、これを最初からやっていました。これを行う関数を書くだけです(カレンダー、1月は31日、2月28日などはハードコード)。関連する場合は、閏年に注意してください。

合計時間範囲で日数を取得したら、その数をチャンク数で割ります。今では、各チャンクにどれくらいの日数があるべきかを知っています。その後、最初の日付から開始し、「各チャンクの日数」を表す数字を追加して間隔を作成します。インターバルは1か月で始まり、将来の月に終了する場合があります。ここでは、ライブラリまたはハードコードされた参照を各月の何日に使用する必要があります。

これが役に立ちます。

編集:以下の私のコメントを参考にして役立つ機能へのリンクをご覧ください。

Edit2:この回答は、私がこのレスポンスを作成した後にどのように編集されたかを見るのにはあまり役に立ちません。しかし、私のコメントにリンクされている機能は、依然として有用です。

+0

私はあなたのP.S.を見た。編集。 [ここでは、Joda-Timeの2つの日付間の日数を取得する方法を説明する記事があります](https://stackoverflow.com/questions/3802893/number-of-days-between-two-dates-in-joda-time)On [クイックスタートガイド](http://joda-time.sourceforge.net/quickstart.html)の一番下には、特定の日付に日を追加する方法の例があります。 –

関連する問題