def get_loss(net, A, X, y, instances):
    net.eval()
    rslt = []
    c_pred = net(torch.from_numpy(X).float()).squeeze().detach().numpy()
    c = y
    for (k, v) in instances.items():
        (source, destination) = v
        b = np.zeros(len(A))
        b[source] = 1
        b[destination] = (- 1)
        model = gp.Model()
        model.setParam('OutputFlag', 0)
        x = model.addMVar(shape=A.shape[1], vtype=gp.GRB.BINARY, name='x')
        model.setObjective((c_pred @ x), gp.GRB.MINIMIZE)
        model.addConstr(((A @ x) == b), name='eq')
        model.optimize()
        if (model.status == 2):
            sol = x.X
            rslt.append(c.dot(sol))
        else:
            print(model.status, k, v)
    net.train()
    return (mse(c_pred, c), sum(rslt))
def get_loss(net, A, X, y, instances):
    net.eval()
    rslt = []
    c_pred = net(torch.from_numpy(X).float()).squeeze().detach().numpy()
    c = y
    for (k, v) in instances.items():
        (source, destination) = v
        b = np.zeros(len(A))
        b[source] = 1
        b[destination] = (- 1)
        model = gp.Model()
        model.setParam('OutputFlag', 0)
        x = model.addMVar(shape=A.shape[1], vtype=gp.GRB.BINARY, name='x')
        model.setObjective((c_pred @ x), gp.GRB.MINIMIZE)
        model.addConstr(((A @ x) == b), name='eq')
        model.optimize()
        if (model.status == 2):
            sol = x.X
            rslt.append(c.dot(sol))
        else:
            print(model.status, k, v)
    net.train()
    return (mse(c_pred, c), sum(rslt))