Жаккард оценка / расстояние или процентное совпадение
Я хочу, чтобы можно было рассчитать балл Жакара / расстояние (расстояние 1 балл) одного прямоугольника по сетке прямоугольников. Моя сетка 50х50 (всего 1625625 прямоугольников).
Я могу рассчитать счет моего входного прямоугольника по всем этим за 0,34 секунды, но это не достаточно быстро, так как мне нужно либо иметь возможность обрабатывать 10 тыс. Прямоугольников, либо сохранять результат в БД (обновляя десятки тысяч строки каждый вызов). Поэтому я надеялся, что БД сделает за меня вычисления, и мне не придется ничего вытаскивать из БД, однако я не могу придумать, как это сделать без курсоров...
sourceRectangles
содержит мой единственный прямоугольник (хотя в действительности будет 10 КБ), rectangles
содержит мою сетку и temporaryRectangleList
содержит сумму баллов.
Dictionary<UInt32, Rectangle> temporaryRectangleList = new Dictionary<UInt32, Rectangle>();
foreach (var sourceRectangle in sourceRectangles)
{
foreach (var rectangle in rectangles)
{
// For each rectangle within the group
//foreach (var rectangle in group)
//{
int max_MinX = Math.Max(sourceRectangle.MinX, rectangle.MinX);
int min_MaxX = Math.Min(sourceRectangle.MaxX, rectangle.MaxX);
// There is an overlap
//if (max_MinX < min_MaxX)
//{
int max_MinY = Math.Max(sourceRectangle.MinY, rectangle.MinY);
int min_MaxY = Math.Min(sourceRectangle.MaxY, rectangle.MaxY);
// Calculate the area of the overlap
int area = ((min_MaxX - max_MinX)*(min_MaxY - max_MinY));
// Store the Jaccard score
var score = (double) area/((sourceRectangle.Area + rectangle.Area) - area);
if (temporaryRectangleList.ContainsKey(rectangle.ID))
{
temporaryRectangleList[rectangle.ID].Weight += score;
}
else
{
temporaryRectangleList.Add(rectangle.ID, new Rectangle(rectangle, score));
}
}
}
Мне нужно иметь возможность искать элементы в словаре, так как мне нужно вытащить данные из него через идентификатор прямоугольника.
Если вы думаете, что вы можете ускорить C#, чтобы быть быстрее (процесс с 10k прямоугольников <1 с), тогда сделайте это, но.34 s - лучшее, что я могу сделать для каждого прямоугольника, поэтому я ищу SQL-эквивалент этого кода (в идеале хотя лучше... смеется)
К сожалению, таблица SQL слишком велика, чтобы вывести ее сюда, поэтому я могу лишь дать вам структуру:
USE [Rectangles]
GO
/****** Object: Table [dbo].[PreProcessed] Script Date: 14/01/2014 16:39:33 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[PreProcessed](
[ID] [int] NOT NULL,
[MinX] [int] NOT NULL,
[MinY] [int] NOT NULL,
[MaxX] [int] NOT NULL,
[MaxY] [int] NOT NULL,
[Area] [int] NOT NULL,
CONSTRAINT [PK_PreProcessed] PRIMARY KEY CLUSTERED
(
[ID] ASC,
[Area] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Класс прямоугольника:
public class Rectangle
{
public Rectangle(UInt32 id, int minX, int maxX, int minY, int maxY, double weight)
{
ID = id;
MinX = minX;
MaxX = maxX;
MinY = minY;
MaxY = maxY;
Area = (maxX - minX)*(maxY - minY);
Weight = weight;
}
public Rectangle(Rectangle input, double weight)
{
ID = input.ID;
MinX = input.MinX;
MaxX = input.MaxX;
MinY = input.MinY;
MaxY = input.MaxY;
Area = input.Area;
Weight = weight;
}
public int Area { get; set; }
public int MinX { get; set; }
public int MaxX { get; set; }
public int MinY { get; set; }
public int MaxY { get; set; }
public UInt32 ID { get; set; }
public double Weight { get; set; }
}
1 ответ
SQL Server имеет geometry
тип данных. У этого есть методы для вычисления пересечения и объединения многоугольников.