依赖图的环形检测,非环有向依赖图的子集的依赖检测

 
class Item {
    private String name;
    private int helperInfo;

    public Item() {
        this.helperInfo = 0;
    }

    public Item(String name) {
        this.name = name;
        this.helperInfo = 0;
    }

    public Item(Item item) {
        this.name = item.getName();
        this.helperInfo = item.getHelperInfo();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getHelperInfo() {
        return helperInfo;
    }

    public void setHelperInfo(int helperInfo) {
        this.helperInfo = helperInfo;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Item item = (Item) o;
        return name != null ? name.equals(item.name) : item.name == null;
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }
}

public static ArrayList<Item> vertex = new ArrayList<>();

public void genVertex() {
    Item a = new Item("A");
    Item b = new Item("B");
    Item c = new Item("C");
    Item d = new Item("D");
    Item e = new Item("E");
    Item f = new Item("F");

    vertex.add(a);
    vertex.add(b);
    vertex.add(c);
    vertex.add(d);
    vertex.add(e);
    vertex.add(f);
}

//public ArrayList<ArrayList<Item>> edgeArr = new ArrayList<>();
public static int[][] arr = new int[6][6];

public static int circleCount = 0;

public static Map<Item, Set<Item>> itemMap = new HashMap<>();

public void genCircleEdge() {
    for (int i = 0; i < 6; i++) {
        for (int j = 0; j < 6; j++) {
            arr[i][j] = 0;
        }
    }
    arr[0][1] = 1;
    arr[1][2] = 1;
    arr[2][4] = 1;
    arr[3][4] = 1;
    arr[4][0] = 1;
    arr[4][5] = 1;
    arr[5][1] = 1;
    arr[5][3] = 1;
}

public void genNoCircleGraph() {

    for (int i = 0; i < 6; i++) {
        for (int j = 0; j < 6; j++) {
            arr[i][j] = 0;
        }
    }
    arr[0][1] = 1;
    //arr[1][2] = 1;
    arr[2][4] = 1;
    //arr[3][4] = 1;
    arr[4][0] = 1;
    arr[4][5] = 1;
    arr[5][1] = 1;
    arr[5][3] = 1;

}

public int getVertexIndex(Item item) {
    int ret = -1;
    int size = vertex.size();
    for (int i = 0; i < size; i++) {
        if (vertex.get(i).getName().equals(item.getName())) {
            ret = i;
            break;
        }
    }
    return ret;
}

public void trimStringBuffer(StringBuffer stringBuffer) {
    int lastIndexOfArray = stringBuffer.lastIndexOf("->");
    int maxIndexOfString = stringBuffer.length();
    stringBuffer.delete(lastIndexOfArray, maxIndexOfString);
}



public void depthTraverse(ArrayList<Item> bussinessList, ArrayList<Item> workStack, Item curItem,
                          StringBuffer stringBuffer, Set<Item> dependencySet) {
    if (workStack.size() == 0) {
        return;
    }

    int row = bussinessList.indexOf(curItem);
    System.out.println("row:" + row);


    int childrenCount = 0;
    int businessSize = bussinessList.size();
    for (int i = 0; i < businessSize; i++) {
        if (arr[row][i] == 1) {
            workStack.add(bussinessList.get(i));
            childrenCount++;
        }
    }

    System.out.print("top ");
    for (int i = workStack.size() - 1; i >= 0; i--) {
        System.out.print(workStack.get(i).getName() + ",");
    }
    System.out.println(" bottom");

    if (childrenCount == 0) {
        System.out.println("dependecyChain: " + stringBuffer.toString());
        String dependencyChain = stringBuffer.toString();
        String[] dependecyItems  = dependencyChain.split("->");
        int length = dependecyItems.length;
        for(int i = 0; i < length; i++ ) {
            Item item = new Item(dependecyItems[i]);
            dependencySet.add(item);
        }
    }

    for (int j = 0; j < childrenCount; j++) {
        int lastIndex = workStack.size() - 1;
        Item priorItem = workStack.get(lastIndex);
        workStack.remove(priorItem);
        if (priorItem.helperInfo == 0) {
            priorItem.helperInfo = 1;
            stringBuffer.append("->" + priorItem.getName());
            depthTraverse(bussinessList, workStack, priorItem, stringBuffer, dependencySet);
            trimStringBuffer(stringBuffer);
        } else if (priorItem.helperInfo == 1) {
            stringBuffer.append("->" + priorItem.getName());
            int beginIndex = stringBuffer.indexOf(priorItem.getName());
            int tailIndex = stringBuffer.lastIndexOf(priorItem.getName());
            if (tailIndex > beginIndex) {
                String circleBegin = stringBuffer.substring(beginIndex);
                System.out.println("circle:" + circleBegin);
                circleCount++;
            } else {
                depthTraverse(bussinessList, workStack, priorItem, stringBuffer, dependencySet);
            }
            trimStringBuffer(stringBuffer);
        }
    }

    curItem.helperInfo = 1;
}

public int checkCircle() {

    int size = vertex.size();
    ArrayList<Item> bussinessList = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        Item item = vertex.get(i);
        Item newItem = new Item(item);
        bussinessList.add(newItem);
    }

    ArrayList<Item> workStack = new ArrayList<>();
    StringBuffer stringBuffer = new StringBuffer();

    for (int i = 0; i < size; i++) {
        Item item = bussinessList.get(i);
        workStack.clear();
        stringBuffer.delete(0, stringBuffer.capacity());
        Set<Item> dependencySet = new HashSet<>();
        if (item.helperInfo != 1) {
            workStack.add(item);
            stringBuffer.append(item.getName());
            depthTraverse(bussinessList, workStack, item, stringBuffer, dependencySet);
        }
    }

    System.out.println("all circle:" + circleCount);

    return circleCount;

}

public void genDependencyChain() {

    circleCount = 0;
    checkCircle();
    if(circleCount != 0) {
        return;
    }

    int size = vertex.size();
    ArrayList<Item> bussinessList = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        Item item = vertex.get(i);
        Item newItem = new Item(item);
        bussinessList.add(newItem);
    }

    ArrayList<Item> workStack = new ArrayList<>();
    StringBuffer stringBuffer = new StringBuffer();

    for (int i = 0; i < size; i++) {
        Item item = bussinessList.get(i);
        workStack.clear();
        stringBuffer.delete(0, stringBuffer.capacity());
        Set<Item> dependencySet = new HashSet<>();
        workStack.add(item);
        stringBuffer.append(item.getName());
        depthTraverse(bussinessList, workStack, item, stringBuffer, dependencySet);
        dependencySet.remove(item);
        itemMap.put(item, dependencySet);
    }
}

public void downloadBussiness(Set<Item> itemHashSet) {

    Iterator<Item> iterator = itemHashSet.iterator();

    while (iterator.hasNext()) {
        Item it = iterator.next();
        boolean dependencyOk = true;

        Set<Item> dependencySet  = itemMap.get(it);
        if(dependencySet != null) {
            Iterator<Item> diter = dependencySet.iterator();
            while(diter.hasNext()) {
                Item dependencyItem = diter.next();
                if(!itemHashSet.contains(dependencyItem)) {
                    System.out.println("item:" + it.getName() + " need " + dependencyItem.getName());
                    dependencyOk = false;
                }
            }
        }

        if(dependencyOk) {
            System.out.println("item:" + it.getName() + " can be download");
        }
    }
}

@Test
public void testCircle() {
    genVertex();
    genCircleEdge();
    checkCircle();
}

@Test
public void testDownLoadBusiness() {
    genVertex();
    genNoCircleGraph();
    genDependencyChain();

    Set<Item> itemHashSet = new HashSet<Item>();
    itemHashSet.add(new Item("A"));
    itemHashSet.add(new Item("D"));
    itemHashSet.add(new Item("C"));
    downloadBussiness(itemHashSet);

}

检查环使用的时候每个子孩子的深度遍历,使用模拟的栈
testCircle 结果输出:
row:0
top B,A, bottom
row:1
top C,A, bottom
row:2
top E,A, bottom
row:4
top F,A,A, bottom
row:5
top D,B,A,A, bottom
row:3
top E,B,A,A, bottom
circle:E->F->D->E
circle:B->C->E->F->B
row:0
top B,A, bottom
circle:B->C->E->A->B
all circle:3

Process finished with exit code 0

testDownLoadBusiness 输出结果:

row:0
top B,A, bottom
row:1
top A, bottom
dependecyChain: A->B
row:2
top E,C, bottom
row:4
top F,A,C, bottom
row:5
top D,B,A,C, bottom
row:3
top B,A,C, bottom
dependecyChain: C->E->F->D
row:1
top A,C, bottom
dependecyChain: C->E->F->B
row:0
top B,C, bottom
row:1
top C, bottom
dependecyChain: C->E->A->B
all circle:0
row:0
top B,A, bottom
row:1
top A, bottom
dependecyChain: A->B
row:1
top B, bottom
dependecyChain: B
row:2
top E,C, bottom
row:4
top F,A,C, bottom
row:5
top D,B,A,C, bottom
row:3
top B,A,C, bottom
dependecyChain: C->E->F->D
row:1
top A,C, bottom
dependecyChain: C->E->F->B
row:0
top B,C, bottom
row:1
top C, bottom
dependecyChain: C->E->A->B
row:3
top D, bottom
dependecyChain: D
row:4
top F,A,E, bottom
row:5
top D,B,A,E, bottom
row:3
top B,A,E, bottom
dependecyChain: E->F->D
row:1
top A,E, bottom
dependecyChain: E->F->B
row:0
top B,E, bottom
row:1
top E, bottom
dependecyChain: E->A->B
row:5
top D,B,F, bottom
row:3
top B,F, bottom
dependecyChain: F->D
row:1
top F, bottom
dependecyChain: F->B
item:A need B
item:C need B
item:C need E
item:C need F
item:D can be download

Process finished with exit code 0




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值