рдЗрд╕ рдкреЛрд╕реНрдЯ рдореЗрдВ, рд╣рдо рднреВ-рд╕реНрдерд╛рдирд┐рдХ рдЕрдиреБрдХреНрд░рдордг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ, рдЬреИрд╕реЗ рдХрд┐ R * -tree рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдФрд░ рдореИрдВрдиреЗ рдЕрдкрдирд╛ рдкрд╣рд▓рд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ред
рддреЛ рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рд╕реНрдирд╛рддрдХ рд╣реЛрдиреЗ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж, рдореБрдЭреЗ рд╢рд┐рдХреНрд╖рдХреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рд▓рдп рд╕реЗ рдПрдХ рдкреНрд░рд╕реНрддрд╛рд╡ рдорд┐рд▓рд╛, рдЬреЛ рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЬреАрдкреАрдПрд╕-рдирд┐рдЧрд░рд╛рдиреА рд╕реЗрд╡рд╛рдПрдВ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдореИрдВрдиреЗ рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдпрд╛ред рдпрд╣рд╛рдБ рдпрд╣ рд╣реИ! рдЕрдВрдд рдореЗрдВ, рдЕрд╕рд▓реА рджрд┐рд▓рдЪрд╕реНрдк рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ! рдореЗрд░рд╛ рдЖрдирдВрдж рдФрд░ рдЙрддреНрд╕рд╛рд╣ рдХреЛрдИ рд╕реАрдорд╛ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдерд╛ред рдкрд╣рд▓рд╛ рдХрд╛рдо рдЬреЛ рдореБрдЭреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЙрд╕рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╢рдмреНрдж рдереЗ:
рдПрдХ рдбреЗрд╕реНрдХрдЯреЙрдк рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдорд╛рдЗрд▓реЗрдЬ рдкрд░ рдХрд┐рд╕реА рднреА рд░рд┐рдкреЛрд░реНрдЯ, рдХрд╛рд░реЛрдВ рдХреЗ рдЦрд░реНрдЪ рдХрд┐рдП рдЧрдП рдИрдВрдзрди рдЗрддреНрдпрд╛рджрд┐ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡реЗрдХреНрдЯрд░ рдирдХреНрд╢реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдореЗрдВ рдЗрди рдХрд╛рд░реЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде, рдХрд╛рд░ рдЖрдВрджреЛрд▓рдиреЛрдВ рдХреЗ рдЗрддрд┐рд╣рд╛рд╕ рдФрд░ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреНрдп рд╕рд╛рдорд╛рдиреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рддреЗ рд╣реИрдВред рдЕрдм рдпрд╣ рд╕рдм рдЧрд▓рдд рдФрд░ рдЕрдХреНрд╖рдо рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред рдХреЛрдИ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдХрд┐ рдЗрд╕реЗ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ...
рдореЗрд░реЗ рд╣рд╛рде рдореЗрдВ 160,000 рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрд╡реЗрджрди рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рд╡рд╣ рдпрд╣ рд╣реИред рдХреЛрдИ рджрд╕реНрддрд╛рд╡реЗрдЬ рдирд╣реАрдВ, рдХреБрдЫ рднреА рдирд╣реАрдВред рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдПрдХрдорд╛рддреНрд░ рд╕реНрд░реЛрдд рдпреЗ рдмрд╣реБрдд рд╣реА рд╢рд┐рдХреНрд╖рдХ рдФрд░ рдпреЛрдЬрдирд╛ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ рджреБрд░реНрд▓рдн рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ "рдореИрдВрдиреЗ рд╡рд╛рд╕ рдХреЗ рдЕрдиреБрд░реЛрдз рдкрд░ n * x рд╣рдЯрд╛ рджрд┐рдпрд╛"ред рдпрд╣ рдкрд░рд┐рдпреЛрдЬрдирд╛ 10 рд╕рд╛рд▓ рд╕реЗ рдЕрдзрд┐рдХ рдкреБрд░рд╛рдиреА рд╣реИ, рдХрд╛рд░реНрдпрд╛рд▓рдп рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдЬрд▓реНрдж рд╕реЗ рдЬрд▓реНрдж рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╣реА рд╡рдлрд╛рджрд╛рд░ рдФрд░ рд▓рдЪреАрд▓рд╛ рд╣реИред рд╕рднреА рддрд░рд╣ рдХреА рдЗрдЪреНрдЫрд╛рдПрдВ рдФрд░ рд╕реАрдЯреА рд▓рдЧрднрдЧ рдЕрдкрдиреЗ рдШреБрдЯрдиреЛрдВ рдкрд░ рдкреВрд░реА рдХрд░ рд▓реА рд╣реИрдВ рдЬреЛ рдХрд┐ рджрд╕реНрддрд╛рд╡реЗрдЬ рдирд╣реАрдВ рдереЗред рд░рд╛рдХреНрд╖рд╕реА рд▓рд╛рдкрд░рд╡рд╛рд╣реА! рд▓реЗрдХрд┐рди рдРрд╕реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рдХрд┐рд╕реА рдФрд░ рдХреЗ рдХреЛрдб рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдореЗрдВ рдХреМрд╢рд▓ рдХреЛ рдкрдВрдк рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреА рд╣реИрдВред
рдЦреИрд░, рдХрд╛рд░реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдХрд╛рдо рдХреЗ рд▓рд┐рдП рд╕рд╛рдордЧреНрд░реА рдереАред рдХреЛрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдлрд╡рд╛рд╣ рдлреИрд▓рд╛рдирд╛, рд╕рд╡рд╛рд▓ рдкреВрдЫрдирд╛, рдореИрдВрдиреЗ рдЙрд╕ рд╕рдордп рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдорд╛рдорд▓реЛрдВ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рд╕реНрдкрд╖реНрдЯ рдХрд┐рдпрд╛:
- рдорд╛рдирдЪрд┐рддреНрд░ рдЗрди рдмрд┐рдВрджреБрдУрдВ рдХреЗ рд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рдмрд┐рдВрджреБрдУрдВ рдФрд░ рд╡рд╕реНрддреБрдУрдВ рдХреА рдПрдХ рд╕рд░рдгреА рд╣реИрдВ
- рд╕реНрдХреНрд░реАрди рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╣рд┐рдЯ рдХрд░рдиреЗ рд╡рд╛рд▓реА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕рдВрдкреВрд░реНрдг рдЦреЛрдЬ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рд╕реНрдХреНрд░реАрди рдкрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЖрдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рдХрд░рдХреЗ "рдордХреНрдЦреА рдкрд░" рдСрдмреНрдЬреЗрдХреНрдЯ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдпрд╛ рдирд╣реАрдВ (рдпрд╣ 1-рдкрд┐рдХреНрд╕реЗрд▓ рдШрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдкрд░ рд╕рд┐рд╕реНрдЯрдо рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдЦрд░реНрдЪ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ)
рдЫреЛрдЯреЗ рдЖрдХрд╛рд░ рдХреЗ рдирдХреНрд╢реЗ (рд╢рд╣рд░, рдЬрд┐рд▓рд╛) рдХрд╛ рдЪрд┐рддреНрд░рдг рд╕рд╣рдиреАрдп рдерд╛ред рдЬрдм рд▓реЛрдб рд╣реЛ рд░рд╣рд╛ рд╣реЛ, рддреЛ рдХреНрд╖реЗрддреНрд░ рдХреЗ рджреЗрд╢ рдХреЗ рдирдХреНрд╢реЗ рдХреЛ рд▓реЛрдб рдХрд░рдирд╛, рдЬрд┐рд╕рдореЗрдВ рд╕реИрдХрдбрд╝реЛрдВ рд╡реЗрдХреНрдЯрд░ рд╡рд╕реНрддреБрдПрдВ рд╣реЛрдВ, рдЬрд┐рд╕рдореЗрдВ рдХреБрд▓ рд▓рд╛рдЦреЛрдВ рдмрд┐рдВрджреБ рд╣реЛрдВ, рдЖрдк рдХрд▓реНрдкрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред Googling рдФрд░ рд╡рд┐рд╖рдп рдкрд░ рдмрд╣реБрдд рд╕рд╛рд░реА рд╕рд╛рдордЧреНрд░реА рдкрдврд╝рдирд╛, рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдЖрдк рдХреЗ рд▓рд┐рдП 2 рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХреА рдХрд┐ рдХреИрд╕реЗ "рдЗрд╕реЗ рд╕рд╣реА рдХрд░реЗрдВ" рд╕рдм рдХреБрдЫ:
- рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рдкреВрд░реЗ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЖрдХрд╛рд░ рдХреЗ рд╡рд░реНрдЧреЛрдВ рдореЗрдВ рддреЛрдбрд╝реЗрдВ, рдЬреЛрдбрд╝реЛрдВ рдкрд░ рдЧрд┐рд░рдиреЗ рд╡рд╛рд▓реА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдПрдХ рд╡рд░реНрдЧ рд╕реВрдЪрдХрд╛рдВрдХ рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВ, рдбреЗрдЯрд╛ рдХреЛ рд╕реЙрд░реНрдЯ рдХрд░реЗрдВ рдФрд░ рдЪрд▓рддреЗ-рдлрд┐рд░рддреЗ рдЖрд╡рд╢реНрдпрдХ рд╡рд╕реНрддреБрдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ;
- рдЖрд░-рдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рдереЛрдбрд╝рд╛ рд╕реЛрдЪрдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рд╡рд╛рдкрд╕ рдлреЗрдВрдХ рджрд┐рдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдХреЗрд▓ рдХреЗ рд╕реНрддрд░реЛрдВ рдХреА рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рд╣реЛрдирд╛ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдЧреНрд░рд┐рдб рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред рджреВрд╕рд░реЗ рд╡рд┐рдХрд▓реНрдк рдиреЗ рдЕрд╕реАрдорд┐рдд рд╕реНрдХреЗрд▓рд┐рдВрдЧ рдХрд╛ рд▓рд╛рдн рджрд┐рдпрд╛, рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдЕрдзрд┐рдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд▓рдЧ рд░рд╣рд╛ рдерд╛ред рдкрд╣рд┐рдпрд╛ рдХреЛ рд╕реБрджреГрдврд╝ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдбреЗрд▓реНрдлреА рдХреЗ рддрд╣рдд рдореМрдЬреВрджрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреА рдЦреЛрдЬ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдкрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ред рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдХрднреА рдирд╣реАрдВ рдорд┐рд▓рд╛ рдФрд░ рдореИрдВрдиреЗ рдЦреБрдж рдХреЛ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред
рдЖрд░-рдЯреНрд░реА рдХреНрдпрд╛ рд╣реИ? рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╕реНрдерд╛рдирд┐рдХ рдбреЗрдЯрд╛ рдЕрдиреБрдХреНрд░рдордг рдХреЗ рд▓рд┐рдП рдПрдВрдЯреЛрдирд┐рди рдЧреБрдЯрдореИрди рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдпрд╣ рдПрдХ рд╕рдВрддреБрд▓рд┐рдд рдкреЗрдбрд╝ рд╣реИ рдФрд░ рдЕрдиреБрднрд╡рдЬрдиреНрдп рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдПрдХ рдкреЗрдбрд╝ рдХрдИ рдиреЗрд╕реНрдЯреЗрдб рдЖрдпрддреЛрдВ рдореЗрдВ рдЬрдЧрд╣ рддреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдЯреНрд░реА рдиреЛрдб рдореЗрдВ рдиреНрдпреВрдирддрдо (рдиреНрдпреВрдирддрдо) рдФрд░ рдЕрдзрд┐рдХрддрдо (рдЕрдзрд┐рдХрддрдо) рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реЛрддреА рд╣реИред рдЯреНрд░реА рдмрд┐рд▓реНрдбрд┐рдВрдЧ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рд╕рд╣реА рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ 2 <= minCount <= maxCount / 2 ред рдкреНрд░рддреНрдпреЗрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рдЕрдкрдиреА рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдЖрдпрдд рд╣реИ - MBR (рдиреНрдпреВрдирддрдо рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдЖрдпрдд)ред рдПрдХ рдПрдордмреАрдЖрд░ рдиреЛрдб рдПрдХ рдЖрдпрдд рд╣реИ рдЬреЛ рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдбреНрд╕ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЖрдпрддреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред
рдПрдХ рдкреЗрдбрд╝ рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЬрдм рдиреЛрдб рдУрд╡рд░рдлреНрд▓реЛ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рд╕рднреА рдореВрд▓ рдиреЛрдбреНрд╕ рдХреЗ рд╡рд┐рднрд╛рдЬрди рдХреЗ рдмрд╛рджред рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдкреНрд░рд╢реНрдиреЛрдВ рдХреА рдкреНрд░рднрд╛рд╡рд╢реАрд▓рддрд╛ рдХрдИ рдорд╛рдирджрдВрдбреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИ:
- рдПрдордмреАрдЖрд░ рдиреЛрдбреНрд╕ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдХрдо рдХрд░рдирд╛ (рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдмреАрдЪ рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рдХреЛ рдХрдо рдХрд░рдирд╛);
- рдПрдордмреАрдЖрд░ рдиреЛрдбреНрд╕ рдХреЗ рдЕрддрд┐рд╡реНрдпрд╛рдкреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдиреНрдпреВрдирддрдордХрд░рдг;
- рдПрдордмреАрдЖрд░ рдиреЛрдб рдХреА рдкрд░рд┐рдзрд┐ рдХреЛ рдиреНрдпреВрдирддрдо рдХрд░рдирд╛;
рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрд░-рдкреЗрдбрд╝ рд╣реИрдВ, рдХреЗрд╡рд▓ рднреАрдбрд╝ рдиреЛрдб рдХреЗ рдЕрдВрддрд┐рдо рдФрд░ рд╡рд┐рднрд╛рдЬрди рдХреА рдкрд╕рдВрдж рдореЗрдВ рднрд┐рдиреНрдирддрд╛ рд╣реИред
рдореИрдВрдиреЗ R * -tree рдХреНрдпреЛрдВ рдЪреБрдирд╛? рдореЗрд░реЗ рд╡реНрдпрдХреНрддрд┐рдкрд░рдХ рдореВрд▓реНрдпрд╛рдВрдХрди рдореЗрдВ рдПрдВрдЯреЛрдирд┐рди рдЧреБрдЯрдореИрди (рдЖрд░-рдЯреНрд░реАрдЬрд╝) рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╢рд╛рд╕реНрддреНрд░реАрдп рджреГрд╖реНрдЯрд┐рдХреЛрдг, рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдиреБрдкрдпреБрдХреНрдд рд╣реИред рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВ рд╡рд┐рдХрд┐рдкреАрдбрд┐рдпрд╛ , рдЕрд░реНрдерд╛рддреН рдЖрд░-рдЯреНрд░реА, рдЬрд░реНрдорди рдбрд╛рдХрдШрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдорд┐рдд рд╕рд╛рдордЧреНрд░реА рдХрд╛ рд╣рд╡рд╛рд▓рд╛ рджреВрдВрдЧрд╛:
рдЬрдм рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рдиреЛрд░рдмрд░реНрдЯ рдмреЗрдХрдореИрди, рд╣рдВрд╕-рдкреАрдЯрд░ рдХреНрд░рд┐рдЧреЗрд▓, рд░рд╛рд▓реНрдл рд╢реНрдирд╛рдЗрдбрд░ рдФрд░ рдмрд░реНрдирд╣рд╛рд░реНрдб рд╕реАрдЬрд░ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдЖрд░ * рдЯреНрд░реА рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рдгрд╛рдо рджреЗрддреЗ рд╣реИрдВ:
рдЖрд░ * -рдЯреНрд░реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕рдВрд╕рд╛рдзрди-рдЧрд╣рди рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рдорд╛рдиреНрдп рдЖрд░-рдЯреНрд░реА рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЦреЛрдЬ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдмреЗрд╣рддрд░ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИред
рдЗрд╕ рдмрд╛рдд рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рд╕рдореНрдорд┐рд▓рди рдХреИрд╕реЗ рд╣реЛрддрд╛ рд╣реИ: рдЗрд╕рдореЗрдВ рдПрдХ рд╢рд╛рдЦрд╛ (рд╕рдмрдЯреНрд░реА) / рдиреЛрдб рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдФрд░ рдПрдХ рдиреЛрдб рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЬрдм рдпрд╣ рднрд░рд╛ рд╣реБрдЖ рд╣реИред
рд╕рдмрдЯреНрд░реА рдЪрдпрди рдПрд▓реНрдЧреЛрд░рд┐рдердо (рдЪрдпрди рдХрд░реЗрдВ)
1. N рдХреЛ рд░реВрдЯ рдиреЛрдб рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЗрдЯ рдХрд░реЗрдВ 2. рдпрджрд┐ рдПрди рдПрдВрдб рдиреЛрдб рд╣реИ, рддреЛ рдПрди рд╡рд╛рдкрд╕ рдХрд░реЗрдВ 3.Inache 4. рдпрджрд┐ N рдХрд╛ рдмрдЪреНрдЪрд╛ рдиреЛрдбреНрд╕ рдЕрдВрддрд┐рдо рдиреЛрдбреНрд╕ (рдкрддреНрддрд┐рдпрд╛рдВ) рд╣реИрдВ, 5. рдПрдХ рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдб рдПрди рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рдЬрд┐рд╕рдХреЗ рдПрдордмреАрдЖрд░ рдХреЛ рд╕рдореНрдорд┐рд▓рди рдкрд░ рдУрд╡рд░рд▓реИрдк рдореЗрдВ рд╕рдмрд╕реЗ рдЫреЛрдЯреА рд╡реГрджреНрдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдиреЛрдб рдХреЗ рд▓рд┐рдП рд╡рд╕реНрддреБ 6. рдпрджрд┐ рдУрд╡рд░рд▓реИрдк рдореЗрдВ рд╕рдмрд╕реЗ рдЫреЛрдЯреА рд╡реГрджреНрдзрд┐ рдХреЗ рд╕рд╛рде рдХрдИ рдиреЛрдб рд╣реИрдВ, рддреЛ рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рдЬрд┐рд╕реЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рдмрд╕реЗ рдЫреЛрдЯреА рд╡реГрджреНрдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ 7. рдпрджрд┐ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рдмрд╕реЗ рдЫреЛрдЯреА рд╡реГрджреНрдзрд┐ рдХреЗ рд╕рд╛рде рдХрдИ рдиреЛрдб рд╣реИрдВ, рддреЛ рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдиреЛрдб рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рд╕рдмрд╕реЗ рдЫреЛрдЯреЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд╕рд╛рде 8. рдирд╣реАрдВ рддреЛ 9. рдПрдХ рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдб рдПрди рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рдЬрд┐рд╕рдХреЗ рдПрдордмреАрдЖрд░ рдХреЛ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рдмрд╕реЗ рдЫреЛрдЯреА рд╡реГрджреНрдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ 10. рдпрджрд┐ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рдмрд╕реЗ рдЫреЛрдЯреА рд╡реГрджреНрдзрд┐ рдХреЗ рд╕рд╛рде рдХрдИ рдиреЛрдб рд╣реИрдВ, рддреЛ рд╕рдмрд╕реЗ рдЫреЛрдЯреЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд╕рд╛рде рдиреЛрдб рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ 11. рдЪрдпрдирд┐рдд рдиреЛрдб рдкрд░ рдПрди рд╕реЗрдЯ рдХрд░реЗрдВред 12. рдЪрд░рдг 2 рд╕реЗ рдкреАрдЫреЗ рд╣рдЯреЗрдВред
рдиреЛрдб рд╡рд┐рднрд╛рдЬрди рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо (рд╕реНрдкреНрд▓рд┐рдЯрдиреЛрдб)
рд╡рд┐рднрд╛рдЬрди рд╡рд┐рдХрд▓реНрдк рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрд░ * - рдЯреНрд░реА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ: рдиреЛрдбреНрд╕ рдХреЛ рдмрд╛рдИрдВ рдФрд░ рджрд╛рдИрдВ рд╕реАрдорд╛рдУрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рддреНрдпреЗрдХ рд╕рдордиреНрд╡рдп рдЕрдХреНрд╖реЛрдВ рдХреЗ рд╕рд╛рде рдХреНрд░рдордмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд╕реЙрд░реНрдЯ рдХрд┐рдП рдЧрдП рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП, рдиреЛрдбреНрд╕ рдХреЛ 2 рд╕рдореВрд╣реЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ k = [1 ... (maxCount - 2 * minCount + 2)] , рдкрд╣рд▓реЗ рд╕рдореВрд╣ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ (minCount - 1) + k рдиреЛрдбреНрд╕ рджреВрд╕рд░реЗ рдореЗрдВ рд╢реЗрд╖ рд╣реИрдВред рдЗрд╕ рддрд░рд╣ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рддрд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрдХреЗрддрдХреЛрдВ рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ:
- рдХреНрд╖реЗрддреНрд░: рдХреНрд╖реЗрддреНрд░ = рдХреНрд╖реЗрддреНрд░ (рдкрд╣рд▓реЗ рд╕рдореВрд╣ рдХрд╛ рдПрдордмреАрдЖрд░) + рдХреНрд╖реЗрддреНрд░ (рджреВрд╕рд░реЗ рд╕рдореВрд╣ рдХрд╛ рдПрдордмреАрдЖрд░)
- рдкрд░рд┐рдзрд┐: рдорд╛рд░реНрдЬрд┐рди = рдорд╛рд░реНрдЬрд┐рди (рдкрд╣рд▓реЗ рд╕рдореВрд╣ рдХрд╛ рдПрдордмреАрдЖрд░) + рдорд╛рд░реНрдЬрд┐рди (рджреВрд╕рд░реЗ рд╕рдореВрд╣ рдХрд╛ рдПрдордмреАрдЖрд░)
- рдУрд╡рд░рд▓реИрдк: рдУрд╡рд░рд▓реИрдк = рдХреНрд╖реЗрддреНрд░ (рдкрд╣рд▓реЗ рд╕рдореВрд╣ рдХрд╛ рдПрдордмреАрдЖрд░ (рджреВрд╕рд░реЗ рд╕рдореВрд╣ рдХрд╛ рдПрдордмреАрдЖрд░))
рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╡рд┐рддрд░рдг рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрд▓реНрдЧреЛрд░рд┐рджрдо рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
1. рдХреЙрд▓ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВSSSSititx рдЕрдХреНрд╖ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╡рд┐рддрд░рдг рд╣реЛрдЧрд╛ред 2. рдЪрдпрдирд┐рдд рдЕрдХреНрд╖ рдкрд░ рд╕рд░реНрд╡реЛрддреНрддрдо рд╡рд┐рддрд░рдг рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП selectSplitIndex рдкрд░ рдХреЙрд▓ рдХрд░реЗрдВ 3. рд╡рд╕реНрддреБрдУрдВ рдХреЛ 2 рдиреЛрдбреНрд╕ рдкрд░ рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВ
chooseSplitAxis
1. рдкреНрд░рддреНрдпреЗрдХ рдЕрдХреНрд╖ рдХреЗ рд▓рд┐рдП 2. рдмрд╛рдИрдВ рдУрд░ рдиреЛрдбреНрд╕ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░реЗрдВ, рдФрд░ рдлрд┐рд░ рдЙрдирдХреЗ рдПрдордмреАрдЖрд░ рдХреА рджрд╛рдИрдВ рд╕реАрдорд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ред рдЙрдкрд░реЛрдХреНрдд рд╡рд░реНрдгрд┐рдд рдиреЛрдбреНрд╕ рдХреЛ рд╡рд┐рддрд░рд┐рдд рдХрд░реЗрдВ, рдПрд╕ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ - рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рддрд░рдг рдХреЗ рд╕рднреА рдкрд░рд┐рдзрд┐ рдХрд╛ рдпреЛрдЧред 3. рдиреНрдпреВрдирддрдо рдПрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдХреНрд╖ рдЪреБрдиреЗрдВред
chooseSplitIndex
1. рдЪрдпрдирд┐рдд рдЕрдХреНрд╖ рдХреЗ рд╕рд╛рде, рдиреНрдпреВрдирддрдо рдУрд╡рд░рд▓реИрдк рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд┐рддрд░рдг рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ 2. рдпрджрд┐ рдиреНрдпреВрдирддрдо рдУрд╡рд░рд▓реИрдк рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдХрдИ рд╡рд┐рддрд░рдг рд╣реИрдВ, рддреЛ рд╡рд┐рддрд░рдг рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рд╕рдмрд╕реЗ рдЫреЛрдЯреЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд╕рд╛рдеред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЦреБрдж рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдВ (рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдВ)
1. рдХреЙрд▓ selectSubStree, рдПрди рдиреЛрдб рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд░реВрдЯ рдиреЛрдб рд╕реЗ рдЧреБрдЬрд░ рд░рд╣рд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╡рд╕реНрддреБ E рдХрд╛ рд╕рдореНрдорд┐рд▓рди рд╣реЛрдЧрд╛ 2. рдпрджрд┐ N рдореЗрдВ рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЕрдзрд┐рдХрддрдо рд╕реЗ рдХрдо рд╣реИ, 3. E рдХреЛ N рдореЗрдВ рдбрд╛рд▓реЗрдВ 4. N рдФрд░ рдЙрд╕рдХреЗ рд╕рднреА рдореВрд▓ рдиреЛрдбреНрд╕ рдХреЗ рд▓рд┐рдП MBR рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ 5. рдЕрдиреНрдпрдерд╛, рдПрди рдФрд░ рдИ рдХреЗ рд▓рд┐рдП рд╕реНрдкреНрд▓рд┐рдЯрдиреЛрдб рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред
рдЕрдкрдиреЗ рд▓реЗрдЦ рдореЗрдВ R * рдЯреНрд░реА рдХреЗ рд▓реЗрдЦрдХреЛрдВ рдХрд╛ рддрд░реНрдХ рд╣реИ рдХрд┐ рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдкреНрд░рджрд░реНрд╢рди minCount = maxCount * 40% рдХреЗ рд╕рд╛рде рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рд╡рд╣ рд╕рдм рд╣реИред рд╣рдорд╛рд░рд╛ рдкреЗрдбрд╝ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЕрдм рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рд╣реА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдвреВрдВрдврдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ:
рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рджрдо (FindObjectsInArea)
1. рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рдиреЛрдб N рдкрд░рд┐рдорд┐рдд рд╣реИ, 2. рдиреЛрдб рдПрди рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдмрдЪреНрдЪреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдИ рдХреЗ рд▓рд┐рдП, рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ 3. рдпрджрд┐ E рдЦреЛрдЬ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдХрд╛рдЯрддрд╛ рд╣реИ, рддреЛ E рдХреЛ рдЦреЛрдЬ рдкрд░рд┐рдгрд╛рдо R рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред 4. рдирд╣реАрдВ рддреЛ 5. рдиреЛрдб рдПрди рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдб рдПрди рдХреЗ рд▓рд┐рдП, рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ 6. рдпрджрд┐ n рдЦреЛрдЬ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдХрд╛рдЯрддрд╛ рд╣реИ, рддреЛ n рдХреЗ рд▓рд┐рдП findObjectsInArea рдкрд░ рдХреЙрд▓ рдХрд░реЗрдВ
рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдмрд╕
findObjectsInArea
рдХреЙрд▓
findObjectsInArea
, рдЗрд╕реЗ рд░реВрдЯ рдиреЛрдб рдФрд░ рдЦреЛрдЬ рдХреНрд╖реЗрддреНрд░ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
рдмреБрдирд┐рдпрд╛рджреА рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдХреЛрдб рдХреЛ рджреЗрдЦреЗрдВ:
sortsy
// R*-tree unit RStar_tree; interface uses Windows, SysUtils, Math; const MAX_M = 16; // MIN_M = Round(MAX_M * 0.4); // type TObjArr = array of Integer; // TAxis = (X, Y); // chooseSplitAxis - TBound = (Left, Right); // (\) TGpsPoint = record // GPS (X = lon\Y = lat) X, Y: Double; end; TMBR = record // \\ MBR = Minimum Bounding Rectangle Left, Right: TGpsPoint; // left - right - end; TRObject = record // R-. mbr: TMBR; // idx: Integer; // , end; TRNode = class // private fmbr: TMBR; // FParent: Integer; // , - FChildren: array of Integer; // FObjects: array of TRObject; // . ( () (, , ) FisLeaf: Boolean; // () FLevel: Integer; // (0=) protected function getIsLeaf: Boolean; // FisLeaf function getChild(Index: Integer): Integer; // function getObject(Index: Integer): TRObject; // procedure setChild(Index: Integer; node_id: Integer); // procedure setObject(Index: Integer; obj: TRObject); // procedure setParent(parent_id: Integer); // - Procedure copy(node: TRNode); // Procedure clearObjects(); // Procedure clearChildren(); // public constructor Create; overload; constructor Create(node: TRNode); overload; destructor Destroy; override; property mbr: TMBR read fmbr write fmbr; // property isLeaf: Boolean read FisLeaf; // property Children[Index: Integer]: Integer read getChild write setChild; // property Objects[Index: Integer]: TRObject read getObject write setObject; // property Parent: Integer read FParent write setParent; // property Level: Integer read FLevel write FLevel; // function isIntersected(mbr1, mbr2: TMBR): Boolean; overload; // mbr1, mbr2 function isIntersected(mbr: TMBR): Boolean; overload; // MBR mbr function Overlap(mbr_ovrl: TMBR): Double; // MBR function Area: Double; overload; // MBR function Area(mbr: TMBR): Double; overload; // MBR function margin: Double; // MBR end; TRtree = class // private FNodeArr: array of TRNode; // FRoot: Integer; // FHeight: Integer; // Procedure QuickSort(var List: array of TRObject; iLo, iHi: Integer; axe: TAxis; bound: TBound); overload; // MBR. axe - , bound - (/) procedure QuickSort(var List: array of Integer; iLo, iHi: Integer; axe: TAxis; bound: TBound); overload; // MBR. axe - , bound - (/) Procedure splitNodeRStar(node_id: Integer; obj: TRObject); overload; // 2 R*-tree (page 325:: The R*-tree: An Efficient and Robust Access Method for Points and Rectangles+) node_id = obj = Procedure splitNodeRStar(splited_Node_Id, inserted_Node_Id: Integer); overload; // 2 R*-tree (page 325:: The R*-tree: An Efficient and Robust Access Method for Points and Rectangles+) splited_Node_Id = , inserted_Node_Id = Procedure updateMBR(node_id: Integer); overload; // MBR Procedure updateMBR(node: TRNode); overload; // MBR Procedure chooseSubtree(obj: TRObject; var node_id: Integer); // node_id obj. function chooseSplitAxis(obj: TRObject; node_id: Integer): TAxis; overload; // ( R*-tree) function chooseSplitAxis(nodeFather, nodeChild: Integer): TAxis; overload; // ( R*-tree) Procedure findObjectsInArea(mbr: TMBR; node_id: Integer; var obj: TObjArr); overload; // mbr function isRoot(node_id: Integer): Boolean; // node_id function newNode(): Integer; // . protected public constructor Create; destructor Destroy; override; Procedure insertObject(obj: TRObject); // Procedure findObjectsInArea(mbr: TMBR; var obj: TObjArr); overload; // mbr. (. .. , ) property Height: Integer read FHeight; // end; function toRObject(lx, ly, rx, ry: Double; idx: Integer): TRObject; overload; function toRObject(mbr: TMBR; idx: Integer): TRObject; overload; implementation function toRObject(lx, ly, rx, ry: Double; idx: Integer): TRObject; begin Result.mbr.Left.X := Min(lx, rx); Result.mbr.Left.Y := Min(ly, ry); Result.mbr.Right.X := Max(lx, rx); Result.mbr.Right.Y := Max(ly, ry); Result.idx := idx; end; function toRObject(mbr: TMBR; idx: Integer): TRObject; begin Result.mbr := mbr; Result.idx := idx; end; { TRNode } function TRNode.Area: Double; begin Result := (fmbr.Right.X - fmbr.Left.X) * (fmbr.Right.Y - fmbr.Left.Y); end; function TRNode.Area(mbr: TMBR): Double; begin Result := (mbr.Right.X - mbr.Left.X) * (mbr.Right.Y - mbr.Left.Y); end; procedure TRNode.clearChildren; begin SetLength(FChildren, 0); end; procedure TRNode.clearObjects; begin FisLeaf := False; SetLength(FObjects, 0); end; procedure TRNode.copy(node: TRNode); var i: Integer; begin SetLength(FObjects, Length(node.FObjects)); SetLength(FChildren, Length(node.FChildren)); if Length(FObjects) > 0 then begin for i := 0 to High(node.FObjects) do begin FObjects[i].idx := node.FObjects[i].idx; FObjects[i].mbr.Left.X := node.FObjects[i].mbr.Left.X; FObjects[i].mbr.Left.Y := node.FObjects[i].mbr.Left.Y; FObjects[i].mbr.Right.X := node.FObjects[i].mbr.Right.X; FObjects[i].mbr.Right.Y := node.FObjects[i].mbr.Right.Y; end; FisLeaf := True; end else begin for i := 0 to High(node.FChildren) do begin Children[i] := node.Children[i]; end; FisLeaf := False; end; fmbr.Left.X := node.fmbr.Left.X; fmbr.Left.Y := node.fmbr.Left.Y; fmbr.Right.X := node.fmbr.Right.X; fmbr.Right.Y := node.fmbr.Right.Y; FParent := node.Parent; FLevel := node.Level; end; constructor TRNode.Create(node: TRNode); begin Create; FParent := -10; copy(node); end; constructor TRNode.Create; begin inherited; FParent := -10; end; destructor TRNode.Destroy; begin SetLength(FObjects, 0); SetLength(FChildren, 0); inherited; end; function TRNode.getChild(Index: Integer): Integer; begin if High(FChildren) >= Index then begin Result := FChildren[Index]; end; end; function TRNode.getIsLeaf: Boolean; begin if Length(FObjects) > 0 then Result := True else Result := False; end; function TRNode.getObject(Index: Integer): TRObject; begin if High(FObjects) >= Index then begin Result := FObjects[Index]; end; end; function TRNode.isIntersected(mbr: TMBR): Boolean; begin Result := False; if (fmbr.Left.X <= mbr.Right.X) and (fmbr.Left.Y <= mbr.Right.Y) then begin if (fmbr.Right.X >= mbr.Left.X) and (fmbr.Right.Y >= mbr.Left.Y) then begin Result := True; end; end; end; function TRNode.margin: Double; begin Result := ((fmbr.Right.X - fmbr.Left.X) + (fmbr.Right.Y - fmbr.Left.Y)) * 2; end; function TRNode.Overlap(mbr_ovrl: TMBR): Double; var X, Y: Double; begin X := Min(mbr_ovrl.Right.X, fmbr.Right.X) - Max(mbr_ovrl.Left.X, fmbr.Left.X); if X <= 0 then begin Result := 0; Exit; end; Y := Min(mbr_ovrl.Right.Y, fmbr.Right.Y) - Max(mbr_ovrl.Left.Y, fmbr.Left.Y); if Y <= 0 then begin Result := 0; Exit; end; Result := X * Y; end; function TRNode.isIntersected(mbr1, mbr2: TMBR): Boolean; begin Result := False; if (mbr1.Left.X <= mbr2.Right.X) and (mbr1.Left.Y <= mbr2.Right.Y) then begin if (mbr1.Right.X >= mbr2.Left.X) and (mbr1.Right.Y >= mbr2.Left.Y) then begin Result := True; end; end; end; procedure TRNode.setChild(Index, node_id: Integer); begin if High(FChildren) >= Index then begin FChildren[Index] := node_id; FisLeaf := False; end else begin if ((Index) <= (MAX_M - 1)) and (Index >= 0) then begin SetLength(FChildren, Index + 1); FChildren[Index] := node_id; FisLeaf := False; end; end; end; procedure TRNode.setObject(Index: Integer; obj: TRObject); begin if High(FObjects) >= Index then begin FObjects[Index] := obj; FisLeaf := True; end else begin if ((Index) <= (MAX_M - 1)) and (Index >= 0) then begin SetLength(FObjects, Index + 1); FObjects[Index] := obj; FisLeaf := True; end; end; end; procedure TRNode.setParent(parent_id: Integer); begin if parent_id >= 0 then FParent := parent_id; end; { TRtree } function TRtree.chooseSplitAxis(obj: TRObject; node_id: Integer): TAxis; var arr_obj: array of TRObject; i, j, k, idx: Integer; node_1, node_2: TRNode; perimeter_min, perimeter: Double; begin SetLength(arr_obj, MAX_M + 1); if not FNodeArr[node_id].isLeaf then Exit; for i := 0 to High(FNodeArr[node_id].FObjects) do begin arr_obj[i] := FNodeArr[node_id].FObjects[i]; end; arr_obj[ High(arr_obj)] := obj; node_1 := TRNode.Create; node_2 := TRNode.Create; perimeter_min := 999999; for i := 0 to 1 do // begin perimeter := 0; for j := 0 to 1 do // () begin node_1.clearObjects; node_2.clearObjects; QuickSort(arr_obj, 0, High(arr_obj), TAxis(i), TBound(j)); for k := 1 to MAX_M - MIN_M * 2 + 2 do // begin idx := 0; while idx < ((MIN_M - 1) + k) do // (MIN_M - 1) + k begin node_1.Objects[idx] := arr_obj[idx]; idx := idx + 1; end; for idx := idx to High(arr_obj) do // begin node_2.Objects[idx - ((MIN_M - 1) + k)] := arr_obj[idx]; end; updateMBR(node_1); updateMBR(node_2); perimeter := perimeter + ((node_1.mbr.Right.X - node_1.mbr.Left.X) * 2 + (node_2.mbr.Right.Y - node_2.mbr.Left.Y) * 2); end; end; if perimeter <= perimeter_min then begin Result := TAxis(i); perimeter_min := perimeter; end; perimeter := 0; end; SetLength(arr_obj, 0); FreeAndNil(node_1); FreeAndNil(node_2); end; function TRtree.chooseSplitAxis(nodeFather, nodeChild: Integer): TAxis; var arr_node: array of Integer; i, j, k, idx: Integer; node_1, node_2: TRNode; perimeter_min, perimeter: Double; begin SetLength(arr_node, MAX_M + 1); for i := 0 to High(FNodeArr[nodeFather].FChildren) do begin arr_node[i] := FNodeArr[nodeFather].FChildren[i]; end; arr_node[ High(arr_node)] := nodeChild; perimeter_min := 999999; node_1 := TRNode.Create; node_2 := TRNode.Create; for i := 0 to 1 do // begin perimeter := 0; for j := 0 to 1 do // () begin node_1.clearChildren; node_2.clearChildren; QuickSort(arr_node, 0, High(arr_node), TAxis(i), TBound(j)); for k := 1 to MAX_M - MIN_M * 2 + 2 do // begin idx := 0; while idx < ((MIN_M - 1) + k) do // (MIN_M - 1) + k begin node_1.Children[idx] := arr_node[idx]; idx := idx + 1; end; for idx := idx to High(arr_node) do // begin node_2.Children[idx - ((MIN_M - 1) + k)] := arr_node[idx]; end; updateMBR(node_1); updateMBR(node_2); perimeter := perimeter + node_1.margin + node_2.margin; end; end; if perimeter <= perimeter_min then begin Result := TAxis(i); perimeter_min := perimeter; end; perimeter := 0; end; FreeAndNil(node_1); FreeAndNil(node_2); SetLength(arr_node, 0); end; procedure TRtree.chooseSubtree(obj: TRObject; var node_id: Integer); var i, id_child: Integer; min_overlap_enlargement: Double; // Overlap_enlargement: Double; area_enlargement: Double; idChild_overlap: array of Integer; { . , , MBR } idChild_area: array of Integer; { . , MBR , MBR } id_zero: Integer; { MBR ( MBR) } enlargement_mbr: TMBR; // MBR dx, dy, dspace: Double; // MBR x, y has_no_enlargement: Boolean; // begin if FNodeArr[node_id].isLeaf then // , begin Exit; end; SetLength(idChild_overlap, 1); SetLength(idChild_area, 1); dx := 0; dy := 0; dspace := 9999999; id_zero := 0; has_no_enlargement := False; min_overlap_enlargement := 999999; if FNodeArr[FNodeArr[node_id].Children[0]].isLeaf then // () begin { } for i := 0 to High(FNodeArr[node_id].FChildren) do begin id_child := FNodeArr[node_id].FChildren[i]; Overlap_enlargement := FNodeArr[id_child].Area(obj.mbr) - FNodeArr[id_child].Overlap(obj.mbr); if Overlap_enlargement <= min_overlap_enlargement then begin if Overlap_enlargement = min_overlap_enlargement then // begin SetLength(idChild_overlap, Length(idChild_overlap) + 1); idChild_overlap[ High(idChild_overlap)] := i; end else // begin min_overlap_enlargement := Overlap_enlargement; if Length(idChild_overlap) = 1 then // idChild_overlap[0] := i else begin SetLength(idChild_overlap, 1); // , 1 idChild_overlap[0] := i end; end; end; end; if Length(idChild_overlap) = 1 then // 1 begin node_id := FNodeArr[node_id].Children[idChild_overlap[0]]; chooseSubtree(obj, node_id); // Exit; end; end else // begin SetLength(idChild_overlap, Length(FNodeArr[node_id].FChildren)); for i := 0 to High(FNodeArr[node_id].FChildren) do // idChild_overlap, ( , idChild_overlap ) idChild_overlap[i] := i; end; { } for i := 0 to High(idChild_overlap) do begin id_child := FNodeArr[node_id].FChildren[idChild_overlap[i]]; enlargement_mbr.Left.X := Min(obj.mbr.Left.X, FNodeArr[id_child].mbr.Left.X); enlargement_mbr.Left.Y := Min(obj.mbr.Left.Y, FNodeArr[id_child].mbr.Left.Y); enlargement_mbr.Right.X := Max(obj.mbr.Right.X, FNodeArr[id_child].mbr.Right.X); enlargement_mbr.Right.Y := Max(obj.mbr.Right.Y, FNodeArr[id_child].mbr.Right.Y); area_enlargement := FNodeArr[id_child].Area(enlargement_mbr) - FNodeArr[id_child].Area; if area_enlargement <= dspace then begin if area_enlargement = dspace then // begin SetLength(idChild_area, Length(idChild_area) + 1); idChild_area[ High(idChild_area)] := i; end else // begin dspace := area_enlargement; if Length(idChild_area) = 1 then // idChild_area[0] := i else begin SetLength(idChild_area, 1); // , 1 idChild_area[0] := i end; end; end; end; if Length(idChild_area) = 1 then // , MBR begin node_id := FNodeArr[node_id].Children[idChild_area[0]]; chooseSubtree(obj, node_id); // end else // ( MBR ) MBR begin dspace := 999999; for i := 0 to High(idChild_area) do begin id_child := FNodeArr[node_id].Children[idChild_area[i]]; if FNodeArr[id_child].Area < dspace then begin id_zero := idChild_area[i]; dspace := FNodeArr[id_child].Area; end; end; node_id := FNodeArr[node_id].Children[id_zero]; chooseSubtree(obj, node_id); end; end; constructor TRtree.Create; begin inherited; SetLength(FNodeArr, 1); FNodeArr[0] := TRNode.Create; FRoot := 0; FNodeArr[FRoot].FisLeaf := True; end; destructor TRtree.Destroy; var i: Integer; begin for i := 0 to High(FNodeArr) do FreeAndNil(FNodeArr[i]); SetLength(FNodeArr, 0); inherited; end; procedure TRtree.findObjectsInArea(mbr: TMBR; node_id: Integer; var obj: TObjArr); var i: Integer; begin if isRoot(node_id) then SetLength(obj, 0); if not FNodeArr[node_id].isLeaf then begin for i := 0 to High(FNodeArr[node_id].FChildren) do begin if FNodeArr[FNodeArr[node_id].Children[i]].isIntersected(mbr) then findObjectsInArea(mbr, FNodeArr[node_id].Children[i], obj); end; end else begin for i := 0 to High(FNodeArr[node_id].FObjects) do begin if FNodeArr[node_id].isIntersected(mbr, FNodeArr[node_id].Objects[i].mbr) then begin SetLength(obj, Length(obj) + 1); obj[ High(obj)] := FNodeArr[node_id].Objects[i].idx; end; end; end; end; procedure TRtree.findObjectsInArea(mbr: TMBR; var obj: TObjArr); begin findObjectsInArea(mbr, FRoot, obj); end; procedure TRtree.insertObject(obj: TRObject); var node_id: Integer; begin node_id := FRoot; chooseSubtree(obj, node_id); if Length(FNodeArr[node_id].FObjects) < MAX_M then // begin FNodeArr[node_id].Objects[ High(FNodeArr[node_id].FObjects) + 1] := obj; updateMBR(node_id); end else // begin splitNodeRStar(node_id, obj); // end; end; function TRtree.isRoot(node_id: Integer): Boolean; begin if node_id = FRoot then Result := True else Result := False; end; function TRtree.newNode: Integer; begin SetLength(FNodeArr, Length(FNodeArr) + 1); FNodeArr[ High(FNodeArr)] := TRNode.Create; Result := High(FNodeArr); end; procedure TRtree.QuickSort(var List: array of TRObject; iLo, iHi: Integer; axe: TAxis; bound: TBound); var Lo: Integer; Hi: Integer; T: TRObject; Mid: Double; begin Lo := iLo; Hi := iHi; case bound of Left: case axe of X: Mid := List[(Lo + Hi) div 2].mbr.Left.X; Y: Mid := List[(Lo + Hi) div 2].mbr.Left.Y; end; Right: case axe of X: Mid := List[(Lo + Hi) div 2].mbr.Right.X; Y: Mid := List[(Lo + Hi) div 2].mbr.Right.Y; end; end; repeat case bound of Left: case axe of X: begin while List[Lo].mbr.Left.X < Mid do Inc(Lo); while List[Hi].mbr.Left.X > Mid do Dec(Hi); end; Y: begin while List[Lo].mbr.Left.Y < Mid do Inc(Lo); while List[Hi].mbr.Left.Y > Mid do Dec(Hi); end; end; Right: case axe of X: begin while List[Lo].mbr.Right.X < Mid do Inc(Lo); while List[Hi].mbr.Right.X > Mid do Dec(Hi); end; Y: begin while List[Lo].mbr.Right.Y < Mid do Inc(Lo); while List[Hi].mbr.Right.Y > Mid do Dec(Hi); end; end; end; if Lo <= Hi then begin T := List[Lo]; List[Lo] := List[Hi]; List[Hi] := T; Inc(Lo); Dec(Hi); end; until Lo > Hi; if Hi > iLo then QuickSort(List, iLo, Hi, axe, bound); if Lo < iHi then QuickSort(List, Lo, iHi, axe, bound); end; procedure TRtree.QuickSort(var List: array of Integer; iLo, iHi: Integer; axe: TAxis; bound: TBound); var Lo: Integer; Hi: Integer; T: Integer; Mid: Double; begin Lo := iLo; Hi := iHi; case bound of Left: case axe of X: Mid := FNodeArr[List[(Lo + Hi) div 2]].mbr.Left.X; Y: Mid := FNodeArr[List[(Lo + Hi) div 2]].mbr.Left.Y; end; Right: case axe of X: Mid := FNodeArr[List[(Lo + Hi) div 2]].mbr.Right.X; Y: Mid := FNodeArr[List[(Lo + Hi) div 2]].mbr.Right.Y; end; end; repeat case bound of Left: case axe of X: begin while FNodeArr[List[Lo]].mbr.Left.X < Mid do Inc(Lo); while FNodeArr[List[Hi]].mbr.Left.X > Mid do Dec(Hi); end; Y: begin while FNodeArr[List[Lo]].mbr.Left.Y < Mid do Inc(Lo); while FNodeArr[List[Hi]].mbr.Left.Y > Mid do Dec(Hi); end; end; Right: case axe of X: begin while FNodeArr[List[Lo]].mbr.Right.X < Mid do Inc(Lo); while FNodeArr[List[Hi]].mbr.Right.X > Mid do Dec(Hi); end; Y: begin while FNodeArr[List[Lo]].mbr.Right.Y < Mid do Inc(Lo); while FNodeArr[List[Hi]].mbr.Right.Y > Mid do Dec(Hi); end; end; end; if Lo <= Hi then begin T := List[Lo]; List[Lo] := List[Hi]; List[Hi] := T; Inc(Lo); Dec(Hi); end; until Lo > Hi; if Hi > iLo then QuickSort(List, iLo, Hi, axe, bound); if Lo < iHi then QuickSort(List, Lo, iHi, axe, bound); end; procedure TRtree.splitNodeRStar(splited_Node_Id, inserted_Node_Id: Integer); var axe: TAxis; parent_id, new_child_id: Integer; node_1, node_2, node_1_min, node_2_min: TRNode; i, j, k: Integer; arr_node: array of Integer; area_overlap_min, area_overlap, // area_min, Area: Double; // begin if FNodeArr[splited_Node_Id].isLeaf then Exit; if isRoot(splited_Node_Id) then begin parent_id := newNode; // id FNodeArr[FRoot].Parent := parent_id; // id , FNodeArr[parent_id].Children[0] := FRoot; // id FNodeArr[parent_id].Level := FNodeArr[FNodeArr[parent_id].Children[0]].Level + 1; // 1 FRoot := parent_id; // id id FHeight := FHeight + 1; // end else begin parent_id := FNodeArr[splited_Node_Id].Parent; end; SetLength(arr_node, MAX_M + 1); for i := 0 to High(arr_node) - 1 do arr_node[i] := FNodeArr[splited_Node_Id].Children[i]; arr_node[ High(arr_node)] := inserted_Node_Id; node_1_min := TRNode.Create; node_2_min := TRNode.Create; node_1 := TRNode.Create; node_2 := TRNode.Create; axe := chooseSplitAxis(splited_Node_Id, inserted_Node_Id); area_overlap_min := 9999999; area_min := 9999999; for i := 0 to 1 do begin QuickSort(arr_node, 0, High(arr_node), axe, TBound(i)); for k := MIN_M - 1 to MAX_M - MIN_M do begin node_1.clearChildren; node_2.clearChildren; j := 0; while j <= k do begin node_1.Children[j] := arr_node[j]; j := j + 1; end; for j := k to High(arr_node) - 1 do begin node_2.Children[j - k] := arr_node[j + 1]; end; updateMBR(node_1); updateMBR(node_2); area_overlap := node_1.Overlap(node_2.mbr); if area_overlap < area_overlap_min then begin node_1_min.copy(node_1); node_2_min.copy(node_2); area_overlap_min := area_overlap; end else begin if area_overlap = area_overlap_min then // begin Area := node_1.Area + node_2.Area; // if Area < area_min then begin node_1_min.copy(node_1); node_2_min.copy(node_2); area_min := Area; end; end; end; end; end; node_1_min.Level := FNodeArr[splited_Node_Id].Level; node_2_min.Level := FNodeArr[splited_Node_Id].Level; FNodeArr[splited_Node_Id].copy(node_1_min); // () FNodeArr[splited_Node_Id].Parent := parent_id; new_child_id := newNode; // FNodeArr[new_child_id].copy(node_2_min); // FNodeArr[new_child_id].Parent := parent_id; // id parent FreeAndNil(node_1); FreeAndNil(node_2); FreeAndNil(node_1_min); FreeAndNil(node_2_min); for i := 0 to High(FNodeArr[new_child_id].FChildren) do // Parent id begin FNodeArr[FNodeArr[new_child_id].Children[i]].Parent := new_child_id end; if Length(FNodeArr[parent_id].FChildren) < MAX_M then // begin FNodeArr[parent_id].Children[ High(FNodeArr[parent_id].FChildren) + 1] := new_child_id; // id updateMBR(parent_id); end else // begin splitNodeRStar(parent_id, new_child_id); // end; end; procedure TRtree.splitNodeRStar(node_id: Integer; obj: TRObject); var axe: TAxis; parent_id, new_child_id: Integer; node_1, node_2, node_1_min, node_2_min: TRNode; i, j, k: Integer; arr_obj: array of TRObject; area_overlap_min, area_overlap, // area_min, Area: Double; // begin if not FNodeArr[node_id].isLeaf then Exit; if isRoot(node_id) then begin parent_id := newNode; // id FNodeArr[FRoot].Parent := parent_id; // id , FNodeArr[parent_id].Children[0] := FRoot; // id FNodeArr[parent_id].Level := FNodeArr[FNodeArr[parent_id].Children[0]].Level + 1; // 1 FRoot := parent_id; // id id FHeight := FHeight + 1; // end else begin parent_id := FNodeArr[node_id].Parent; end; SetLength(arr_obj, MAX_M + 1); for i := 0 to High(arr_obj) - 1 do arr_obj[i] := FNodeArr[node_id].Objects[i]; arr_obj[ High(arr_obj)] := obj; node_1_min := TRNode.Create; node_2_min := TRNode.Create; node_1 := TRNode.Create; node_2 := TRNode.Create; axe := chooseSplitAxis(obj, node_id); area_overlap_min := 9999999; area_min := 9999999; for i := 0 to 1 do begin QuickSort(arr_obj, 0, High(arr_obj), axe, TBound(i)); for k := MIN_M - 1 to MAX_M - MIN_M do begin node_1.clearObjects; node_2.clearObjects; j := 0; while j <= k do begin node_1.Objects[j] := arr_obj[j]; j := j + 1; end; for j := k to High(arr_obj) - 1 do begin node_2.Objects[j - k] := arr_obj[j + 1]; end; updateMBR(node_1); updateMBR(node_2); area_overlap := node_1.Overlap(node_2.mbr); if area_overlap < area_overlap_min then begin node_1_min.copy(node_1); node_2_min.copy(node_2); area_overlap_min := area_overlap; end else begin if area_overlap = area_overlap_min then // begin Area := node_1.Area + node_2.Area; // if Area < area_min then begin node_1_min.copy(node_1); node_2_min.copy(node_2); area_min := Area; end; end; end; end; end; node_1_min.Level := 0; node_2_min.Level := 0; FNodeArr[node_id].copy(node_1_min); // () FNodeArr[node_id].Parent := parent_id; updateMBR(node_id); new_child_id := newNode; // FNodeArr[new_child_id].copy(node_2_min); // FNodeArr[new_child_id].Parent := parent_id; // id parent updateMBR(new_child_id); FreeAndNil(node_1); FreeAndNil(node_2); FreeAndNil(node_1_min); FreeAndNil(node_2_min); if Length(FNodeArr[parent_id].FChildren) < MAX_M then // begin FNodeArr[parent_id].Children[ High(FNodeArr[parent_id].FChildren) + 1] := new_child_id; // id updateMBR(parent_id); end else // begin splitNodeRStar(parent_id, new_child_id); // end; end; procedure TRtree.updateMBR(node: TRNode); var i, idx: Integer; changed: Boolean; begin changed := False; node.fmbr.Left.X := 9999; node.fmbr.Left.Y := 9999; node.fmbr.Right.X := 0; node.fmbr.Right.Y := 0; if node.isLeaf then begin for i := 0 to High(node.FObjects) do begin if node.FObjects[i].mbr.Left.X < node.mbr.Left.X then begin node.fmbr.Left.X := node.FObjects[i].mbr.Left.X; changed := True; end; if node.FObjects[i].mbr.Left.Y < node.mbr.Left.Y then begin node.fmbr.Left.Y := node.FObjects[i].mbr.Left.Y; changed := True; end; if node.FObjects[i].mbr.Right.X > node.mbr.Right.X then begin node.fmbr.Right.X := node.FObjects[i].mbr.Right.X; changed := True; end; if node.FObjects[i].mbr.Right.Y > node.mbr.Right.Y then begin node.fmbr.Right.Y := node.FObjects[i].mbr.Right.Y; changed := True; end; end; end else begin for i := 0 to High(node.FChildren) do begin idx := node.FChildren[i]; if FNodeArr[idx].mbr.Left.X < node.mbr.Left.X then begin node.fmbr.Left.X := FNodeArr[idx].mbr.Left.X; changed := True; end; if FNodeArr[idx].mbr.Left.Y < node.mbr.Left.Y then begin node.fmbr.Left.Y := FNodeArr[idx].mbr.Left.Y; changed := True; end; if FNodeArr[idx].mbr.Right.X > node.mbr.Right.X then begin node.fmbr.Right.X := FNodeArr[idx].mbr.Right.X; changed := True; end; if FNodeArr[idx].mbr.Right.Y > node.mbr.Right.Y then begin node.fmbr.Right.Y := FNodeArr[idx].mbr.Right.Y; changed := True; end; end; end; if changed then begin if node.Parent >= 0 then updateMBR(node.Parent); end; end; procedure TRtree.updateMBR(node_id: Integer); var i, idx: Integer; changed: Boolean; begin changed := False; FNodeArr[node_id].fmbr.Left.X := 9999; FNodeArr[node_id].fmbr.Left.Y := 9999; FNodeArr[node_id].fmbr.Right.X := 0; FNodeArr[node_id].fmbr.Right.Y := 0; if FNodeArr[node_id].isLeaf then begin for i := 0 to High(FNodeArr[node_id].FObjects) do begin if FNodeArr[node_id].FObjects[i].mbr.Left.X < FNodeArr[node_id].mbr.Left.X then begin FNodeArr[node_id].fmbr.Left.X := FNodeArr[node_id].FObjects[i].mbr.Left.X; changed := True; end; if FNodeArr[node_id].FObjects[i].mbr.Left.Y < FNodeArr[node_id].mbr.Left.Y then begin FNodeArr[node_id].fmbr.Left.Y := FNodeArr[node_id].FObjects[i].mbr.Left.Y; changed := True; end; if FNodeArr[node_id].FObjects[i].mbr.Right.X > FNodeArr[node_id].mbr.Right.X then begin FNodeArr[node_id].fmbr.Right.X := FNodeArr[node_id].FObjects[i].mbr.Right.X; changed := True; end; if FNodeArr[node_id].FObjects[i].mbr.Right.Y > FNodeArr[node_id].mbr.Right.Y then begin FNodeArr[node_id].fmbr.Right.Y := FNodeArr[node_id].FObjects[i].mbr.Right.Y; changed := True; end; end; end else begin for i := 0 to High(FNodeArr[node_id].FChildren) do begin idx := FNodeArr[node_id].FChildren[i]; if FNodeArr[idx].mbr.Left.X < FNodeArr[node_id].mbr.Left.X then begin FNodeArr[node_id].fmbr.Left.X := FNodeArr[idx].mbr.Left.X; changed := True; end; if FNodeArr[idx].mbr.Left.Y < FNodeArr[node_id].mbr.Left.Y then begin FNodeArr[node_id].fmbr.Left.Y := FNodeArr[idx].mbr.Left.Y; changed := True; end; if FNodeArr[idx].mbr.Right.X > FNodeArr[node_id].mbr.Right.X then begin FNodeArr[node_id].fmbr.Right.X := FNodeArr[idx].mbr.Right.X; changed := True; end; if FNodeArr[idx].mbr.Right.Y > FNodeArr[node_id].mbr.Right.Y then begin FNodeArr[node_id].fmbr.Right.Y := FNodeArr[idx].mbr.Right.Y; changed := True; end; end; end; if changed then begin if FNodeArr[node_id].Parent >= 0 then updateMBR(FNodeArr[node_id].Parent); end; end; end.
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд╛рдж, рдЬреЛ рдХреБрдЫ рдХрд░рдирд╛ рдмрд╛рдХреА рдерд╛, рд╡рд╣ рд╡реЗрдХреНрдЯрд░ рдореИрдк рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рдкрд░рддреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рдерд╛, рдЗрди рдкрд░рддреЛрдВ рдХреЛ рдЕрдзрд┐рдХрддрдо рдкреИрдорд╛рдиреЗ рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВ рдЬрд┐рд╕ рдкрд░ рд╡реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдВрдЧреЗ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдкрд░рдд рдХреЗ рд▓рд┐рдП R * -tree рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВрдЧреЗред
рдкрд░рд┐рдгрд╛рдо рд╡реАрдбрд┐рдпреЛ рдкрд░ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ: