ASYMM¶
This is an example on how to use the ASYMM
class. See also the reference [FaGa19b].
import numpy as np
import networkx as nx
import dill as pickle
from mpi4py import MPI
from disropt.agents import Agent
from disropt.algorithms.asymm import ASYMM
from disropt.utils.graph_constructor import binomial_random_graph, metropolis_hastings
from disropt.functions import SquaredNorm, Norm, Variable
from disropt.problems import Problem
# get MPI info
comm = MPI.COMM_WORLD
nproc = comm.Get_size()
local_rank = comm.Get_rank()
# Generate a common graph (everyone use the same seed)
Adj = binomial_random_graph(nproc, p=1, seed=1)
W = metropolis_hastings(Adj)
graph = nx.DiGraph(Adj)
graph_diameter = nx.diameter(graph)
if local_rank == 0:
print(Adj)
# create local agent
agent = Agent(in_neighbors=np.nonzero(Adj[local_rank, :])[0].tolist(),
out_neighbors=np.nonzero(Adj[:, local_rank])[0].tolist(),
in_weights=W[local_rank, :].tolist())
# problem set-up
n = 2
# target point
x_true = np.random.randn(n, 1)
if local_rank == 0:
print(x_true)
# reset local seed
np.random.seed(10 * local_rank)
# local position
c = np.random.randn(n, 1)
# true distance
distance = np.linalg.norm(x_true-c, ord=2)
# declare a variable
x = Variable(n)
# define the local objective function
objective = (x -c) @ (x - c)
# local constraint
upper_bound = (x-c) @ (x-c) <= (distance**2 + 0.00001*np.random.rand())
lower_bound = (x-c) @ (x-c) >= (distance**2 - 0.00001*np.random.rand())
constraints = [upper_bound, lower_bound]
# define local problem
pb = Problem(objective_function=objective, constraints=constraints)
agent.set_problem(pb)
####
x0 = np.random.randn(n, 1)
algorithm = ASYMM(agent=agent,
graph_diameter=graph_diameter,
initial_condition=x0,
enable_log=True)
timestamp_sequence_awake, timestamp_sequence_sleep, sequence = algorithm.run(running_time=30.0)
# print solution
print("Agent {}:\n value: {}\n".format(agent.id, algorithm.get_result()))
# save data
with open('agent_{}_constraints.pkl'.format(agent.id), 'wb') as output:
pickle.dump(agent.problem.constraints, output, pickle.HIGHEST_PROTOCOL)
np.save("agents.npy", nproc)
np.save("agent_{}_sequence.npy".format(agent.id), sequence)
np.save("agent_{}_timestamp_sequence_awake.npy".format(agent.id), timestamp_sequence_awake)
np.save("agent_{}_timestamp_sequence_sleep.npy".format(agent.id), timestamp_sequence_sleep)
import numpy as np
import dill as pickle
import matplotlib.pyplot as plt
# number of agents
N = np.load("agents.npy")
# retrieve local sequences
sequence = {}
constraints = {}
timestamp_sequence_awake = {}
timestamp_sequence_sleep = {}
colors = {}
t_init = None
for i in range(N):
colors[i] = np.random.rand(3, 1).flatten()
filename = "agent_{}_sequence.npy".format(i)
sequence[i] = np.load(filename, allow_pickle=True)
filename = "agent_{}_timestamp_sequence_awake.npy".format(i)
timestamp_sequence_awake[i] = np.load(filename, allow_pickle=True)
filename = "agent_{}_timestamp_sequence_sleep.npy".format(i)
timestamp_sequence_sleep[i] = np.load(filename, allow_pickle=True)
if t_init is not None:
m = min(timestamp_sequence_awake[i])
t_init = min(t_init, m)
else:
t_init = min(timestamp_sequence_awake[i])
with open('agent_{}_constraints.pkl'.format(i), 'rb') as input:
constraints[i] = pickle.load(input)
for i in range(N):
timestamp_sequence_awake[i] = timestamp_sequence_awake[i] - t_init
timestamp_sequence_sleep[i] = timestamp_sequence_sleep[i] - t_init
# plot
plt.figure()
for i in range(N):
dims = sequence[i].shape
for j in range(dims[1]):
for m in range(dims[2]):
plt.plot(timestamp_sequence_sleep[i], sequence[i][:, j, m])
plt.ylim([-5, 5])
# # plt
plt.figure()
for i in range(N):
dims = sequence[i].shape
iterations = dims[0]
print("Agent {}, iterations {}".format(i, iterations))
feasibility = np.zeros([iterations, 2])
for k in range(iterations):
for idx, constr in enumerate(constraints[i]):
flag = constr.eval((sequence[i][k, :, :]).reshape(2,1))
if flag == False:
feasibility[k, idx] += abs(constr.function.eval((sequence[i][k, :, :]).reshape(2,1)).flatten())
plt.semilogy(timestamp_sequence_sleep[i], feasibility)
# plt.lim([-1, 15])
plt.show()
The two files can be executed by issuing the following commands in the example folder:
> mpirun -np 30 --oversubscribe python launcher.py
> python results.py