Clair::Network

KernighanLin


SummaryIncluded librariesPackage variablesSynopsisGeneral documentationMethods

SummaryTop
Clair::Network::KrenighanLin - Network module implemented the Krenighan-Lin algorithm

Package variablesTop
No package variables defined.

Included modulesTop
Clair::Network

InheritTop
Clair::Network

SynopsisTop
my $fileName = "karate.gml";
my $reader = Clair::Network::Reader::GML->new();
my $net = $reader->read_network($fileName);
my $KL = new Clair::Network::KernighanLin($net);
$graphPartition = $KL->generatePartition();
#graphPartiton is a hash with node id as key and partition number 0/1 as value.
# structure of $graphPartition
$graphPartition = {
1 => 1,
2 => 1,
3 => 1,
4 => 0,
...
};

DescriptionTop
No description!
MethodsTop
AllLockedNo descriptionCode
generatePartitionDescriptionCode
getAllCostNo descriptionCode
newDescriptionCode

Methods description


generatePartitioncode    nextTop
run the KernighanLin algorithm and generate the partition.

newcodeprevnextTop
$KL = new Clair::Network::KernighanLin($network);
Load the graph needed to be partitioned (the Clair::Network object).

Methods code


AllLockeddescriptionprevnextTop
sub AllLocked {
    (my $self, my $nodeStatus) = @_;

    foreach $item(keys %$nodeStatus) {
        return 0 if ($$nodeStatus{$item} != -1);
    }

    return 1;
}

generatePartitiondescriptionprevnextTop
sub generatePartition {
    my $self = shift;
    # read in the number of partition needed
$self->{numberOfPartitions} = shift; # now I need to get the weight matrix for all edges.
# first get all nodes
my @vertices = $self->get_vertices(); my $nodes =\@ vertices; my @edges = $self->get_edges(); $self->{edges} =\@ edges; my $nodePartition = {}; my $nodeStatus = {}; my $size = $#$nodes+1; $self->{nodes} = $nodes; # initilaize all variables
for (my $i = 0; $i < $size; $i++) { if ($i%2 != 0) { $$nodePartition{$$nodes[$i]} =$$nodePartition{$$nodes[$i]}.0; $value0 = $$nodePartition{$$nodes[$i]}; } else { $$nodePartition{$$nodes[$i]} = $$nodePartition{$$nodes[$i]}.1; $value1 = $$nodePartition{$$nodes[$i]}; } $$nodeStatus{$$nodes[$i]} = 0; } while (1) { my $EC = {}; my $IC = {}; my $D = {}; my @s = (); my @t = (); my @g = (); my $maxI; my $maxJ; my $maxG; my $nodeStatus = {}; # unlock all nodes
for (my $i = 0; $i < $size; $i++) { $$nodeStatus{$$nodes[$i]} = 0; } # get all cost based on current partition
$self->getAllCost($EC, $IC, $D, $nodePartition); while ($self->AllLocked($nodeStatus) == 0) { $maxI = 0; $maxJ = 0; $maxG = -10000; foreach $node1(keys %$nodePartition) { next if ($$nodePartition{$node1} == $value1); next if ($$nodeStatus{$node1} == -1); foreach $node2(keys %$nodePartition) { next if($$nodePartition{$node2} == $value0); next if ($$nodeStatus{$node2} == -1); my $g = $$D{$node1} + $$D{$node2} - 2*($self->get_edge_weight($node1, $node2)); if ($g > $maxG) { $maxI = $node1; $maxJ = $node2; $maxG = $g; } } } push(@s, $maxI); push(@t, $maxJ); push(@g, $maxG); $$nodeStatus{$maxI} = $$nodeStatus{$maxJ} = -1; #update all other nodes:
foreach $node (keys %$nodeStatus) { if ($$nodeStatus{$node} == -1) { next; } if($$nodePartition{$node} == $value0) { $$D{$node} = $$D{$node} + 2*($self->get_edge_weight($node,$maxI)) - 2*($self->get_edge_weight($node,$maxJ)); } if($$nodePartition{$node} == $value1) { $$D{$node} = $$D{$node} + 2*($self->get_edge_weight($node,$maxJ)) - 2*($self->get_edge_weight($node, $maxI)); } } } my $sum = 0; my $maxSum = -100000; my $maxPair = 0; for (my $i = 0; $i < $#g; $i++) { $sum += $g[$i]; if ($sum > $maxSum) { $maxSum = $sum; $maxPair = $i; } } if ($maxSum > 0) { for ($i = 0; $i <= $maxPair; $i++) { $$nodePartition{$s[$i]} = $value1; $$nodePartition{$t[$i]} = $value0; } }else { last; } } return $nodePartition;
}

getAllCostdescriptionprevnextTop
sub getAllCost {
    my $self = shift; 
    (my $EC, my $IC, my $D, my $nodePartition) = @_;

    $edges = $self->{edges};

    foreach $edge(@$edges) {
        $source = $$edge[0];
        $target = $$edge[1];

        if ($$nodePartition{$source} eq $$nodePartition{$target}) {
            $$IC{$source} += $self->get_edge_weight($source, $target);
            $$IC{$target} += $self->get_edge_weight($source, $target);
        }
        # if not, External Cost
if ($$nodePartition{$source} ne $$nodePartition{$target}) { $$EC{$source} += $self->get_edge_weight($source, $target); $$EC{$target} += $self->get_edge_weight($source, $target); } $$D{$source} = $$EC{$source} - $$IC{$source}; $$D{$target} = $$EC{$target} - $$IC{$target}; }
}

newdescriptionprevnextTop
sub new {
    my $class = shift;
    my $self = shift;
    $self->{graph} = $self->get_undirected_graph($self->{graph});

    bless($self, $class);
    return $self;
}

General documentation


VERSIONTop
Version 0.01

AlllockedTop
private method, used to check if all nodes have been exchanged.

getAllcostTop
private method, used to intialize all algorithms' parameters.

AUTHORTop
Chen Huang << <clair at umich.edu> >>