Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

Without life, Biology itself would be impossible.


devel / comp.theory / Re: Graph isomorphism code (explanation follows)

SubjectAuthor
* Graph isomorphism code (explanation follows)B.H.
`- Graph isomorphism code (explanation follows)B.H.

1
Graph isomorphism code (explanation follows)

<2d79000d-8511-40fd-8b6b-1bc43e7d89d5n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=36414&group=comp.theory#36414

  copy link   Newsgroups: comp.theory
X-Received: by 2002:a05:620a:d83:b0:6b8:5da4:887a with SMTP id q3-20020a05620a0d8300b006b85da4887amr7446436qkl.415.1659212440127;
Sat, 30 Jul 2022 13:20:40 -0700 (PDT)
X-Received: by 2002:a25:4052:0:b0:676:cd07:ae87 with SMTP id
n79-20020a254052000000b00676cd07ae87mr4444805yba.238.1659212439792; Sat, 30
Jul 2022 13:20:39 -0700 (PDT)
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!feed1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.theory
Date: Sat, 30 Jul 2022 13:20:39 -0700 (PDT)
Injection-Info: google-groups.googlegroups.com; posting-host=173.53.104.152; posting-account=X_pe-goAAACrVTtZeoCLt7hslVPY2-Uo
NNTP-Posting-Host: 173.53.104.152
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <2d79000d-8511-40fd-8b6b-1bc43e7d89d5n@googlegroups.com>
Subject: Graph isomorphism code (explanation follows)
From: xlt....@gmail.com (B.H.)
Injection-Date: Sat, 30 Jul 2022 20:20:40 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 6676
 by: B.H. - Sat, 30 Jul 2022 20:20 UTC

This code is very drafty; it took longer than I thought and I wanted to go for speed. It took a total of 63 minutes; there might be mistakes, I didn't get a chance to check it and/or fix it. It represents what I can get done in 63 minutes. I'll explain the algorithm in a subsequent post. On the job, I might start by coding something like this and then fix the code...or, I might plan more carefully. Here is the code:

------------

#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

struct graph;
struct node;
struct tree;
struct edge;

void readTwoGraphsFromFile(graph & a, graph & b, string filename);

bool graphsAreIsomorphic(graph a, graph b);

void attachAllNodes(graph a, tree & helper, int index, int counter);

void attachChild(graph a, int label, tree & helper);

bool operator == (tree a, tree b);

int strToInt(string str);

struct node
{ int ID;
};

struct edge
{ node from;
node to;
};

struct graph
{ vector <edge> allEdges;
vector <node> allNodes;
};

struct tree
{ vector <tree> children;
node thisNode;
};

int main()
{ int c;
graph a, b;
readTwoGraphsFromFile(a,b,"input.txt");
cout << graphsAreIsomorphic(a,b);
cin >> c;

return 0;
}

bool graphsAreIsomorphic(graph a, graph b)
{ tree helper;
vector <tree> allAtrees;
vector <tree> allBtrees;
for (int i = 0; i < a.allNodes.size(); i++)
{
// Construct a tree from each node.
helper.thisNode.ID = a.allNodes[i].ID;

// Attach each node as a child to the appropriate parent nodes in the graph/tree.

// Find all the children of the initial node; use a recursive process to connect them all.

attachAllNodes(a,helper,i,a.allNodes.size());

allAtrees.push_back(helper);
}

for (int i = 0; i < b.allNodes.size(); i++)
{
helper.thisNode.ID = b.allNodes[i].ID;

attachAllNodes(b,helper,i,b.allNodes.size());

allAtrees.push_back(helper);
}

bool flag = false;
bool changeFlag = true;
do
{
for (int i = 0; i < allAtrees.size() && !flag; i++)
{
for (int j = 0; j < allBtrees.size() && !flag; j++)
{
if (allAtrees[i] == allBtrees[j])
{
for (int k = i; k < allAtrees.size()-1; k++)
{
allAtrees[k] = allAtrees[k+1];
}
for (int k = j; k < allBtrees.size()-1; k++)
{
allBtrees[k] = allBtrees[k+1];
}
}
}
}
if (flag != true)
{
changeFlag = false;
}
} while (changeFlag == true);

if (allAtrees.size() == 0 && allBtrees.size() == 0) // the trees matched
{
return true;
}
return false;
}

void attachChild(graph a, int label, tree & helper)
{ helper.children.resize(helper.children.size()+1);
helper.children[helper.children.size()-1].thisNode.ID = label;
}

void attachAllNodes(graph a, tree & helper, int index, int counter)
{ if (counter < 0)
{
return; // The recursion is done.
}
int k, val;
for (int j = 0; j < a.allEdges.size(); j++)
{
if (helper.thisNode.ID == a.allEdges[j].from.ID)
{
attachChild(a,a.allEdges[j].to.ID,helper);
}
for (k = 0; k < a.allNodes.size(); k++)
{
if (a.allNodes[k].ID == a.allEdges[k].to.ID)
{
val = k;
}
}
attachAllNodes(a,helper.children[helper.children.size()-1],val, counter-1);
}
}

void readTwoGraphsFromFile(graph & a, graph & b, string filename)
{ ifstream inFile(filename);
if (!inFile.is_open())
{
cout << "ERROR, file not found.";
exit(0);
}
else
{
string str;
int i;
do
{
i = 0;
inFile >> str;
if (str != "#")
{
a.allNodes[i++].ID = strToInt(str);
}
} while (str != "#");
do
{
i = 0;
inFile >> str;
if (str != "#")
{
a.allEdges[i++].from.ID = strToInt(str);
a.allEdges[i++].to.ID = strToInt(str);
}
} while (str != "#");
do
{
i = 0;
inFile >> str;
if (str != "#")
{
b.allNodes[i++].ID = strToInt(str);
}
} while (str != "#");
do
{
i = 0;
inFile >> str;
if (str != "#")
{
b.allEdges[i++].from.ID = strToInt(str);
b.allEdges[i++].to.ID = strToInt(str);
}
} while (str != "#");
}
}

bool operator == (tree a, tree b)
{ return (a.thisNode.ID == b.thisNode.ID && a.children == b.children);
}

int strToInt(string str)
{ int num = 0;
for (int i = 0; i < str.size(); i++)
{
num += str[i] - '0';
num *= 10;
}
return num / 10;
}

Re: Graph isomorphism code (explanation follows)

<8f6112e5-00b0-4cac-8eef-7d4f176114ddn@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=36415&group=comp.theory#36415

  copy link   Newsgroups: comp.theory
X-Received: by 2002:a05:620a:12cd:b0:6b5:d8da:7ce7 with SMTP id e13-20020a05620a12cd00b006b5d8da7ce7mr6981961qkl.579.1659212618326;
Sat, 30 Jul 2022 13:23:38 -0700 (PDT)
X-Received: by 2002:a5b:603:0:b0:673:e5d7:e9e8 with SMTP id
d3-20020a5b0603000000b00673e5d7e9e8mr6454139ybq.632.1659212618043; Sat, 30
Jul 2022 13:23:38 -0700 (PDT)
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!feed1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.theory
Date: Sat, 30 Jul 2022 13:23:37 -0700 (PDT)
In-Reply-To: <2d79000d-8511-40fd-8b6b-1bc43e7d89d5n@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=173.53.104.152; posting-account=X_pe-goAAACrVTtZeoCLt7hslVPY2-Uo
NNTP-Posting-Host: 173.53.104.152
References: <2d79000d-8511-40fd-8b6b-1bc43e7d89d5n@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <8f6112e5-00b0-4cac-8eef-7d4f176114ddn@googlegroups.com>
Subject: Re: Graph isomorphism code (explanation follows)
From: xlt....@gmail.com (B.H.)
Injection-Date: Sat, 30 Jul 2022 20:23:38 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 7504
 by: B.H. - Sat, 30 Jul 2022 20:23 UTC

On Saturday, July 30, 2022 at 4:20:41 PM UTC-4, B.H. wrote:
> This code is very drafty; it took longer than I thought and I wanted to go for speed. It took a total of 63 minutes; there might be mistakes, I didn't get a chance to check it and/or fix it. It represents what I can get done in 63 minutes. I'll explain the algorithm in a subsequent post. On the job, I might start by coding something like this and then fix the code...or, I might plan more carefully. Here is the code:
>
> ------------
>
>
> #include <iostream>
> #include <vector>
> #include <fstream>
>
> using namespace std;
>
> struct graph;
> struct node;
> struct tree;
> struct edge;
>
> void readTwoGraphsFromFile(graph & a, graph & b, string filename);
>
> bool graphsAreIsomorphic(graph a, graph b);
>
> void attachAllNodes(graph a, tree & helper, int index, int counter);
>
> void attachChild(graph a, int label, tree & helper);
>
> bool operator == (tree a, tree b);
>
> int strToInt(string str);
>
>
>
> struct node
> {
> int ID;
> };
>
> struct edge
> {
> node from;
> node to;
> };
>
> struct graph
> {
> vector <edge> allEdges;
> vector <node> allNodes;
> };
>
>
> struct tree
> {
> vector <tree> children;
> node thisNode;
> };
>
>
>
>
> int main()
> {
> int c;
> graph a, b;
> readTwoGraphsFromFile(a,b,"input.txt");
> cout << graphsAreIsomorphic(a,b);
> cin >> c;
>
> return 0;
> }
>
>
> bool graphsAreIsomorphic(graph a, graph b)
> {
> tree helper;
> vector <tree> allAtrees;
> vector <tree> allBtrees;
> for (int i = 0; i < a.allNodes.size(); i++)
> {
> // Construct a tree from each node.
> helper.thisNode.ID = a.allNodes[i].ID;
>
> // Attach each node as a child to the appropriate parent nodes in the graph/tree.
>
> // Find all the children of the initial node; use a recursive process to connect them all.
>
> attachAllNodes(a,helper,i,a.allNodes.size());
>
> allAtrees.push_back(helper);
> }
>
> for (int i = 0; i < b.allNodes.size(); i++)
> {
> helper.thisNode.ID = b.allNodes[i].ID;
>
> attachAllNodes(b,helper,i,b.allNodes.size());
>
> allAtrees.push_back(helper);
> }
>
> bool flag = false;
> bool changeFlag = true;
> do
> {
> for (int i = 0; i < allAtrees.size() && !flag; i++)
> {
> for (int j = 0; j < allBtrees.size() && !flag; j++)
> {
> if (allAtrees[i] == allBtrees[j])
> {
> for (int k = i; k < allAtrees.size()-1; k++)
> {
> allAtrees[k] = allAtrees[k+1];
> }
> for (int k = j; k < allBtrees.size()-1; k++)
> {
> allBtrees[k] = allBtrees[k+1];
> }
> }
> }
> }
> if (flag != true)
> {
> changeFlag = false;
> }
> } while (changeFlag == true);
>
> if (allAtrees.size() == 0 && allBtrees.size() == 0) // the trees matched
> {
> return true;
> }
> return false;
> }
>
>
>
> void attachChild(graph a, int label, tree & helper)
> {
> helper.children.resize(helper.children.size()+1);
> helper.children[helper.children.size()-1].thisNode.ID = label;
> }
>
>
> void attachAllNodes(graph a, tree & helper, int index, int counter)
> {
> if (counter < 0)
> {
> return; // The recursion is done.
> }
> int k, val;
> for (int j = 0; j < a.allEdges.size(); j++)
> {
> if (helper.thisNode.ID == a.allEdges[j].from.ID)
> {
> attachChild(a,a.allEdges[j].to.ID,helper);
> }
> for (k = 0; k < a.allNodes.size(); k++)
> {
> if (a.allNodes[k].ID == a.allEdges[k].to.ID)
> {
> val = k;
> }
> }
> attachAllNodes(a,helper.children[helper.children.size()-1],val, counter-1);
> }
> }
>
> void readTwoGraphsFromFile(graph & a, graph & b, string filename)
> {
> ifstream inFile(filename);
> if (!inFile.is_open())
> {
> cout << "ERROR, file not found.";
> exit(0);
> }
> else
> {
> string str;
> int i;
> do
> {
> i = 0;
> inFile >> str;
> if (str != "#")
> {
> a.allNodes[i++].ID = strToInt(str);
> }
> } while (str != "#");
> do
> {
> i = 0;
> inFile >> str;
> if (str != "#")
> {
> a.allEdges[i++].from.ID = strToInt(str);
> a.allEdges[i++].to.ID = strToInt(str);
> }
> } while (str != "#");
> do
> {
> i = 0;
> inFile >> str;
> if (str != "#")
> {
> b.allNodes[i++].ID = strToInt(str);
> }
> } while (str != "#");
> do
> {
> i = 0;
> inFile >> str;
> if (str != "#")
> {
> b.allEdges[i++].from.ID = strToInt(str);
> b.allEdges[i++].to.ID = strToInt(str);
> }
> } while (str != "#");
> }
> }
>
> bool operator == (tree a, tree b)
> {
> return (a.thisNode.ID == b.thisNode.ID && a.children == b.children);
> }
>
>
> int strToInt(string str)
> {
> int num = 0;
> for (int i = 0; i < str.size(); i++)
> {
> num += str[i] - '0';
> num *= 10;
> }
> return num / 10;
> }

So as I think I said, I barely checked the code. Again, it's to represent what I can currently do with a challenging task in 63 minutes, working as fast as I can.

The idea for the graph isomorphism algorithm was: Turn each node in each graph into the root node of a tree, and try to track/include cycles. Each tree should in the first graph should be identical to one tree in the second graph if and only if the graphs are isomorphic. I just noticed that in this code, I forgot to sort the nodes by label, for one thing. So the code isn't perfect for sure. The idea appears to be good, although I didn't write out a journal-ready proof. There's a second "confirmation step" that can be omitted because it's trivial, too.

-Philip White (philipjwhite@yahoo.com)

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor