2013-04-17 2 views
9

Мой проект о реализации гиперграфа в JavaКак избежать дублирования кода в этом случае?

Мои HyperGraph содержат различные типы гиперребро в зависимости от типа вершины, что у меня есть

Vertex Тип: изображения, теги ...

гиперребро = Однородная (касаются вершин того же типа)/Гетерогенного (касаются вершин другого типа)

Однородных гиперребро = изображение-изображений гиперребро/Tag-тег гиперребро

Тхи s является быстро рисовать UML диаграмму

enter image description here

enter image description here это мой код

public interface HomogenousHyperedge< T extends Vertex<L>, L> extends Hyperedge { 

    public abstract List<T> searchNearstNeighborsVertex(
     Hypergraph hypergraph, T vertex); 
} 


public class ImageImageHyperedge implements 
    HomogenousHyperedge<ImageVertex, Map<String,Instance>> { 

    @Override 
    public List<ImageVertex> searchNearstNeighborsVertex(Hypergraph hypergraph, 
     ImageVertex vertex) { 
     return null; 
    } 
} 

проблема в классе ImageImageHyperEdge я должен знать, что тип функции, основанный на ней, я буду искать ближайших соседей ImageVertexя не могу передать его в абстрактный метод супер интерфейс, потому что TagTagHyperEdge класс не нужен ему

и если я заменю класс ImageImageHyperEdge от {featureOneHyperEdge класс ... featureFiveHyperEdge класс} (в котором я знаю тип объекта) это будет дублированием кода, как это тот же ближайших соседи алгоритм поиска


функции = низкая функция уровня изображения (цвет гистограмма, например)
у меня 5 типа низкого уровня feature
Я буду использовать каждый для поиска ближайшего ne ighbors моего текущего изображения
Всех функции снабжены в простом текстовом файле
тот же алгоритм используется для поиска ближайших соседей
только файл изменяется каждый раз, когда

+0

Я не уверен, что правильно понял, что вам нужно, так что это может пойти в любом случае. У вас есть базовый класс BaseFeatureHyperEdge, который будет реализовывать алгоритм поиска. И выложите какой-то метод шаблона, который будет переопределен FeatureOneHyperEdge, FeatureTwoHyperEdge и т. Д. Этот метод шаблона должен предоставлять только тип функции, на которой основан поиск. Надеюсь, поможет? –

+0

@DenisRosca первая идея, которую я получил, - использовать шаблон стратегии Я думаю, что он похож на шаблон шаблона вы можете объяснить больше, чем вы идете, пожалуйста? – nawara

+0

Я предполагаю, что добавлю ответ –

ответ

0

Основываясь на том, что вы написали о «функции », Я бы сказал, что это будет подходящим полем в вашем классе ImageImageHyperEdge. Вы можете создать класс FeatureType с любыми различными членами, которые его определят.

public class ImageImageHyperedge implements 
    HomogenousHyperedge<ImageVertex, Map<String,Instance>> { 

    private FeatureType featureType; 

    @Override 
    public List<ImageVertex> searchNearstNeighborsVertex(Hypergraph hypergraph, 
     ImageVertex vertex) { 
     return null; 
    } 
} 
+0

, подкласс класса наследует реалистичную конкретизацию, но как он узнает тип функции? – nawara

+0

Не будет ли сам класс указывать тип функции? Как и в, не будет ли FeatureOneHyperEdge указывать, что тип функции - «FeatureOne»? –

+0

Да, но как будет реализована конкретизация в суперклассе? – nawara

0

Попробуйте что-нибудь в этом роде?

public abstract class BaseFeatureHyperEdge { 

    @Override 
    public List<ImageVertex> searchNearstNeighborsVertex(Hypergraph hypergraph, 
     ImageVertex vertex) { 
     // implement nearest neighbor search algorithm 
     // and call getFeatureType where you need it. 
     // This will allow you to have the search algorithm only in one place. 
     //But make the search based on the feature type; 
    } 

    protected FeatureType getFeatureType(); 
} 

public class FeatureOneHyperEdge extends BaseFeatureHyperEdge{ 

    @Override 
    protected FeatureType getFeatureType() { 
     return new FeatureTypeOne(); 
    } 
} 


public class FeatureTwoHyperEdge extends BaseFeatureHyperEdge{ 

    @Override 
    protected FeatureType getFeatureType() { 
     return new FeatureTypeTwo(); 
    } 
} 

Возможно, вы можете попробовать Template Method Pattern?

+0

Я понятия не имею об этом – nawara

1

