Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,13 @@

package com.baidu.hugegraph.computer.algorithm.community.cc;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.baidu.hugegraph.computer.algorithm.community.trianglecount.TriangleCount;
import com.baidu.hugegraph.computer.core.config.Config;
import com.baidu.hugegraph.computer.core.graph.edge.Edge;
import com.baidu.hugegraph.computer.core.graph.edge.Edges;
import com.baidu.hugegraph.computer.core.graph.id.Id;
import com.baidu.hugegraph.computer.core.graph.value.IdList;
import com.baidu.hugegraph.computer.core.graph.value.IdSet;
import com.baidu.hugegraph.computer.core.graph.vertex.Vertex;
import com.baidu.hugegraph.computer.core.worker.Computation;
import com.baidu.hugegraph.computer.core.worker.ComputationContext;

/**
Expand All @@ -42,15 +38,12 @@
* And we have 2 ways to count local cc:
* 1. if we already saved the triangles in each vertex, we can calculate only
* in superstep0/compute0 to get the result
* 2. if we want recount the triangles result, we can choose:
* - copy code from TriangleCount, then add extra logic
* - reuse code in TriangleCount (need solve compatible problem - TODO)
* <p>
* The formula of local CC is: C(v) = 2T / Dv(Dv - 1)
* v represents one vertex, T represents the triangles of current vertex,
* D represents the degree of current vertex
*/
public class ClusteringCoefficient implements Computation<IdList> {
public class ClusteringCoefficient extends TriangleCount {

@Override
public String name() {
Expand Down Expand Up @@ -80,63 +73,11 @@ public void compute0(ComputationContext context, Vertex vertex) {

@Override
public void compute(ComputationContext context, Vertex vertex, Iterator<IdList> messages) {
Integer count = this.triangleCount(context, vertex, messages);
IdSet neighbors = ((ClusteringCoefficientValue) vertex.value()).idSet();
Integer count = super.triangleCount(context, vertex, messages, neighbors);
if (count != null) {
((ClusteringCoefficientValue) vertex.value()).count(count);
vertex.inactivate();
}
}

private Integer triangleCount(ComputationContext context, Vertex vertex,
Iterator<IdList> messages) {
IdList neighbors = ((ClusteringCoefficientValue) vertex.value()).idList();

if (context.superstep() == 1) {
// Collect outgoing neighbors
Set<Id> outNeighbors = getOutNeighbors(vertex);
neighbors.addAll(outNeighbors);

// Collect incoming neighbors
while (messages.hasNext()) {
IdList idList = messages.next();
assert idList.size() == 1;
Id inId = idList.get(0);
if (!outNeighbors.contains(inId)) {
neighbors.add(inId);
}
}
// TODO: Save degree to vertex value here (optional)
// Send all neighbors to neighbors
for (Id targetId : neighbors.values()) {
context.sendMessage(targetId, neighbors);
}
} else if (context.superstep() == 2) {
int count = 0;

Set<Id> allNeighbors = new HashSet<>(neighbors.values());
while (messages.hasNext()) {
IdList twoDegreeNeighbors = messages.next();
for (Id twoDegreeNeighbor : twoDegreeNeighbors.values()) {
if (allNeighbors.contains(twoDegreeNeighbor)) {
count++;
}
}
}

return count >> 1;
}
return null;
}

private static Set<Id> getOutNeighbors(Vertex vertex) {
Set<Id> outNeighbors = new HashSet<>();
Edges edges = vertex.edges();
for (Edge edge : edges) {
Id targetId = edge.targetId();
if (!vertex.id().equals(targetId)) {
outNeighbors.add(targetId);
}
}
return outNeighbors;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ protected org.apache.hugegraph.structure.graph.Vertex constructHugeVertex(Vertex
new org.apache.hugegraph.structure.graph.Vertex(null);
hugeVertex.id(vertex.id().asObject());
float triangle = ((ClusteringCoefficientValue) vertex.value()).count();
int degree = ((ClusteringCoefficientValue) vertex.value()).idList().size();
int degree = ((ClusteringCoefficientValue) vertex.value()).idSet().value().size();
hugeVertex.property(this.name(), 2 * triangle / degree / (degree - 1));
return hugeVertex;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import java.io.IOException;

import com.baidu.hugegraph.computer.core.graph.value.IdList;
import com.baidu.hugegraph.computer.core.graph.value.IdSet;
import com.baidu.hugegraph.computer.core.graph.value.IntValue;
import com.baidu.hugegraph.computer.core.graph.value.Value;
import com.baidu.hugegraph.computer.core.io.RandomAccessInput;
Expand All @@ -32,22 +32,22 @@
*/
public class ClusteringCoefficientValue implements Value.CustomizeValue<Integer> {

private IdList idList;
private IdSet idSet;
private IntValue count;
private final IntValue degree;

public ClusteringCoefficientValue() {
this.idList = new IdList();
this.idSet = new IdSet();
this.count = new IntValue();
this.degree = new IntValue();
}

public IdList idList() {
return this.idList;
public IdSet idSet() {
return this.idSet;
}

public long count() {
return this.count.value();
public int count() {
return this.count.intValue();
}

public void count(Integer count) {
Expand All @@ -65,7 +65,7 @@ public void degree(Integer degree) {
@Override
public ClusteringCoefficientValue copy() {
ClusteringCoefficientValue ccValue = new ClusteringCoefficientValue();
ccValue.idList = this.idList.copy();
ccValue.idSet = this.idSet.copy();
ccValue.count = this.count.copy();
return ccValue;
}
Expand All @@ -77,13 +77,13 @@ public Integer value() {

@Override
public void read(RandomAccessInput in) throws IOException {
this.idList.read(in);
this.idSet.read(in);
this.count.read(in);
}

@Override
public void write(RandomAccessOutput out) throws IOException {
this.idList.write(out);
this.idSet.write(out);
this.count.write(out);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package com.baidu.hugegraph.computer.algorithm.community.trianglecount;


import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
Expand All @@ -28,6 +27,7 @@
import com.baidu.hugegraph.computer.core.graph.edge.Edges;
import com.baidu.hugegraph.computer.core.graph.id.Id;
import com.baidu.hugegraph.computer.core.graph.value.IdList;
import com.baidu.hugegraph.computer.core.graph.value.IdSet;
import com.baidu.hugegraph.computer.core.graph.vertex.Vertex;
import com.baidu.hugegraph.computer.core.worker.Computation;
import com.baidu.hugegraph.computer.core.worker.ComputationContext;
Expand All @@ -46,29 +46,28 @@ public String category() {

@Override
public void compute0(ComputationContext context, Vertex vertex) {
IdList selfId = new IdList();
IdSet selfId = new IdSet();
selfId.add(vertex.id());

context.sendMessageToAllEdgesIf(vertex, selfId, (ids, targetId) -> {
return !ids.get(0).equals(targetId);
return !vertex.id().equals(targetId);
});
vertex.value(new TriangleCountValue());
}

@Override
public void compute(ComputationContext context, Vertex vertex,
Iterator<IdList> messages) {
Integer count = this.triangleCount(context, vertex, messages);
IdSet neighbors = ((TriangleCountValue) vertex.value()).idSet();
Integer count = this.triangleCount(context, vertex, messages, neighbors);
if (count != null) {
((TriangleCountValue) vertex.value()).count(count);
vertex.inactivate();
}
}

private Integer triangleCount(ComputationContext context, Vertex vertex,
Iterator<IdList> messages) {
IdList neighbors = ((TriangleCountValue) vertex.value()).idList();

protected Integer triangleCount(ComputationContext context, Vertex vertex,
Iterator<IdList> messages, IdSet neighbors) {
if (context.superstep() == 1) {
// Collect outgoing neighbors
Set<Id> outNeighbors = getOutNeighbors(vertex);
Expand All @@ -85,17 +84,16 @@ private Integer triangleCount(ComputationContext context, Vertex vertex,
}

// Send all neighbors to neighbors
for (Id targetId : neighbors.values()) {
for (Id targetId : neighbors.value()) {
context.sendMessage(targetId, neighbors);
}
} else if (context.superstep() == 2) {
int count = 0;

Set<Id> allNeighbors = new HashSet<>(neighbors.values());
while (messages.hasNext()) {
IdList twoDegreeNeighbors = messages.next();
for (Id twoDegreeNeighbor : twoDegreeNeighbors.values()) {
if (allNeighbors.contains(twoDegreeNeighbor)) {
if (neighbors.contains(twoDegreeNeighbor)) {
count++;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,28 @@

import org.apache.commons.lang3.builder.ToStringBuilder;

import com.baidu.hugegraph.computer.core.graph.value.IdList;
import com.baidu.hugegraph.computer.core.graph.value.IdSet;
import com.baidu.hugegraph.computer.core.graph.value.IntValue;
import com.baidu.hugegraph.computer.core.graph.value.Value.CustomizeValue;
import com.baidu.hugegraph.computer.core.io.RandomAccessInput;
import com.baidu.hugegraph.computer.core.io.RandomAccessOutput;

public class TriangleCountValue implements CustomizeValue<Integer> {

private IdList idList;
private IdSet idSet;
private IntValue count;

public TriangleCountValue() {
this.idList = new IdList();
this.idSet = new IdSet();
this.count = new IntValue();
}

public IdList idList() {
return this.idList;
public IdSet idSet() {
return this.idSet;
}

public long count() {
return this.count.longValue();
public int count() {
return this.count.intValue();
}

public void count(int count) {
Expand All @@ -54,26 +54,26 @@ public void count(int count) {
@Override
public TriangleCountValue copy() {
TriangleCountValue triangleCountValue = new TriangleCountValue();
triangleCountValue.idList = this.idList.copy();
triangleCountValue.idSet = this.idSet.copy();
triangleCountValue.count = this.count.copy();
return triangleCountValue;
}

@Override
public void read(RandomAccessInput in) throws IOException {
this.idList.read(in);
this.idSet.read(in);
this.count.read(in);
}

@Override
public void write(RandomAccessOutput out) throws IOException {
this.idList.write(out);
this.idSet.write(out);
this.count.write(out);
}

@Override
public String toString() {
return new ToStringBuilder(this).append("idList", this.idList)
return new ToStringBuilder(this).append("idSet", this.idSet)
.append("count", this.count).toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.baidu.hugegraph.computer.core.graph.value;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;

Expand Down Expand Up @@ -48,6 +49,10 @@ public void addAll(IdSet other) {
this.values.addAll(other.values);
}

public void addAll(Collection<Id> other) {
this.values.addAll(other);
}

public boolean contains(Id id) {
return this.values.contains(id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
import org.apache.hugegraph.util.E;

import com.baidu.hugegraph.computer.core.common.ComputerContext;
import com.baidu.hugegraph.computer.core.common.SerialEnum;
import com.baidu.hugegraph.computer.core.graph.GraphFactory;
import com.baidu.hugegraph.computer.core.graph.value.Value.Tvalue;
import com.baidu.hugegraph.computer.core.io.RandomAccessInput;
import com.baidu.hugegraph.computer.core.io.RandomAccessOutput;
import org.apache.hugegraph.util.E;

public class ListValue<T extends Tvalue<?>> implements Tvalue<List<Object>> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package com.baidu.hugegraph.computer.algorithm;

import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

Expand All @@ -34,7 +33,6 @@
import com.baidu.hugegraph.computer.algorithm.community.wcc.WccTest;
import com.baidu.hugegraph.computer.algorithm.path.rings.RingsDetectionTest;
import com.baidu.hugegraph.computer.algorithm.path.rings.RingsDetectionWithFilterTest;
import org.apache.hugegraph.config.OptionSpace;

@RunWith(Suite.class)
@Suite.SuiteClasses({
Expand All @@ -51,14 +49,4 @@
BetweennessCentralityTest.class
})
public class AlgorithmTestSuite {

@BeforeClass
public static void setup() throws ClassNotFoundException {
// Don't forget to register options
OptionSpace.register("computer",
"com.baidu.hugegraph.computer.core.config." +
"ComputerOptions");
OptionSpace.register("computer-rpc",
"org.apache.hugegraph.config.RpcOptions");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import com.baidu.hugegraph.computer.core.config.ComputerOptions;
import com.google.common.collect.ImmutableMap;


public class ClusteringCoefficientTest extends AlgorithmTestBase {

private static final String VERTX_LABEL = "tc_user";
Expand Down Expand Up @@ -105,7 +104,7 @@ public void testClusteringCoefficientValue() {

ClusteringCoefficientValue copy = value.copy();
Assert.assertEquals(10, copy.count());
Assert.assertNotSame(value.idList(), copy.idList());
Assert.assertNotSame(value.idSet(), copy.idSet());

Assert.assertContains("10", value.toString());
}
Expand Down
Loading