[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-i18n-doc
Subject:    [rocs] RocsCore/DataStructures/Graph: Fix distance computation for unconnected nodes.
From:       Andreas Cord-Landwehr <cola () uni-paderborn ! de>
Date:       2013-06-11 18:28:30
Message-ID: 20130611182830.C18F4A605A () git ! kde ! org
[Download RAW message or body]

Git commit 06c79f18fc9b43d0ff5a3c2a6a98cd86ce54a609 by Andreas Cord-Landwehr, on \
behalf of Matthew Mellott. Committed on 11/06/2013 at 11:41.
Pushed by cordlandwehr into branch 'master'.

Fix distance computation for unconnected nodes.

If a path does not exist between any two vertices in a graph, the
distance between those vertices is defined to be infinity. The
GraphStructure::distances method was returning zero in this situation
and so this was a bug. A fix for this bug was implemented, a test case
was added to verify these changes, and related documentation was
updated.

Introducing two new strings, as requested at i18n list.

REVIEW: 110822
CCMAIL: kde-i18n-doc@kde.org

M  +13   -5    RocsCore/DataStructures/Graph/GraphStructure.cpp
M  +4    -2    RocsCore/DataStructures/Graph/GraphStructure.h
M  +14   -0    RocsCore/DataStructures/Graph/GraphStructure.xml
M  +31   -0    RocsCore/DataStructures/Graph/Tests/TestGraphStructureAlgorithms.cpp
M  +1    -0    RocsCore/DataStructures/Graph/Tests/TestGraphStructureAlgorithms.h

http://commits.kde.org/rocs/06c79f18fc9b43d0ff5a3c2a6a98cd86ce54a609

diff --git a/RocsCore/DataStructures/Graph/GraphStructure.cpp \
b/RocsCore/DataStructures/Graph/GraphStructure.cpp index a3de72a..01630f5 100644
--- a/RocsCore/DataStructures/Graph/GraphStructure.cpp
+++ b/RocsCore/DataStructures/Graph/GraphStructure.cpp
@@ -39,6 +39,8 @@
 #include <KLocale>
 #include <QString>
 
+#include <cmath>
+
 DataStructurePtr Rocs::GraphStructure::create(Document *parent)
 {
     return DataStructure::create<GraphStructure>(parent);
@@ -268,13 +270,19 @@ QScriptValue Rocs::GraphStructure::distances(Data* fromRaw)
     QScriptValue distances = engine()->newArray();
     foreach (DataPtr target, dataListAll()) {
         qreal length = 0;
-        foreach (PointerPtr edge, shortestPaths[target]) {
-            if (!edge->property("value").toString().isEmpty()) {
-                length += edge->property("value").toDouble();
-            } else {
-                length += 1;
+
+        if (shortestPaths[target].isEmpty() && from != target) {
+            length = INFINITY;
+        } else {
+            foreach (PointerPtr edge, shortestPaths[target]) {
+                if (!edge->property("value").toString().isEmpty()) {
+                    length += edge->property("value").toDouble();
+                } else {
+                    length += 1;
+                }
             }
         }
+
         distances.property("push").call(
             distances,
             QScriptValueList() << length
diff --git a/RocsCore/DataStructures/Graph/GraphStructure.h \
b/RocsCore/DataStructures/Graph/GraphStructure.h index 7754cd0..66b0c20 100644
--- a/RocsCore/DataStructures/Graph/GraphStructure.h
+++ b/RocsCore/DataStructures/Graph/GraphStructure.h
@@ -254,8 +254,10 @@ public slots:
     /**
      * Computes the Dijkstra's shortest path algorithm to compute
      * all shortest path distances from \p from. If edge has value 0, the edge value
-     * is set to 1. Note: this shortest path algorithm works only for graphs with \
                all
-     * edges values non-negative. For undirected graphs reverse edges are add \
automatically. +     * is set to 1. Infinity is returned when there is no path
+     * between \p from and another node in the graph. Note: this shortest path
+     * algorithm works only for graphs with all edges values non-negative. For
+     * undirected graphs reverse edges are added automatically.
      * The algorithm has time complexity O(V log V + E).
      *
      * \param from the node from which the computation starts
diff --git a/RocsCore/DataStructures/Graph/GraphStructure.xml \
b/RocsCore/DataStructures/Graph/GraphStructure.xml index a814a25..16308f5 100644
--- a/RocsCore/DataStructures/Graph/GraphStructure.xml
+++ b/RocsCore/DataStructures/Graph/GraphStructure.xml
@@ -120,5 +120,19 @@ A graph objects holds the information of a data structure of \
type "Graph".  </parameter>
     </parameters>
 </method>
+<method>
+    <name>distances(from)</name>
+    <description>
+        <para>Returns an array of shortest path lengths from this node to every \
other node in the graph.</para> +    </description>
+    <returnType>Array</returnType>
+    <parameters>
+        <parameter>
+            <name>from</name>
+            <type>GraphNode</type>
+            <info>Source node for distance computations.</info>
+        </parameter>
+    </parameters>
+</method>
 </methods>
 </object>
diff --git a/RocsCore/DataStructures/Graph/Tests/TestGraphStructureAlgorithms.cpp \
b/RocsCore/DataStructures/Graph/Tests/TestGraphStructureAlgorithms.cpp index \
                340f5d9..93e835b 100644
--- a/RocsCore/DataStructures/Graph/Tests/TestGraphStructureAlgorithms.cpp
+++ b/RocsCore/DataStructures/Graph/Tests/TestGraphStructureAlgorithms.cpp
@@ -31,6 +31,8 @@
 #include <DataStructureBackendManager.h>
 #include <DocumentManager.h>
 
+#include <cmath>
+
 TestGraphStructureAlgorithms::TestGraphStructureAlgorithms()
 {
     QVERIFY(DataStructureBackendManager::self().backends().count() > 0);
@@ -49,6 +51,35 @@ void TestGraphStructureAlgorithms::cleanupTestCase()
     DocumentManager::self().removeDocument(DocumentManager::self().activeDocument());
  }
 
+void TestGraphStructureAlgorithms::testDistances()
+{
+    Document *document = DocumentManager::self().activeDocument();
+    DataList dataList;
+
+    document->pointerType(0)->setDirection(PointerType::Bidirectional);
+
+    DataStructurePtr ds = document->addDataStructure("Dijkstra");
+    boost::shared_ptr<Rocs::GraphStructure> graph = \
boost::static_pointer_cast<Rocs::GraphStructure>(ds); +
+    // need to set engine because GraphStructure::distances calls \
QScriptEngine::newArray +    ds->setEngine(new QScriptEngine(this));
+
+    // create 3 nodes connected as follows:
+    // x-x x
+    int nodes = 3;
+    dataList.clear();
+    for (int i = 0; i < nodes; ++i) {
+        dataList.append(graph->createData(QString(i), 0));
+    }
+    dataList[0]->createPointer(dataList[1]);
+
+    // test distances from 0 to all others
+    QScriptValue distances = graph->distances(dataList[0].get());
+    QVERIFY2(distances.property(0).equals(QScriptValue(0)), "ERROR: distance is \
wrong"); +    QVERIFY2(distances.property(1).equals(QScriptValue(1)), "ERROR: \
distance is wrong"); +    \
QVERIFY2(distances.property(2).equals(QScriptValue(INFINITY)), "ERROR: distance is \
wrong"); +}
+
 void TestGraphStructureAlgorithms::testDijkstraBidirectional()
 {
     Document *document = DocumentManager::self().activeDocument();
diff --git a/RocsCore/DataStructures/Graph/Tests/TestGraphStructureAlgorithms.h \
b/RocsCore/DataStructures/Graph/Tests/TestGraphStructureAlgorithms.h index \
                abac132..e563fd0 100644
--- a/RocsCore/DataStructures/Graph/Tests/TestGraphStructureAlgorithms.h
+++ b/RocsCore/DataStructures/Graph/Tests/TestGraphStructureAlgorithms.h
@@ -35,6 +35,7 @@ public:
 private slots:
     void init();
     void cleanupTestCase();
+    void testDistances();
     void testDijkstraBidirectional();
     void testDijkstraUnidirectional();
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic