As initial value of a new map expression with ()+-/* operators can be given. These operators work on numbers, or on maps. If maps are given, then the new value for a given graph element will be calculated using the value from the given maps that belong to that graph element.
2 * lemon/concept/graph_component.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 ///\ingroup graph_concepts
19 ///\brief The graph components.
22 #ifndef LEMON_CONCEPT_GRAPH_COMPONENT_H
23 #define LEMON_CONCEPT_GRAPH_COMPONENT_H
25 #include <lemon/invalid.h>
26 #include <lemon/concept/maps.h>
28 #include <lemon/bits/alteration_notifier.h>
33 /**************** Graph iterator concepts ****************/
35 /// Skeleton class for graph Node and Edge types
37 /// This class describes the interface of Node and Edge (and UndirEdge
38 /// in undirected graphs) subtypes of graph types.
40 /// \note This class is a template class so that we can use it to
41 /// create graph skeleton classes. The reason for this is than Node
42 /// and Edge types should \em not derive from the same base class.
43 /// For Node you should instantiate it with character 'n' and for Edge
47 template <char _selector = '0'>
51 /// Default constructor.
53 /// \warning The default constructor is not required to set
54 /// the item to some well-defined value. So you should consider it
61 GraphItem(GraphItem const&) {}
62 /// Invalid constructor \& conversion.
64 /// This constructor initializes the item to be invalid.
65 /// \sa Invalid for more details.
67 /// Assign operator for nodes.
69 /// The nodes are assignable.
71 GraphItem& operator=(GraphItem const&) { return *this; }
72 /// Equality operator.
74 /// Two iterators are equal if and only if they represents the
75 /// same node in the graph or both are invalid.
76 bool operator==(GraphItem) const { return false; }
77 /// Inequality operator.
79 /// \sa operator==(const Node& n)
81 bool operator!=(GraphItem) const { return false; }
83 /// Artificial ordering operator.
85 /// To allow the use of graph descriptors as key type in std::map or
86 /// similar associative container we require this.
88 /// \note This operator only have to define some strict ordering of
89 /// the items; this order has nothing to do with the iteration
90 /// ordering of the items.
92 /// \bug This is a technical requirement. Do we really need this?
93 bool operator<(GraphItem) const { return false; }
95 template<typename _GraphItem>
100 _GraphItem i3 = INVALID;
105 // b = (ia == ib) && (ia != ib) && (ia < ib);
106 b = (ia == ib) && (ia != ib);
107 b = (ia == INVALID) && (ib != INVALID);
111 const _GraphItem &ia;
112 const _GraphItem &ib;
116 /// A type describing the concept of graph node
118 /// This is an instantiation of \ref GraphItem which can be used as a
119 /// Node subtype in graph skeleton definitions
120 typedef GraphItem<'n'> GraphNode;
122 /// A type describing the concept of graph edge
124 /// This is an instantiation of \ref GraphItem which can be used as a
125 /// Edge subtype in graph skeleton definitions
126 typedef GraphItem<'e'> GraphEdge;
129 /**************** Basic features of graphs ****************/
131 /// An empty base graph class.
133 /// This class provides the minimal set of features needed for a graph
134 /// structure. All graph concepts have to be conform to this base
137 /// \bug This is not true. The minimal graph concept is the
138 /// BaseIterableGraphComponent.
140 class BaseGraphComponent {
143 typedef BaseGraphComponent Graph;
145 /// Node class of the graph.
147 /// This class represents the Nodes of the graph.
149 typedef GraphItem<'n'> Node;
151 /// Edge class of the graph.
153 /// This class represents the Edges of the graph.
155 typedef GraphItem<'e'> Edge;
157 ///Gives back the target node of an edge.
159 ///Gives back the target node of an edge.
161 Node target(const Edge&) const { return INVALID;}
163 ///Gives back the source node of an edge.
165 ///Gives back the source node of an edge.
167 Node source(const Edge&) const { return INVALID;}
170 template <typename _Graph>
172 typedef typename _Graph::Node Node;
173 typedef typename _Graph::Edge Edge;
176 checkConcept<GraphItem<'n'>, Node>();
177 checkConcept<GraphItem<'e'>, Edge>();
190 /// An empty iterable base graph class.
192 /// This class provides beside the core graph features
193 /// core iterable interface for the graph structure.
194 /// Most of the base graphs should be conform to this concept.
196 class BaseIterableGraphComponent : virtual public BaseGraphComponent {
199 typedef BaseGraphComponent::Node Node;
200 typedef BaseGraphComponent::Edge Edge;
202 /// Gives back the first Node in the iterating order.
204 /// Gives back the first Node in the iterating order.
206 void first(Node&) const {}
208 /// Gives back the next Node in the iterating order.
210 /// Gives back the next Node in the iterating order.
212 void next(Node&) const {}
214 /// Gives back the first Edge in the iterating order.
216 /// Gives back the first Edge in the iterating order.
218 void first(Edge&) const {}
219 /// Gives back the next Edge in the iterating order.
221 /// Gives back the next Edge in the iterating order.
223 void next(Edge&) const {}
226 /// Gives back the first of the Edges point to the given Node.
228 /// Gives back the first of the Edges point to the given Node.
230 void firstIn(Edge&, const Node&) const {}
232 /// Gives back the next of the Edges points to the given Node.
235 /// Gives back the next of the Edges points to the given Node.
237 void nextIn(Edge&) const {}
239 /// Gives back the first of the Edges start from the given Node.
241 /// Gives back the first of the Edges start from the given Node.
243 void firstOut(Edge&, const Node&) const {}
245 /// Gives back the next of the Edges start from the given Node.
247 /// Gives back the next of the Edges start from the given Node.
249 void nextOut(Edge&) const {}
252 template <typename _Graph>
256 checkConcept< BaseGraphComponent, _Graph >();
257 typename _Graph::Node node;
258 typename _Graph::Edge edge;
268 graph.firstIn(edge, node);
272 graph.firstOut(edge, node);
281 /// An empty idable base graph class.
283 /// This class provides beside the core graph features
284 /// core id functions for the graph structure.
285 /// The most of the base graphs should be conform to this concept.
286 /// The id's are unique and immutable.
287 class IDableGraphComponent : virtual public BaseGraphComponent {
290 typedef BaseGraphComponent::Node Node;
291 typedef BaseGraphComponent::Edge Edge;
293 /// Gives back an unique integer id for the Node.
295 /// Gives back an unique integer id for the Node.
297 int id(const Node&) const { return -1;}
299 /// \brief Gives back the node by the unique id.
301 /// Gives back the node by the unique id.
302 /// If the graph does not contain node with the given id
303 /// then the result of the function is undetermined.
304 Node fromId(int , Node) const { return INVALID;}
306 /// \brief Gives back an unique integer id for the Edge.
308 /// Gives back an unique integer id for the Edge.
310 int id(const Edge&) const { return -1;}
312 /// \brief Gives back the edge by the unique id.
314 /// Gives back the edge by the unique id.
315 /// If the graph does not contain edge with the given id
316 /// then the result of the function is undetermined.
317 Edge fromId(int, Edge) const { return INVALID;}
319 template <typename _Graph>
323 checkConcept< BaseGraphComponent, _Graph >();
324 typename _Graph::Node node;
325 int nid = graph.id(node);
326 nid = graph.id(node);
327 node = graph.fromId(nid, Node());
328 typename _Graph::Edge edge;
329 int eid = graph.id(edge);
330 eid = graph.id(edge);
331 edge = graph.fromId(eid, Edge());
339 /// An empty max-idable base graph class.
341 /// This class provides beside the core graph features
342 /// core max id functions for the graph structure.
343 /// The most of the base graphs should be conform to this concept.
344 /// The id's are unique and immutable.
345 class MaxIDableGraphComponent : virtual public BaseGraphComponent {
348 /// Gives back an integer greater or equal to the maximum Node id.
350 /// Gives back an integer greater or equal to the maximum Node id.
352 int maxId(Node = INVALID) const { return -1;}
354 /// Gives back an integer greater or equal to the maximum Edge id.
356 /// Gives back an integer greater or equal to the maximum Edge id.
358 int maxId(Edge = INVALID) const { return -1;}
360 template <typename _Graph>
364 checkConcept<BaseGraphComponent, _Graph>();
365 int nid = graph.maxId(typename _Graph::Node());
366 ignore_unused_variable_warning(nid);
367 int eid = graph.maxId(typename _Graph::Edge());
368 ignore_unused_variable_warning(eid);
375 /// An empty extendable base graph class.
377 /// This class provides beside the core graph features
378 /// core graph extend interface for the graph structure.
379 /// The most of the base graphs should be conform to this concept.
380 class BaseExtendableGraphComponent : virtual public BaseGraphComponent {
383 typedef BaseGraphComponent::Node Node;
384 typedef BaseGraphComponent::Edge Edge;
386 /// Adds a new Node to the graph.
388 /// Adds a new Node to the graph.
394 /// Adds a new Edge connects the two Nodes to the graph.
396 /// Adds a new Edge connects the two Nodes to the graph.
398 Edge addEdge(const Node&, const Node&) {
402 template <typename _Graph>
405 checkConcept<BaseGraphComponent, _Graph >();
406 typename _Graph::Node node_a, node_b;
407 node_a = graph.addNode();
408 node_b = graph.addNode();
409 typename _Graph::Edge edge;
410 edge = graph.addEdge(node_a, node_b);
417 /// An empty erasable base graph class.
419 /// This class provides beside the core graph features
420 /// core erase functions for the graph structure.
421 /// The most of the base graphs should be conform to this concept.
422 class BaseErasableGraphComponent : virtual public BaseGraphComponent {
425 typedef BaseGraphComponent::Node Node;
426 typedef BaseGraphComponent::Edge Edge;
428 /// Erase a Node from the graph.
430 /// Erase a Node from the graph. This function should not
431 /// erase edges connecting to the Node.
432 void erase(const Node&) {}
434 /// Erase an Edge from the graph.
436 /// Erase an Edge from the graph.
438 void erase(const Edge&) {}
440 template <typename _Graph>
443 checkConcept<BaseGraphComponent, _Graph>();
444 typename _Graph::Node node;
446 typename _Graph::Edge edge;
454 /// An empty clearable base graph class.
456 /// This class provides beside the core graph features
457 /// core clear functions for the graph structure.
458 /// The most of the base graphs should be conform to this concept.
459 class ClearableGraphComponent : virtual public BaseGraphComponent {
462 /// Erase all the Nodes and Edges from the graph.
464 /// Erase all the Nodes and Edges from the graph.
468 template <typename _Graph>
471 checkConcept<BaseGraphComponent, _Graph>();
480 /// Skeleton class for graph NodeIt and EdgeIt
482 /// Skeleton class for graph NodeIt and EdgeIt.
484 template <typename _Graph, typename _Item>
485 class GraphIterator : public _Item {
487 /// \todo Don't we need the Item type as typedef?
489 /// Default constructor.
491 /// @warning The default constructor sets the iterator
492 /// to an undefined value.
494 /// Copy constructor.
496 /// Copy constructor.
498 GraphIterator(GraphIterator const&) {}
499 /// Sets the iterator to the first item.
501 /// Sets the iterator to the first item of \c the graph.
503 explicit GraphIterator(const _Graph&) {}
504 /// Invalid constructor \& conversion.
506 /// This constructor initializes the item to be invalid.
507 /// \sa Invalid for more details.
508 GraphIterator(Invalid) {}
509 /// Assign operator for items.
511 /// The items are assignable.
513 GraphIterator& operator=(GraphIterator const&) { return *this; }
516 /// Assign the iterator to the next item.
518 GraphIterator& operator++() { return *this; }
519 // Node operator*() const { return INVALID; }
520 /// Equality operator
522 /// Two iterators are equal if and only if they point to the
523 /// same object or both are invalid.
524 bool operator==(const GraphIterator&) const { return true;}
525 /// Inequality operator
527 /// \sa operator==(Node n)
529 bool operator!=(const GraphIterator&) const { return true;}
531 template<typename _GraphIterator>
534 // checkConcept< Item, _GraphIterator >();
535 _GraphIterator it1(g);
537 /// \todo Do we need NodeIt(Node) kind of constructor?
538 // _GraphIterator it2(bj);
544 /// \bug This should be: is_base_and_derived<BaseItem, _GraphIterator>
552 /// Skeleton class for graph InEdgeIt and OutEdgeIt
554 /// \note Because InEdgeIt and OutEdgeIt may not inherit from the same
555 /// base class, the _selector is a additional template parameter. For
556 /// InEdgeIt you should instantiate it with character 'i' and for
557 /// OutEdgeIt with 'o'.
558 /// \todo Is this a good name for this concept?
559 template <typename Graph,
560 typename Edge = typename Graph::Edge,
561 char _selector = '0'>
562 class GraphIncIterator : public Edge {
564 /// Default constructor.
566 /// @warning The default constructor sets the iterator
567 /// to an undefined value.
568 GraphIncIterator() {}
569 /// Copy constructor.
571 /// Copy constructor.
573 GraphIncIterator(GraphIncIterator const& gi) :Edge(gi) {}
574 /// Sets the iterator to the first edge incoming into or outgoing
577 /// Sets the iterator to the first edge incoming into or outgoing
580 explicit GraphIncIterator(const Graph&, const typename Graph::Node&) {}
581 /// Invalid constructor \& conversion.
583 /// This constructor initializes the item to be invalid.
584 /// \sa Invalid for more details.
585 GraphIncIterator(Invalid) {}
586 /// Assign operator for nodes.
588 /// The nodes are assignable.
590 GraphIncIterator& operator=(GraphIncIterator const&) { return *this; }
593 /// Assign the iterator to the next node.
595 GraphIncIterator& operator++() { return *this; }
597 // Node operator*() const { return INVALID; }
599 /// Equality operator
601 /// Two iterators are equal if and only if they point to the
602 /// same object or both are invalid.
603 bool operator==(const GraphIncIterator&) const { return true;}
605 /// Inequality operator
607 /// \sa operator==(Node n)
609 bool operator!=(const GraphIncIterator&) const { return true;}
611 template <typename _GraphIncIterator>
613 typedef typename Graph::Node Node;
615 checkConcept<GraphItem<'e'>, _GraphIncIterator>();
616 _GraphIncIterator it1(graph, node);
617 /// \todo Do we need OutEdgeIt(Edge) kind of constructor?
618 // _GraphIncIterator it2(edge);
619 _GraphIncIterator it2;
630 void const_constraits() {
631 Node n = graph.baseNode(it);
632 n = graph.runningNode(it);
638 _GraphIncIterator it;
643 /// An empty iterable base graph class.
645 /// This class provides beside the core graph features
646 /// iterator based iterable interface for the graph structure.
647 /// This concept is part of the StaticGraphConcept.
648 class IterableGraphComponent : virtual public BaseGraphComponent {
652 typedef IterableGraphComponent Graph;
654 typedef BaseGraphComponent::Node Node;
655 typedef BaseGraphComponent::Edge Edge;
657 /// This iterator goes through each node.
659 /// This iterator goes through each node.
661 typedef GraphIterator<Graph, Node> NodeIt;
662 /// This iterator goes through each node.
664 /// This iterator goes through each node.
666 typedef GraphIterator<Graph, Edge> EdgeIt;
667 /// This iterator goes trough the incoming edges of a node.
669 /// This iterator goes trough the \e inccoming edges of a certain node
671 typedef GraphIncIterator<Graph, Edge, 'i'> InEdgeIt;
672 /// This iterator goes trough the outgoing edges of a node.
674 /// This iterator goes trough the \e outgoing edges of a certain node
676 typedef GraphIncIterator<Graph, Edge, 'o'> OutEdgeIt;
678 /// \brief The base node of the iterator.
680 /// Gives back the base node of the iterator.
681 /// It is always the target of the pointed edge.
682 Node baseNode(const InEdgeIt&) const { return INVALID; }
684 /// \brief The running node of the iterator.
686 /// Gives back the running node of the iterator.
687 /// It is always the source of the pointed edge.
688 Node runningNode(const InEdgeIt&) const { return INVALID; }
690 /// \brief The base node of the iterator.
692 /// Gives back the base node of the iterator.
693 /// It is always the source of the pointed edge.
694 Node baseNode(const OutEdgeIt&) const { return INVALID; }
696 /// \brief The running node of the iterator.
698 /// Gives back the running node of the iterator.
699 /// It is always the target of the pointed edge.
700 Node runningNode(const OutEdgeIt&) const { return INVALID; }
702 /// \brief The opposite node on the given edge.
704 /// Gives back the opposite on the given edge.
705 /// \todo It should not be here.
706 Node oppositeNode(const Node&, const Edge&) const { return INVALID; }
709 template <typename _Graph>
712 checkConcept< BaseGraphComponent, _Graph>();
714 checkConcept<GraphIterator<_Graph, typename _Graph::Edge>,
715 typename _Graph::EdgeIt >();
716 checkConcept<GraphIterator<_Graph, typename _Graph::Node>,
717 typename _Graph::NodeIt >();
718 checkConcept<GraphIncIterator<_Graph>, typename _Graph::InEdgeIt>();
719 checkConcept<GraphIncIterator<_Graph>, typename _Graph::OutEdgeIt>();
721 typename _Graph::Node n(INVALID);
722 typename _Graph::Edge e(INVALID);
723 n = graph.oppositeNode(n, e);
731 /// An empty alteration notifier base graph class.
733 /// This class provides beside the core graph features
734 /// alteration notifier interface for the graph structure.
735 /// This is an observer-notifier pattern. More Obsevers can
736 /// be registered into the notifier and whenever an alteration
737 /// occured in the graph all the observers will notified about it.
738 class AlterableGraphComponent : virtual public BaseGraphComponent {
741 /// The edge observer registry.
742 typedef AlterationNotifier<Edge> EdgeNotifier;
743 /// The node observer registry.
744 typedef AlterationNotifier<Node> NodeNotifier;
746 /// \brief Gives back the edge alteration notifier.
748 /// Gives back the edge alteration notifier.
749 EdgeNotifier getNotifier(Edge) const {
750 return EdgeNotifier();
753 /// \brief Gives back the node alteration notifier.
755 /// Gives back the node alteration notifier.
756 NodeNotifier getNotifier(Node) const {
757 return NodeNotifier();
763 /// Class describing the concept of graph maps
765 /// This class describes the common interface of the graph maps
766 /// (NodeMap, EdgeMap), that is \ref maps-page "maps" which can be used to
767 /// associate data to graph descriptors (nodes or edges).
768 template <typename Graph, typename Item, typename _Value>
769 class GraphMap : public ReadWriteMap<Item, _Value> {
773 /// \brief Construct a new map.
775 /// Construct a new map for the graph.
776 explicit GraphMap(const Graph&) {}
777 /// \brief Construct a new map with default value.
779 /// Construct a new map for the graph and initalise the values.
780 GraphMap(const Graph&, const _Value&) {}
781 /// \brief Copy constructor.
783 /// Copy Constructor.
784 GraphMap(const GraphMap& gm) :ReadWriteMap<Item, _Value>(gm) {}
786 /// \brief Assign operator.
789 GraphMap& operator=(const GraphMap&) { return *this;}
791 template<typename _Map>
794 checkConcept<ReadWriteMap<Item, _Value>, _Map >();
795 // Construction with a graph parameter
797 // Constructor with a graph and a default value parameter
799 // Copy constructor. Do we need it?
802 ignore_unused_variable_warning(a2);
807 const typename GraphMap::Value &t;
812 /// An empty mappable base graph class.
814 /// This class provides beside the core graph features
815 /// map interface for the graph structure.
816 /// This concept is part of the StaticGraphConcept.
817 class MappableGraphComponent : virtual public BaseGraphComponent {
820 typedef MappableGraphComponent Graph;
822 typedef BaseGraphComponent::Node Node;
823 typedef BaseGraphComponent::Edge Edge;
825 /// ReadWrite map of the nodes.
827 /// ReadWrite map of the nodes.
829 template <typename _Value>
830 class NodeMap : public GraphMap<Graph, Node, _Value> {
834 /// \brief Construct a new map.
836 /// Construct a new map for the graph.
837 /// \todo call the right parent class constructor
838 explicit NodeMap(const Graph&) {}
839 /// \brief Construct a new map with default value.
841 /// Construct a new map for the graph and initalise the values.
842 NodeMap(const Graph&, const _Value&) {}
843 /// \brief Copy constructor.
845 /// Copy Constructor.
846 NodeMap(const NodeMap& nm) : GraphMap<Graph, Node, _Value>(nm) {}
848 /// \brief Assign operator.
851 NodeMap& operator=(const NodeMap&) { return *this;}
855 /// ReadWrite map of the edges.
857 /// ReadWrite map of the edges.
859 template <typename _Value>
860 class EdgeMap : public GraphMap<Graph, Edge, _Value> {
864 /// \brief Construct a new map.
866 /// Construct a new map for the graph.
867 /// \todo call the right parent class constructor
868 explicit EdgeMap(const Graph&) {}
869 /// \brief Construct a new map with default value.
871 /// Construct a new map for the graph and initalise the values.
872 EdgeMap(const Graph&, const _Value&) {}
873 /// \brief Copy constructor.
875 /// Copy Constructor.
876 EdgeMap(const EdgeMap& em) :GraphMap<Graph, Edge, _Value>(em) {}
878 /// \brief Assign operator.
881 EdgeMap& operator=(const EdgeMap&) { return *this;}
885 template <typename _Graph>
891 Type(int _v) : value(_v) {}
895 checkConcept<BaseGraphComponent, _Graph>();
897 typedef typename _Graph::template NodeMap<int> IntNodeMap;
898 checkConcept<GraphMap<_Graph, typename _Graph::Node, int>,
901 typedef typename _Graph::template NodeMap<bool> BoolNodeMap;
902 checkConcept<GraphMap<_Graph, typename _Graph::Node, bool>,
905 typedef typename _Graph::template NodeMap<Type> TypeNodeMap;
906 checkConcept<GraphMap<_Graph, typename _Graph::Node, Type>,
911 typedef typename _Graph::template EdgeMap<int> IntEdgeMap;
912 checkConcept<GraphMap<_Graph, typename _Graph::Edge, int>,
915 typedef typename _Graph::template EdgeMap<bool> BoolEdgeMap;
916 checkConcept<GraphMap<_Graph, typename _Graph::Edge, bool>,
919 typedef typename _Graph::template EdgeMap<Type> TypeEdgeMap;
920 checkConcept<GraphMap<_Graph, typename _Graph::Edge, Type>,
929 /// \brief An empty extendable extended graph class.
931 /// This class provides beside the core graph features
932 /// item addition interface for the graph structure.
933 /// The difference between this class and the
934 /// \c BaseExtendableGraphComponent is that it should
935 /// notify the item alteration observers.
936 class ExtendableGraphComponent : virtual public BaseGraphComponent {
939 typedef ExtendableGraphComponent Graph;
941 typedef BaseGraphComponent::Node Node;
942 typedef BaseGraphComponent::Edge Edge;
944 /// \brief Add a node to the graph.
946 /// Add a node to the graph and notify the observers.
951 /// \brief Add an edge to the graph.
953 /// Add an edge to the graph and notify the observers.
954 Edge addEdge(const Node&, const Node&) {
958 template <typename _Graph>
961 checkConcept<BaseGraphComponent, _Graph >();
962 typename _Graph::Node node_a, node_b;
963 node_a = graph.addNode();
964 node_b = graph.addNode();
965 typename _Graph::Edge edge;
966 edge = graph.addEdge(node_a, node_b);
972 /// \brief An empty erasable extended graph class.
974 /// This class provides beside the core graph features
975 /// item erase interface for the graph structure.
976 /// The difference between this class and the
977 /// \c BaseErasableGraphComponent is that it should
978 /// notify the item alteration observers.
979 class ErasableGraphComponent : virtual public BaseGraphComponent {
982 typedef ErasableGraphComponent Graph;
984 typedef BaseGraphComponent::Node Node;
985 typedef BaseGraphComponent::Edge Edge;
987 /// \brief Erase the Node and notify the node alteration observers.
989 /// Erase the Node and notify the node alteration observers.
990 void erase(const Node&) {}
992 /// \brief Erase the Edge and notify the edge alteration observers.
994 /// Erase the Edge and notify the edge alteration observers.
995 void erase(const Edge&) {}
997 template <typename _Graph>
1000 checkConcept<BaseGraphComponent, _Graph >();
1001 typename _Graph::Node node;
1003 typename _Graph::Edge edge;