001/*
002 * Copyright 2006 - 2013
003 *     Stefan Balev     <stefan.balev@graphstream-project.org>
004 *     Julien Baudry    <julien.baudry@graphstream-project.org>
005 *     Antoine Dutot    <antoine.dutot@graphstream-project.org>
006 *     Yoann Pigné      <yoann.pigne@graphstream-project.org>
007 *     Guilhelm Savin   <guilhelm.savin@graphstream-project.org>
008 * 
009 * This file is part of GraphStream <http://graphstream-project.org>.
010 * 
011 * GraphStream is a library whose purpose is to handle static or dynamic
012 * graph, create them from scratch, file or any source and display them.
013 * 
014 * This program is free software distributed under the terms of two licenses, the
015 * CeCILL-C license that fits European law, and the GNU Lesser General Public
016 * License. You can  use, modify and/ or redistribute the software under the terms
017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
019 * the Free Software Foundation, either version 3 of the License, or (at your
020 * option) any later version.
021 * 
022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
024 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
025 * 
026 * You should have received a copy of the GNU Lesser General Public License
027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
028 * 
029 * The fact that you are presently reading this means that you have had
030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
031 */
032package org.graphstream.algorithm.measure;
033
034import static org.graphstream.algorithm.Toolkit.communities;
035
036import java.util.HashMap;
037import java.util.HashSet;
038
039import org.graphstream.graph.Node;
040
041/**
042 * Computes and updates a relative measure based on the comparison between the
043 * current community assignment and a reference assignment on a given graph.
044 * 
045 * @author Guillaume-Jean Herbiet
046 * 
047 */
048public abstract class CommunityRelativeMeasure extends CommunityMeasure {
049
050        /**
051         * Name of the attribute marking the reference communities.
052         */
053        protected String referenceMarker;
054
055        /**
056         * All reference communities indexed by their marker value.
057         */
058        protected HashMap<Object, HashSet<Node>> referenceCommunities;
059
060        public CommunityRelativeMeasure(String marker) {
061                super(marker);
062                this.referenceMarker = "label";
063        }
064
065        /**
066         * New comparative measure using "marker" as attribute name for each node
067         * current community assignment and "referenceMarker" as attribute name for
068         * each node reference assignment.
069         * 
070         * @param marker
071         *            Current community assignment attribute name
072         * @param referenceMarker
073         *            Reference community assignment attribute name
074         */
075        public CommunityRelativeMeasure(String marker, String referenceMarker) {
076                super(marker);
077                this.referenceMarker = referenceMarker;
078        }
079
080        // /**
081        // * New comparative measure using the results of the specified algorithm as
082        // * current community assignment and "referenceMarker" as attribute name
083        // for
084        // * each node reference assignment.
085        // *
086        // * @param algo
087        // * Algorithm which results will be used for measurement.
088        // * @param referenceMarker
089        // * Reference community assignment attribute name
090        // */
091        // public CommunityMeasure(CommunityAlgorithm algo) {
092        // this.marker = algo.getMarker();
093        // this.referenceMarker = referenceMarker;
094        // }
095
096        @Override
097        public abstract void compute();
098
099        @Override
100        protected void initialize() {
101                super.initialize();
102                referenceCommunities = communities(graph, referenceMarker);
103        }
104
105        @Override
106        public void nodeAdded(String graphId, long timeId, String nodeId) {
107                super.nodeAdded(graphId, timeId, nodeId);
108
109                Node n = graph.getNode(nodeId);
110                assignNode(nodeId, n.getAttribute(referenceMarker),
111                                referenceCommunities);
112        }
113
114        @Override
115        public void nodeRemoved(String graphId, long timeId, String nodeId) {
116                super.nodeRemoved(graphId, timeId, nodeId);
117
118                Node n = graph.getNode(nodeId);
119                unassignNode(nodeId, n.getAttribute(referenceMarker),
120                                referenceCommunities);
121        }
122
123        @Override
124        public void nodeAttributeChanged(String graphId, long timeId,
125                        String nodeId, String attribute, Object oldValue, Object newValue) {
126                super.nodeAttributeChanged(graphId, timeId, nodeId, attribute,
127                                oldValue, newValue);
128
129                if (attribute.equals(referenceMarker) && oldValue != newValue) {
130                        unassignNode(nodeId, oldValue, referenceCommunities);
131                        assignNode(nodeId, newValue, referenceCommunities);
132                }
133        }
134}