Ваш дизайн UML не достаточно хорош. Пропустите уродливый & сложный для чтения «стиль», покажите нам «Вершину», а также «Край» и диаграмму ассоциации; а не вашей (потенциально чрезмерной) идеей наследования.

Ваши API, дизайн & Основной вопрос не совсем ясен.Классы «Hyperedge» могут представлять один экземпляр Edge и связывать два конца этого; или они могут (если лучше названы) представлять тип Edge и искать глобальный график по заданному параметру конечной точки.

Это совершенно разные конструкции, ваш вопрос бессмыслен, пока вы не рисуете выше.

В любом случае, Edge.search() не имеет правильной подписи. Где VS и VE является начальными и конечными вершинами-типом, и ТОТ краевой тип, он должен быть либо:

public class EdgeType { 
    public List<EV> getEndpoints (SV startVertex); 
} 

или

public class Vertex { 
    public List<TE> Vertex.getEdges(); 
} 
public class Edge { 
    public EV Edge.getEndpoint(); 
} 

Алгоритм ближайшего соседа должен быть реализован с использованием обобщенных типов , а затем вызвал по требованию (с точными типами-сигнатурами) конкретные классы.

BTW, когда вы упоминаете «ближайший сосед»; Не ясно также, что «ближайший сосед» означает напрямую связанную вершину, что является тривиальным, или найти ближайшую удаленную (как измеряется расстояние, которую вы не указали), вершину указанного типа.

В любом случае, утилита & правильность/необходимость реализации подтипов «края» кажется неясной. Многие алгоритмы графа находят Вершины/Узлы интересными и подтипами, но я меньше, чем знаю о подтипировании (или полезности подтипирования) ребер, ведущих к ним.

Последний совет: канавы комплексного именования, KISS. «Vertex» и «Edge» помогут вам получить четкий, простой, понятный & правильный дизайн. Сохраните дополнительный файл для после у вас есть это.


В ответ на новые данные из Навара:

Тогда Это EdgeType вы смоделировали, и когда просят «ближайшего соседа» вы должны принять Start Vertex & возврата либо Грань (S) - если вам нужны метрики расстояния - или Вершины.

Ссылка на «График» должна быть, вероятно, неявной из параметра Vertex.

Что касается вашего наследства наследования типа EdgeType: подтипы & Наследование должно определяться с учетом поведенческих характеристик, а не общих типов (типов вершин), которые они ссылаются. Принцип построения иерархии класса OO заключается в модели , выполняющей, а не , являющийся.

В этом отношении у вас могут быть классы KnnDistanceEdgeType & FlickrDistanceEdgeType, либо как предки, либо, если иное поведение метода не должно быть иным, как фактические классы реализации. Типы объектов/классы, которые они ищут, могут быть заданы как свойства - со свойствами & обобщены по-разному, чтобы отвечать на разные типы вершин.

например.

IMAGE_IMAGE_EDGES = new KnnDistanceEdgeType<ImageVertex,ImageVertex>(ImageVertex.class, ImageVertex.class); 
TAG_TAG_EDGES = new FlickrDistanceEdgeType<TagVertex,TagVertex>(TagVertex.class, TagVertex.class); 
ANY_EDGES = new KnnDistanceEdgeType<Vertex,Vertex>(Vertex.class, Vertex.class); 

Если есть много другого поведения (мы не определили, и не можем себе представить, много) в EdgeType, вы могли бы переместить алгоритмы KNN- и Flickr расстояния от до отдельных классов. Наверное, не нужно.

Помните: в OO подкласс для поведения, а не для существования. И дайте мне +1 голос!

+0

У меня сложный гиперграф G = (V, E), V - множество вершин, которое может содержать разные типы вершин (изображение, тег , locaetion ...), а E - это набор гиперэлементов, которые также содержат разные типы ребер (края между изображениями, между тегами, между изображением и тегом). способ нахождения вершины падения каждого гиперэдера отличается в соответствии с типом hyperEdge для пример в случае hyperEdge, начальной и конечной точкой которого является изображение. vertex. Я использую алгоритм knn (с эвклидовым расстоянием) в случае hypeEdge, начальная и конечная точка которого являются тегами. Я использую расстояние Flickr – nawara

+0

, поэтому я думаю, что я должен использовать абстрактный класс 'hyperedge' и множественный подкласс наследуются от него, и каждый из них представляет собой другой тип hyperEdge e – nawara

+0

В этом случае это EdgeKind или EdgeType - и вы задаете ему задание StartVertex и отвечаете на Edge или Vertex как результат; Край, если вам нужно расстояние, Вершина, если вы этого не сделаете. –

Смежные вопросы